1 package keystore
2 3 import (
4 "bytes"
5 "crypto/aes"
6 "crypto/cipher"
7 "crypto/rand"
8 "crypto/sha512"
9 "encoding/binary"
10 "encoding/hex"
11 "errors"
12 "fmt"
13 "github.com/p9c/p9/pkg/btcaddr"
14 "github.com/p9c/p9/pkg/chaincfg"
15 "io"
16 "io/ioutil"
17 "math/big"
18 "os"
19 "path/filepath"
20 "sync"
21 "time"
22 23 "golang.org/x/crypto/ripemd160"
24 25 "github.com/p9c/p9/pkg/chainhash"
26 ec "github.com/p9c/p9/pkg/ecc"
27 "github.com/p9c/p9/pkg/txscript"
28 "github.com/p9c/p9/pkg/util"
29 "github.com/p9c/p9/pkg/util/legacy/rename"
30 "github.com/p9c/p9/pkg/wire"
31 )
32 33 // A bunch of constants
34 const (
35 Filename = "wallet.bin"
36 // Length in bytes of KDF output.
37 kdfOutputBytes = 32
38 // Maximum length in bytes of a comment that can have a size represented as a uint16.
39 maxCommentLen = (1 << 16) - 1
40 defaultKdfComputeTime = 0.25
41 defaultKdfMaxMem = 32 * 1024 * 1024
42 )
43 44 // Possible errors when dealing with key stores.
45 var (
46 ErrAddressNotFound = errors.New("address not found")
47 ErrAlreadyEncrypted = errors.New("private key is already encrypted")
48 ErrChecksumMismatch = errors.New("checksum mismatch")
49 ErrDuplicate = errors.New("duplicate key or address")
50 ErrMalformedEntry = errors.New("malformed entry")
51 ErrWatchingOnly = errors.New("keystore is watching-only")
52 ErrLocked = errors.New("keystore is locked")
53 ErrWrongPassphrase = errors.New("wrong passphrase")
54 )
55 var fileID = [8]byte{0xba, 'W', 'A', 'L', 'L', 'E', 'T', 0x00}
56 57 type entryHeader byte
58 59 const (
60 addrCommentHeader entryHeader = 1 << iota
61 txCommentHeader
62 deletedHeader
63 scriptHeader
64 addrHeader entryHeader = 0
65 )
66 67 // We want to use binaryRead and binaryWrite instead of binary.Read and binary.Write because those from the binary
68 // package do not return the number of bytes actually written or read. We need to return this value to correctly support
69 // the io.ReaderFrom and io.WriterTo interfaces.
70 func binaryRead(r io.Reader, order binary.ByteOrder, data interface{}) (n int64, e error) {
71 var read int
72 buf := make([]byte, binary.Size(data))
73 if read, e = io.ReadFull(r, buf); E.Chk(e) {
74 return int64(read), e
75 }
76 return int64(read), binary.Read(bytes.NewBuffer(buf), order, data)
77 }
78 79 // See comment for binaryRead().
80 func binaryWrite(w io.Writer, order binary.ByteOrder, data interface{}) (n int64, e error) {
81 buf := bytes.Buffer{}
82 if e = binary.Write(&buf, order, data); E.Chk(e) {
83 return 0, e
84 }
85 written, e := w.Write(buf.Bytes())
86 return int64(written), e
87 }
88 89 // pubkeyFromPrivkey creates an encoded pubkey based on a 32-byte privkey. The returned pubkey is 33 bytes if
90 // compressed, or 65 bytes if uncompressed.
91 func pubkeyFromPrivkey(privkey []byte, compress bool) (pubkey []byte) {
92 _, pk := ec.PrivKeyFromBytes(ec.S256(), privkey)
93 if compress {
94 return pk.SerializeCompressed()
95 }
96 return pk.SerializeUncompressed()
97 }
98 func keyOneIter(passphrase, salt []byte, memReqts uint64) []byte {
99 saltedpass := append(passphrase, salt...)
100 lutbl := make([]byte, memReqts)
101 // Seed for lookup table
102 seed := sha512.Sum512(saltedpass)
103 copy(lutbl[:sha512.Size], seed[:])
104 for nByte := 0; nByte < (int(memReqts) - sha512.Size); nByte += sha512.Size {
105 hash := sha512.Sum512(lutbl[nByte : nByte+sha512.Size])
106 copy(lutbl[nByte+sha512.Size:nByte+2*sha512.Size], hash[:])
107 }
108 x := lutbl[cap(lutbl)-sha512.Size:]
109 seqCt := uint32(memReqts / sha512.Size)
110 nLookups := seqCt / 2
111 for i := uint32(0); i < nLookups; i++ {
112 // Armory ignores endianness here. We assume LE.
113 newIdx := binary.LittleEndian.Uint32(x[cap(x)-4:]) % seqCt
114 // Index of hash result at newIdx
115 vIdx := newIdx * sha512.Size
116 v := lutbl[vIdx : vIdx+sha512.Size]
117 // XOR hash x with hash v
118 for j := 0; j < sha512.Size; j++ {
119 x[j] ^= v[j]
120 }
121 // Save new hash to x
122 hash := sha512.Sum512(x)
123 copy(x, hash[:])
124 }
125 return x[:kdfOutputBytes]
126 }
127 128 // kdf implements the key derivation function used by Armory based on the ROMix algorithm described in Colin Percival's
129 // paper "Stronger Key Derivation via Sequential Memory-Hard Functions" (http://www.tarsnap.com/scrypt/scrypt.pdf).
130 func kdf(passphrase []byte, params *kdfParameters) []byte {
131 masterKey := passphrase
132 for i := uint32(0); i < params.nIter; i++ {
133 masterKey = keyOneIter(masterKey, params.salt[:], params.mem)
134 }
135 return masterKey
136 }
137 func pad(size int, b []byte) []byte {
138 // Prevent a possible panic if the input exceeds the expected size.
139 if len(b) > size {
140 size = len(b)
141 }
142 p := make([]byte, size)
143 copy(p[size-len(b):], b)
144 return p
145 }
146 147 // chainedPrivKey deterministically generates a new private key using a previous address and chaincode. privkey and
148 // chaincode must be 32 bytes long, and pubkey may either be 33 or 65 bytes.
149 func chainedPrivKey(privkey, pubkey, chaincode []byte) ([]byte, error) {
150 if len(privkey) != 32 {
151 return nil, fmt.Errorf(
152 "invalid privkey length %d (must be 32)",
153 len(privkey),
154 )
155 }
156 if len(chaincode) != 32 {
157 return nil, fmt.Errorf(
158 "invalid chaincode length %d (must be 32)",
159 len(chaincode),
160 )
161 }
162 switch n := len(pubkey); n {
163 case ec.PubKeyBytesLenUncompressed, ec.PubKeyBytesLenCompressed:
164 // Correct length
165 default:
166 return nil, fmt.Errorf("invalid pubkey length %d", n)
167 }
168 xorbytes := make([]byte, 32)
169 chainMod := chainhash.DoubleHashB(pubkey)
170 for i := range xorbytes {
171 xorbytes[i] = chainMod[i] ^ chaincode[i]
172 }
173 chainXor := new(big.Int).SetBytes(xorbytes)
174 privint := new(big.Int).SetBytes(privkey)
175 t := new(big.Int).Mul(chainXor, privint)
176 b := t.Mod(t, ec.S256().N).Bytes()
177 return pad(32, b), nil
178 }
179 180 // chainedPubKey deterministically generates a new public key using a previous public key and chaincode. pubkey must be
181 // 33 or 65 bytes, and chaincode must be 32 bytes long.
182 func chainedPubKey(pubkey, chaincode []byte) ([]byte, error) {
183 var compressed bool
184 switch n := len(pubkey); n {
185 case ec.PubKeyBytesLenUncompressed:
186 compressed = false
187 case ec.PubKeyBytesLenCompressed:
188 compressed = true
189 default:
190 // Incorrect serialized pubkey length
191 return nil, fmt.Errorf("invalid pubkey length %d", n)
192 }
193 if len(chaincode) != 32 {
194 return nil, fmt.Errorf(
195 "invalid chaincode length %d (must be 32)",
196 len(chaincode),
197 )
198 }
199 xorbytes := make([]byte, 32)
200 chainMod := chainhash.DoubleHashB(pubkey)
201 for i := range xorbytes {
202 xorbytes[i] = chainMod[i] ^ chaincode[i]
203 }
204 oldPk, e := ec.ParsePubKey(pubkey, ec.S256())
205 if e != nil {
206 E.Ln(e)
207 return nil, e
208 }
209 newX, newY := ec.S256().ScalarMult(oldPk.X, oldPk.Y, xorbytes)
210 // if e != nil {
211 // return nil, e
212 // }
213 newPk := &ec.PublicKey{
214 Curve: ec.S256(),
215 X: newX,
216 Y: newY,
217 }
218 if compressed {
219 return newPk.SerializeCompressed(), nil
220 }
221 return newPk.SerializeUncompressed(), nil
222 }
223 224 type ksVersion struct {
225 major byte
226 minor byte
227 bugfix byte
228 autoincrement byte
229 }
230 231 // Enforce that ksVersion satisfies the io.ReaderFrom and io.WriterTo interfaces.
232 var _ io.ReaderFrom = &ksVersion{}
233 var _ io.WriterTo = &ksVersion{}
234 235 // readerFromVersion is an io.ReaderFrom and io.WriterTo that can specify any particular key store file format for
236 // reading depending on the key store file ksVersion.
237 type readerFromVersion interface {
238 readFromVersion(ksVersion, io.Reader) (int64, error)
239 io.WriterTo
240 }
241 242 func (v ksVersion) String() string {
243 str := fmt.Sprintf("%d.%d", v.major, v.minor)
244 if v.bugfix != 0x00 || v.autoincrement != 0x00 {
245 str += fmt.Sprintf(".%d", v.bugfix)
246 }
247 if v.autoincrement != 0x00 {
248 str += fmt.Sprintf(".%d", v.autoincrement)
249 }
250 return str
251 }
252 func (v ksVersion) Uint32() uint32 {
253 return uint32(v.major)<<6 | uint32(v.minor)<<4 | uint32(v.bugfix)<<2 | uint32(v.autoincrement)
254 }
255 func (v *ksVersion) ReadFrom(r io.Reader) (int64, error) {
256 // Read 4 bytes for the ksVersion.
257 var versBytes [4]byte
258 n, e := io.ReadFull(r, versBytes[:])
259 if e != nil {
260 E.Ln(e)
261 return int64(n), e
262 }
263 v.major = versBytes[0]
264 v.minor = versBytes[1]
265 v.bugfix = versBytes[2]
266 v.autoincrement = versBytes[3]
267 return int64(n), nil
268 }
269 func (v *ksVersion) WriteTo(w io.Writer) (int64, error) {
270 // Write 4 bytes for the ksVersion.
271 versBytes := []byte{
272 v.major,
273 v.minor,
274 v.bugfix,
275 v.autoincrement,
276 }
277 n, e := w.Write(versBytes)
278 return int64(n), e
279 }
280 281 // LT returns whether v is an earlier ksVersion than v2.
282 func (v ksVersion) LT(v2 ksVersion) bool {
283 switch {
284 case v.major < v2.major:
285 return true
286 case v.minor < v2.minor:
287 return true
288 case v.bugfix < v2.bugfix:
289 return true
290 case v.autoincrement < v2.autoincrement:
291 return true
292 default:
293 return false
294 }
295 }
296 297 // EQ returns whether v2 is an equal ksVersion to v.
298 func (v ksVersion) EQ(v2 ksVersion) bool {
299 switch {
300 case v.major != v2.major:
301 return false
302 case v.minor != v2.minor:
303 return false
304 case v.bugfix != v2.bugfix:
305 return false
306 case v.autoincrement != v2.autoincrement:
307 return false
308 default:
309 return true
310 }
311 }
312 313 // GT returns whether v is a later ksVersion than v2.
314 func (v ksVersion) GT(v2 ksVersion) bool {
315 switch {
316 case v.major > v2.major:
317 return true
318 case v.minor > v2.minor:
319 return true
320 case v.bugfix > v2.bugfix:
321 return true
322 case v.autoincrement > v2.autoincrement:
323 return true
324 default:
325 return false
326 }
327 }
328 329 // Various versions.
330 var (
331 // VersArmory is the latest ksVersion used by Armory.
332 VersArmory = ksVersion{1, 35, 0, 0}
333 // Vers20LastBlocks is the ksVersion where key store files now hold the 20 most recently seen block hashes.
334 Vers20LastBlocks = ksVersion{1, 36, 0, 0}
335 // VersUnsetNeedsPrivkeyFlag is the bugfix ksVersion where the createPrivKeyNextUnlock address flag is correctly unset
336 // after creating and encrypting its private key after unlock.
337 //
338 // Otherwise, re-creating private keys will occur too early in the address chain and fail due to encrypting an
339 // already encrypted address.
340 //
341 // Key store versions at or before this ksVersion include a special case to allow the duplicate encrypt.
342 VersUnsetNeedsPrivkeyFlag = ksVersion{1, 36, 1, 0}
343 // VersCurrent is the current key store file ksVersion.
344 VersCurrent = VersUnsetNeedsPrivkeyFlag
345 )
346 347 type varEntries struct {
348 store *Store
349 entries []io.WriterTo
350 }
351 352 func (v *varEntries) WriteTo(w io.Writer) (n int64, e error) {
353 ss := v.entries
354 var written int64
355 for _, s := range ss {
356 var e error
357 if written, e = s.WriteTo(w); E.Chk(e) {
358 return n + written, e
359 }
360 n += written
361 }
362 return n, nil
363 }
364 func (v *varEntries) ReadFrom(r io.Reader) (n int64, e error) {
365 var read int64
366 // Remove any previous entries.
367 v.entries = nil
368 wts := v.entries
369 // Keep reading entries until an EOF is reached.
370 for {
371 var header entryHeader
372 if read, e = binaryRead(r, binary.LittleEndian, &header); E.Chk(e) {
373 // EOF here is not an error.
374 if e == io.EOF {
375 return n + read, nil
376 }
377 return n + read, e
378 }
379 n += read
380 var wt io.WriterTo
381 switch header {
382 case addrHeader:
383 var entry addrEntry
384 entry.addr.store = v.store
385 if read, e = entry.ReadFrom(r); E.Chk(e) {
386 return n + read, e
387 }
388 n += read
389 wt = &entry
390 case scriptHeader:
391 var entry scriptEntry
392 entry.script.store = v.store
393 if read, e = entry.ReadFrom(r); E.Chk(e) {
394 return n + read, e
395 }
396 n += read
397 wt = &entry
398 default:
399 return n, fmt.Errorf("unknown entry header: %d", uint8(header))
400 }
401 if wt != nil {
402 wts = append(wts, wt)
403 v.entries = wts
404 }
405 }
406 }
407 408 // Key stores use a custom network parameters type so it can be an io.ReaderFrom.
409 //
410 // Due to the way and order that key stores are currently serialized and how address reading requires the key store's
411 // network parameters, setting and failing on unknown key store networks must happen on the read itself and not after
412 // the fact.
413 //
414 // This is admittedly a hack, but with a bip32 keystore on the horizon I'm not too motivated to clean this up.
415 type netParams chaincfg.Params
416 417 func (net *netParams) ReadFrom(r io.Reader) (int64, error) {
418 var buf [4]byte
419 uint32Bytes := buf[:4]
420 n, e := io.ReadFull(r, uint32Bytes)
421 n64 := int64(n)
422 if e != nil {
423 E.Ln(e)
424 return n64, e
425 }
426 switch wire.BitcoinNet(binary.LittleEndian.Uint32(uint32Bytes)) {
427 case wire.MainNet:
428 *net = netParams(chaincfg.MainNetParams)
429 case wire.TestNet3:
430 *net = netParams(chaincfg.TestNet3Params)
431 case wire.SimNet:
432 *net = netParams(chaincfg.SimNetParams)
433 default:
434 return n64, errors.New("unknown network")
435 }
436 return n64, nil
437 }
438 func (net *netParams) WriteTo(w io.Writer) (int64, error) {
439 var buf [4]byte
440 uint32Bytes := buf[:4]
441 binary.LittleEndian.PutUint32(uint32Bytes, uint32(net.Net))
442 n, e := w.Write(uint32Bytes)
443 n64 := int64(n)
444 return n64, e
445 }
446 447 // Stringified byte slices for use as map lookup keys.
448 type addressKey string
449 450 // type transactionHashKey string
451 // type comment []byte
452 453 func getAddressKey(addr btcaddr.Address) addressKey {
454 return addressKey(addr.ScriptAddress())
455 }
456 457 // Store represents an key store in memory. It implements the io.ReaderFrom and io.WriterTo interfaces to read from and
458 // write to any type of byte streams, including files.
459 type Store struct {
460 // TODO: Use atomic operations for dirty so the reader lock doesn't need to be grabbed.
461 dirty bool
462 path string
463 dir string
464 file string
465 mtx sync.RWMutex
466 vers ksVersion
467 net *netParams
468 flags walletFlags
469 createDate int64
470 name [32]byte
471 desc [256]byte
472 highestUsed int64
473 kdfParams kdfParameters
474 keyGenerator btcAddress
475 // These are non-standard and fit in the extra 1024 bytes between the root address and the appended entries.
476 recent recentBlocks
477 addrMap map[addressKey]walletAddress
478 // The rest of the fields in this struct are not serialized.
479 passphrase []byte
480 secret []byte
481 chainIdxMap map[int64]btcaddr.Address
482 importedAddrs []walletAddress
483 lastChainIdx int64
484 missingKeysStart int64
485 }
486 487 // New creates and initializes a new Store. name's and desc's byte length must not exceed 32 and 256 bytes,
488 // respectively. All address private keys are encrypted with passphrase. The key store is returned locked.
489 func New(
490 dir string, desc string, passphrase []byte, net *chaincfg.Params,
491 createdAt *BlockStamp,
492 ) (s *Store, e error) {
493 // Chk txsizes of inputs.
494 if len(desc) > 256 {
495 return nil, errors.New("desc exceeds 256 byte maximum size")
496 }
497 // Randomly-generate rootkey and chaincode.
498 rootkey := make([]byte, 32)
499 if _, e = rand.Read(rootkey); E.Chk(e) {
500 return nil, e
501 }
502 chaincode := make([]byte, 32)
503 if _, e = rand.Read(chaincode); E.Chk(e) {
504 return nil, e
505 }
506 // Compute AES key and encrypt root address.
507 kdfp, e := computeKdfParameters(defaultKdfComputeTime, defaultKdfMaxMem)
508 if e != nil {
509 E.Ln(e)
510 return nil, e
511 }
512 aeskey := kdf(passphrase, kdfp)
513 // Create and fill key store.
514 s = &Store{
515 path: filepath.Join(dir, Filename),
516 dir: dir,
517 file: Filename,
518 vers: VersCurrent,
519 net: (*netParams)(net),
520 flags: walletFlags{
521 useEncryption: true,
522 watchingOnly: false,
523 },
524 createDate: time.Now().Unix(),
525 highestUsed: rootKeyChainIdx,
526 kdfParams: *kdfp,
527 recent: recentBlocks{
528 lastHeight: createdAt.Height,
529 hashes: []*chainhash.Hash{
530 createdAt.Hash,
531 },
532 },
533 addrMap: make(map[addressKey]walletAddress),
534 chainIdxMap: make(map[int64]btcaddr.Address),
535 lastChainIdx: rootKeyChainIdx,
536 missingKeysStart: rootKeyChainIdx,
537 secret: aeskey,
538 }
539 copy(s.desc[:], desc)
540 // Create new root address from key and chaincode.
541 root, e := newRootBtcAddress(
542 s, rootkey, nil, chaincode,
543 createdAt,
544 )
545 if e != nil {
546 return nil, e
547 }
548 // Verify root address keypairs.
549 if e := root.verifyKeypairs(); E.Chk(e) {
550 return nil, e
551 }
552 if e := root.encrypt(aeskey); E.Chk(e) {
553 return nil, e
554 }
555 s.keyGenerator = *root
556 // Add root address to maps.
557 rootAddr := s.keyGenerator.Address()
558 s.addrMap[getAddressKey(rootAddr)] = &s.keyGenerator
559 s.chainIdxMap[rootKeyChainIdx] = rootAddr
560 // key store must be returned locked.
561 if e := s.Lock(); E.Chk(e) {
562 return nil, e
563 }
564 return s, nil
565 }
566 567 // ReadFrom reads data from a io.Reader and saves it to a key store, returning the number of bytes read and any errors
568 // encountered.
569 func (s *Store) ReadFrom(r io.Reader) (n int64, e error) {
570 s.mtx.Lock()
571 defer s.mtx.Unlock()
572 var read int64
573 s.net = &netParams{}
574 s.addrMap = make(map[addressKey]walletAddress)
575 s.chainIdxMap = make(map[int64]btcaddr.Address)
576 var id [8]byte
577 appendedEntries := varEntries{store: s}
578 s.keyGenerator.store = s
579 // Iterate through each entry needing to be read. If data implements io.ReaderFrom, use its ReadFrom func.
580 // Otherwise, data is a pointer to a fixed sized value.
581 datas := []interface{}{
582 &id,
583 &s.vers,
584 s.net,
585 &s.flags,
586 make([]byte, 6), // Hash for Armory unique ID
587 &s.createDate,
588 &s.name,
589 &s.desc,
590 &s.highestUsed,
591 &s.kdfParams,
592 make([]byte, 256),
593 &s.keyGenerator,
594 newUnusedSpace(1024, &s.recent),
595 &appendedEntries,
596 }
597 for _, data := range datas {
598 var e error
599 switch d := data.(type) {
600 case readerFromVersion:
601 read, e = d.readFromVersion(s.vers, r)
602 case io.ReaderFrom:
603 read, e = d.ReadFrom(r)
604 default:
605 read, e = binaryRead(r, binary.LittleEndian, d)
606 }
607 n += read
608 if e != nil {
609 return n, e
610 }
611 }
612 if id != fileID {
613 return n, errors.New("unknown file ID")
614 }
615 // Add root address to address map.
616 rootAddr := s.keyGenerator.Address()
617 s.addrMap[getAddressKey(rootAddr)] = &s.keyGenerator
618 s.chainIdxMap[rootKeyChainIdx] = rootAddr
619 s.lastChainIdx = rootKeyChainIdx
620 // Fill unserializied fields.
621 wts := appendedEntries.entries
622 for _, wt := range wts {
623 switch e := wt.(type) {
624 case *addrEntry:
625 addr := e.addr.Address()
626 s.addrMap[getAddressKey(addr)] = &e.addr
627 if e.addr.Imported() {
628 s.importedAddrs = append(s.importedAddrs, &e.addr)
629 } else {
630 s.chainIdxMap[e.addr.chainIndex] = addr
631 if s.lastChainIdx < e.addr.chainIndex {
632 s.lastChainIdx = e.addr.chainIndex
633 }
634 }
635 // If the private keys have not been created yet, mark the
636 // earliest so all can be created on next key store unlock.
637 if e.addr.flags.createPrivKeyNextUnlock {
638 switch {
639 case s.missingKeysStart == rootKeyChainIdx:
640 fallthrough
641 case e.addr.chainIndex < s.missingKeysStart:
642 s.missingKeysStart = e.addr.chainIndex
643 }
644 }
645 case *scriptEntry:
646 addr := e.script.Address()
647 s.addrMap[getAddressKey(addr)] = &e.script
648 // script are always imported.
649 s.importedAddrs = append(s.importedAddrs, &e.script)
650 default:
651 return n, errors.New("unknown appended entry")
652 }
653 }
654 return n, nil
655 }
656 657 // WriteTo serializes a key store and writes it to a io.Writer, returning the number of bytes written and any errors
658 // encountered.
659 func (s *Store) WriteTo(w io.Writer) (n int64, e error) {
660 s.mtx.RLock()
661 defer s.mtx.RUnlock()
662 return s.writeTo(w)
663 }
664 func (s *Store) writeTo(w io.Writer) (n int64, e error) {
665 var wts []io.WriterTo
666 var chainedAddrs = make([]io.WriterTo, len(s.chainIdxMap)-1)
667 var importedAddrs []io.WriterTo
668 for _, wAddr := range s.addrMap {
669 switch btcAddr := wAddr.(type) {
670 case *btcAddress:
671 e := &addrEntry{
672 addr: *btcAddr,
673 }
674 copy(e.pubKeyHash160[:], btcAddr.AddrHash())
675 if btcAddr.Imported() {
676 // No order for imported addresses.
677 importedAddrs = append(importedAddrs, e)
678 } else if btcAddr.chainIndex >= 0 {
679 // Chained addresses are sorted. This is
680 // kind of nice but probably isn't necessary.
681 chainedAddrs[btcAddr.chainIndex] = e
682 }
683 case *scriptAddress:
684 e := &scriptEntry{
685 script: *btcAddr,
686 }
687 copy(e.scriptHash160[:], btcAddr.AddrHash())
688 // scripts are always imported
689 importedAddrs = append(importedAddrs, e)
690 }
691 }
692 wts = append(chainedAddrs, importedAddrs...)
693 appendedEntries := varEntries{store: s, entries: wts}
694 // Iterate through each entry needing to be written. If data implements io.WriterTo, use its WriteTo func.
695 // Otherwise, data is a pointer to a fixed size value.
696 datas := []interface{}{
697 &fileID,
698 &VersCurrent,
699 s.net,
700 &s.flags,
701 make([]byte, 6), // Hash for Armory unique ID
702 &s.createDate,
703 &s.name,
704 &s.desc,
705 &s.highestUsed,
706 &s.kdfParams,
707 make([]byte, 256),
708 &s.keyGenerator,
709 newUnusedSpace(1024, &s.recent),
710 &appendedEntries,
711 }
712 var written int64
713 for _, data := range datas {
714 if s, ok := data.(io.WriterTo); ok {
715 written, e = s.WriteTo(w)
716 } else {
717 written, e = binaryWrite(w, binary.LittleEndian, data)
718 }
719 n += written
720 if e != nil {
721 return n, e
722 }
723 }
724 return n, nil
725 }
726 727 // TODO: set this automatically.
728 729 // MarkDirty is
730 func (s *Store) MarkDirty() {
731 s.mtx.Lock()
732 defer s.mtx.Unlock()
733 s.dirty = true
734 }
735 736 // WriteIfDirty is
737 func (s *Store) WriteIfDirty() (e error) {
738 s.mtx.RLock()
739 if !s.dirty {
740 s.mtx.RUnlock()
741 return nil
742 }
743 // TempFile creates the file 0600, so no need to chmod it.
744 fi, e := ioutil.TempFile(s.dir, s.file)
745 if e != nil {
746 s.mtx.RUnlock()
747 return e
748 }
749 fiPath := fi.Name()
750 _, e = s.writeTo(fi)
751 if e != nil {
752 s.mtx.RUnlock()
753 if e = fi.Close(); E.Chk(e) {
754 }
755 return e
756 }
757 e = fi.Sync()
758 if e != nil {
759 s.mtx.RUnlock()
760 if e = fi.Close(); E.Chk(e) {
761 }
762 return e
763 }
764 if e = fi.Close(); E.Chk(e) {
765 }
766 e = rename.Atomic(fiPath, s.path)
767 s.mtx.RUnlock()
768 if e == nil {
769 s.mtx.Lock()
770 s.dirty = false
771 s.mtx.Unlock()
772 }
773 return e
774 }
775 776 // OpenDir opens a new key store from the specified directory.
777 //
778 // If the file does not exist, the error from the os package will be returned, and can be checked with os.IsNotExist to
779 // differentiate missing file errors from others (including deserialization).
780 func OpenDir(dir string) (*Store, error) {
781 path := filepath.Join(dir, Filename)
782 fi, e := os.OpenFile(path, os.O_RDONLY, 0)
783 if e != nil {
784 return nil, e
785 }
786 defer func() {
787 if e = fi.Close(); E.Chk(e) {
788 }
789 }()
790 store := new(Store)
791 _, e = store.ReadFrom(fi)
792 if e != nil {
793 return nil, e
794 }
795 store.path = path
796 store.dir = dir
797 store.file = Filename
798 return store, nil
799 }
800 801 // Unlock derives an AES key from passphrase and key store's KDF parameters and unlocks the root key of the key store.
802 // If the unlock was successful, the key store's secret key is saved, allowing the decryption of any encrypted private
803 // key. Any addresses created while the key store was locked without private keys are created at this time.
804 func (s *Store) Unlock(passphrase []byte) (e error) {
805 s.mtx.Lock()
806 defer s.mtx.Unlock()
807 if s.flags.watchingOnly {
808 return ErrWatchingOnly
809 }
810 // Derive key from KDF parameters and passphrase.
811 key := kdf(passphrase, &s.kdfParams)
812 // Unlock root address with derived key.
813 if _, e = s.keyGenerator.unlock(key); E.Chk(e) {
814 return e
815 }
816 // If unlock was successful, save the passphrase and aes key.
817 s.passphrase = passphrase
818 s.secret = key
819 return s.createMissingPrivateKeys()
820 }
821 822 // Lock performs a best try effort to remove and zero all secret keys associated with the key store.
823 func (s *Store) Lock() (e error) {
824 s.mtx.Lock()
825 defer s.mtx.Unlock()
826 if s.flags.watchingOnly {
827 return ErrWatchingOnly
828 }
829 // Remove clear text passphrase from key store.
830 if s.isLocked() {
831 e = ErrLocked
832 } else {
833 zero(s.passphrase)
834 s.passphrase = nil
835 zero(s.secret)
836 s.secret = nil
837 }
838 // Remove clear text private keys from all address entries.
839 for _, addr := range s.addrMap {
840 if baddr, ok := addr.(*btcAddress); ok {
841 _ = baddr.lock()
842 }
843 }
844 return e
845 }
846 847 // ChangePassphrase creates a new AES key from a new passphrase and re-encrypts all encrypted private keys with the new
848 // key.
849 func (s *Store) ChangePassphrase(new []byte) (e error) {
850 s.mtx.Lock()
851 defer s.mtx.Unlock()
852 if s.flags.watchingOnly {
853 return ErrWatchingOnly
854 }
855 if s.isLocked() {
856 return ErrLocked
857 }
858 oldkey := s.secret
859 newkey := kdf(new, &s.kdfParams)
860 for _, wa := range s.addrMap {
861 // Only btcAddresses curently have private keys.
862 a, ok := wa.(*btcAddress)
863 if !ok {
864 continue
865 }
866 if e := a.changeEncryptionKey(oldkey, newkey); E.Chk(e) {
867 return e
868 }
869 }
870 // zero old secrets.
871 zero(s.passphrase)
872 zero(s.secret)
873 // Save new secrets.
874 s.passphrase = new
875 s.secret = newkey
876 return nil
877 }
878 func zero(b []byte) {
879 for i := range b {
880 b[i] = 0
881 }
882 }
883 884 // IsLocked returns whether a key store is unlocked (in which case the key is saved in memory), or locked.
885 func (s *Store) IsLocked() bool {
886 s.mtx.RLock()
887 defer s.mtx.RUnlock()
888 return s.isLocked()
889 }
890 func (s *Store) isLocked() bool {
891 return len(s.secret) != 32
892 }
893 894 // NextChainedAddress attempts to get the next chained address. If the key store is unlocked, the next pubkey and
895 // private key of the address chain are derived.
896 //
897 // If the key store is locke, only the next pubkey is derived, and the private key will be generated on next unlock.
898 func (s *Store) NextChainedAddress(bs *BlockStamp) (btcaddr.Address, error) {
899 s.mtx.Lock()
900 defer s.mtx.Unlock()
901 return s.nextChainedAddress(bs)
902 }
903 func (s *Store) nextChainedAddress(bs *BlockStamp) (btcaddr.Address, error) {
904 addr, e := s.nextChainedBtcAddress(bs)
905 if e != nil {
906 return nil, e
907 }
908 return addr.Address(), nil
909 }
910 911 // ChangeAddress returns the next chained address from the key store, marking the address for a change transaction
912 // output.
913 func (s *Store) ChangeAddress(bs *BlockStamp) (btcaddr.Address, error) {
914 s.mtx.Lock()
915 defer s.mtx.Unlock()
916 addr, e := s.nextChainedBtcAddress(bs)
917 if e != nil {
918 return nil, e
919 }
920 addr.flags.change = true
921 // Create and return payment address for address hash.
922 return addr.Address(), nil
923 }
924 func (s *Store) nextChainedBtcAddress(bs *BlockStamp) (*btcAddress, error) {
925 // Attempt to get address hash of next chained address.
926 nextAPKH, ok := s.chainIdxMap[s.highestUsed+1]
927 if !ok {
928 if s.isLocked() {
929 // Chain pubkeys.
930 if e := s.extendLocked(bs); E.Chk(e) {
931 return nil, e
932 }
933 } else {
934 // Chain private and pubkeys.
935 if e := s.extendUnlocked(bs); E.Chk(e) {
936 return nil, e
937 }
938 }
939 // Should be added to the internal maps, try lookup again.
940 nextAPKH, ok = s.chainIdxMap[s.highestUsed+1]
941 if !ok {
942 return nil, errors.New("chain index map inproperly updated")
943 }
944 }
945 // Look up address.
946 addr, ok := s.addrMap[getAddressKey(nextAPKH)]
947 if !ok {
948 return nil, errors.New("cannot find generated address")
949 }
950 btcAddr, ok := addr.(*btcAddress)
951 if !ok {
952 return nil, errors.New("found non-pubkey chained address")
953 }
954 s.highestUsed++
955 return btcAddr, nil
956 }
957 958 // LastChainedAddress returns the most recently requested chained address from calling NextChainedAddress, or the root
959 // address if no chained addresses have been requested.
960 func (s *Store) LastChainedAddress() btcaddr.Address {
961 s.mtx.RLock()
962 defer s.mtx.RUnlock()
963 return s.chainIdxMap[s.highestUsed]
964 }
965 966 // extendUnlocked grows address chain for an unlocked keystore.
967 func (s *Store) extendUnlocked(bs *BlockStamp) (e error) {
968 // Get last chained address. New chained addresses will be chained off of this address's chaincode and private key.
969 a := s.chainIdxMap[s.lastChainIdx]
970 waddr, ok := s.addrMap[getAddressKey(a)]
971 if !ok {
972 return errors.New("expected last chained address not found")
973 }
974 if s.isLocked() {
975 return ErrLocked
976 }
977 lastAddr, ok := waddr.(*btcAddress)
978 if !ok {
979 return errors.New("found non-pubkey chained address")
980 }
981 privkey, e := lastAddr.unlock(s.secret)
982 if e != nil {
983 return e
984 }
985 cc := lastAddr.chaincode[:]
986 privkey, e = chainedPrivKey(privkey, lastAddr.pubKeyBytes(), cc)
987 if e != nil {
988 return e
989 }
990 newAddr, e := newBtcAddress(s, privkey, nil, bs, true)
991 if e != nil {
992 return e
993 }
994 if e = newAddr.verifyKeypairs(); E.Chk(e) {
995 return e
996 }
997 if e = newAddr.encrypt(s.secret); E.Chk(e) {
998 return e
999 }
1000 a = newAddr.Address()
1001 s.addrMap[getAddressKey(a)] = newAddr
1002 newAddr.chainIndex = lastAddr.chainIndex + 1
1003 s.chainIdxMap[newAddr.chainIndex] = a
1004 s.lastChainIdx++
1005 copy(newAddr.chaincode[:], cc)
1006 return nil
1007 }
1008 1009 // extendLocked creates one new address without a private key (allowing for extending the address chain from a locked
1010 // key store) chained from the last used chained address and adds the address to the key store's internal bookkeeping
1011 // structures.
1012 func (s *Store) extendLocked(bs *BlockStamp) (e error) {
1013 a := s.chainIdxMap[s.lastChainIdx]
1014 waddr, ok := s.addrMap[getAddressKey(a)]
1015 if !ok {
1016 return errors.New("expected last chained address not found")
1017 }
1018 addr, ok := waddr.(*btcAddress)
1019 if !ok {
1020 return errors.New("found non-pubkey chained address")
1021 }
1022 cc := addr.chaincode[:]
1023 nextPubkey, e := chainedPubKey(addr.pubKeyBytes(), cc)
1024 if e != nil {
1025 return e
1026 }
1027 newaddr, e := newBtcAddressWithoutPrivkey(s, nextPubkey, nil, bs)
1028 if e != nil {
1029 return e
1030 }
1031 a = newaddr.Address()
1032 s.addrMap[getAddressKey(a)] = newaddr
1033 newaddr.chainIndex = addr.chainIndex + 1
1034 s.chainIdxMap[newaddr.chainIndex] = a
1035 s.lastChainIdx++
1036 copy(newaddr.chaincode[:], cc)
1037 if s.missingKeysStart == rootKeyChainIdx {
1038 s.missingKeysStart = newaddr.chainIndex
1039 }
1040 return nil
1041 }
1042 func (s *Store) createMissingPrivateKeys() (e error) {
1043 idx := s.missingKeysStart
1044 if idx == rootKeyChainIdx {
1045 return nil
1046 }
1047 // Lookup previous address.
1048 apkh, ok := s.chainIdxMap[idx-1]
1049 if !ok {
1050 return errors.New("missing previous chained address")
1051 }
1052 prevWAddr := s.addrMap[getAddressKey(apkh)]
1053 if s.isLocked() {
1054 return ErrLocked
1055 }
1056 prevAddr, ok := prevWAddr.(*btcAddress)
1057 if !ok {
1058 return errors.New("found non-pubkey chained address")
1059 }
1060 prevPrivKey, e := prevAddr.unlock(s.secret)
1061 if e != nil {
1062 return e
1063 }
1064 for i := idx; ; i++ {
1065 // Get the next private key for the ith address in the address chain.
1066 ithPrivKey, e := chainedPrivKey(
1067 prevPrivKey,
1068 prevAddr.pubKeyBytes(), prevAddr.chaincode[:],
1069 )
1070 if e != nil {
1071 return e
1072 }
1073 // Get the address with the missing private key, set, and encrypt.
1074 apkh, ok := s.chainIdxMap[i]
1075 if !ok {
1076 // Finished.
1077 break
1078 }
1079 waddr := s.addrMap[getAddressKey(apkh)]
1080 addr, ok := waddr.(*btcAddress)
1081 if !ok {
1082 return errors.New("found non-pubkey chained address")
1083 }
1084 addr.privKeyCT = ithPrivKey
1085 if e := addr.encrypt(s.secret); E.Chk(e) {
1086 // Avoid bug: see comment for VersUnsetNeedsPrivkeyFlag.
1087 if e != ErrAlreadyEncrypted || s.vers.LT(VersUnsetNeedsPrivkeyFlag) {
1088 return e
1089 }
1090 }
1091 addr.flags.createPrivKeyNextUnlock = false
1092 // Set previous address and private key for next iteration.
1093 prevAddr = addr
1094 prevPrivKey = ithPrivKey
1095 }
1096 s.missingKeysStart = rootKeyChainIdx
1097 return nil
1098 }
1099 1100 // Address returns an walletAddress structure for an address in a key store. This address may be typecast into other
1101 // interfaces (like PubKeyAddress and ScriptAddress) if specific information e.g. keys is required.
1102 func (s *Store) Address(a btcaddr.Address) (WalletAddress, error) {
1103 s.mtx.RLock()
1104 defer s.mtx.RUnlock()
1105 // Look up address by address hash.
1106 btcaddr, ok := s.addrMap[getAddressKey(a)]
1107 if !ok {
1108 return nil, ErrAddressNotFound
1109 }
1110 return btcaddr, nil
1111 }
1112 1113 // Net returns the bitcoin network parameters for this key store.
1114 func (s *Store) Net() *chaincfg.Params {
1115 s.mtx.RLock()
1116 defer s.mtx.RUnlock()
1117 return s.netParams()
1118 }
1119 func (s *Store) netParams() *chaincfg.Params {
1120 return (*chaincfg.Params)(s.net)
1121 }
1122 1123 // SetSyncStatus sets the sync status for a single key store address. This may error if the address is not found in the
1124 // key store.
1125 //
1126 // When marking an address as unsynced, only the type Unsynced matters. The value is ignored.
1127 func (s *Store) SetSyncStatus(a btcaddr.Address, ss SyncStatus) (e error) {
1128 s.mtx.Lock()
1129 defer s.mtx.Unlock()
1130 wa, ok := s.addrMap[getAddressKey(a)]
1131 if !ok {
1132 return ErrAddressNotFound
1133 }
1134 wa.setSyncStatus(ss)
1135 return nil
1136 }
1137 1138 // SetSyncedWith marks already synced addresses in the key store to be in sync with the recently-seen block described by
1139 // the blockstamp.
1140 //
1141 // Unsynced addresses are unaffected by this method and must be marked as in sync with MarkAddressSynced or
1142 // MarkAllSynced to be considered in sync with bs.
1143 //
1144 // If bs is nil, the entire key store is marked unsynced.
1145 func (s *Store) SetSyncedWith(bs *BlockStamp) {
1146 s.mtx.Lock()
1147 defer s.mtx.Unlock()
1148 if bs == nil {
1149 s.recent.hashes = s.recent.hashes[:0]
1150 s.recent.lastHeight = s.keyGenerator.firstBlock
1151 s.keyGenerator.setSyncStatus(Unsynced(s.keyGenerator.firstBlock))
1152 return
1153 }
1154 // Chk if we're trying to rollback the last seen history.
1155 //
1156 // If so, and this bs is already saved, remove anything after and return. Otherwise, remove previous hashes.
1157 if bs.Height < s.recent.lastHeight {
1158 maybeIdx := len(s.recent.hashes) - 1 - int(s.recent.lastHeight-bs.Height)
1159 if maybeIdx >= 0 && maybeIdx < len(s.recent.hashes) &&
1160 *s.recent.hashes[maybeIdx] == *bs.Hash {
1161 s.recent.lastHeight = bs.Height
1162 // subslice out the removed hashes.
1163 s.recent.hashes = s.recent.hashes[:maybeIdx]
1164 return
1165 }
1166 s.recent.hashes = nil
1167 }
1168 if bs.Height != s.recent.lastHeight+1 {
1169 s.recent.hashes = nil
1170 }
1171 s.recent.lastHeight = bs.Height
1172 if len(s.recent.hashes) == 20 {
1173 // Make room for the most recent hash.
1174 copy(s.recent.hashes, s.recent.hashes[1:])
1175 // Set new block in the last position.
1176 s.recent.hashes[19] = bs.Hash
1177 } else {
1178 s.recent.hashes = append(s.recent.hashes, bs.Hash)
1179 }
1180 }
1181 1182 // SyncedTo returns details about the block that a wallet is marked at least synced through. The height is the height
1183 // that rescans should start at when syncing a wallet back to the best chain.
1184 //
1185 // NOTE: If the hash of the synced block is not known, hash will be nil, and must be obtained from elsewhere. This must
1186 // be explicitly checked before dereferencing the pointer.
1187 func (s *Store) SyncedTo() (hash *chainhash.Hash, height int32) {
1188 s.mtx.RLock()
1189 defer s.mtx.RUnlock()
1190 switch h, ok := s.keyGenerator.SyncStatus().(PartialSync); {
1191 case ok && int32(h) > s.recent.lastHeight:
1192 height = int32(h)
1193 default:
1194 height = s.recent.lastHeight
1195 if n := len(s.recent.hashes); n != 0 {
1196 hash = s.recent.hashes[n-1]
1197 }
1198 }
1199 for _, a := range s.addrMap {
1200 var syncHeight int32
1201 switch e := a.SyncStatus().(type) {
1202 case Unsynced:
1203 syncHeight = int32(e)
1204 case PartialSync:
1205 syncHeight = int32(e)
1206 case FullSync:
1207 continue
1208 }
1209 if syncHeight < height {
1210 height = syncHeight
1211 hash = nil
1212 // Can't go lower than 0.
1213 if height == 0 {
1214 return
1215 }
1216 }
1217 }
1218 return
1219 }
1220 1221 // NewIterateRecentBlocks returns an iterator for recently-seen blocks. The iterator starts at the most recently-added
1222 // block, and Prev should be used to access earlier blocks.
1223 func (s *Store) NewIterateRecentBlocks() *BlockIterator {
1224 s.mtx.RLock()
1225 defer s.mtx.RUnlock()
1226 return s.recent.iter(s)
1227 }
1228 1229 // ImportPrivateKey imports a WIF private key into the keystore. The imported address is created using either a
1230 // compressed or uncompressed serialized public key, depending on the CompressPubKey bool of the WIF.
1231 func (s *Store) ImportPrivateKey(wif *util.WIF, bs *BlockStamp) (btcaddr.Address, error) {
1232 s.mtx.Lock()
1233 defer s.mtx.Unlock()
1234 if s.flags.watchingOnly {
1235 return nil, ErrWatchingOnly
1236 }
1237 // First, must check that the key being imported will not result in a duplicate address.
1238 pkh := btcaddr.Hash160(wif.SerializePubKey())
1239 if _, ok := s.addrMap[addressKey(pkh)]; ok {
1240 return nil, ErrDuplicate
1241 }
1242 // The key store must be unlocked to encrypt the imported private key.
1243 if s.isLocked() {
1244 return nil, ErrLocked
1245 }
1246 // Create new address with this private key.
1247 privKey := wif.PrivKey.Serialize()
1248 btcaddr, e := newBtcAddress(s, privKey, nil, bs, wif.CompressPubKey)
1249 if e != nil {
1250 return nil, e
1251 }
1252 btcaddr.chainIndex = importedKeyChainIdx
1253 // Mark as unsynced if import height is below currently-synced height.
1254 if len(s.recent.hashes) != 0 && bs.Height < s.recent.lastHeight {
1255 btcaddr.flags.unsynced = true
1256 }
1257 // Encrypt imported address with the derived AES key.
1258 if e = btcaddr.encrypt(s.secret); E.Chk(e) {
1259 return nil, e
1260 }
1261 addr := btcaddr.Address()
1262 // Add address to key store's bookkeeping structures. Adding to the map will result in the imported address being
1263 // serialized on the next WriteTo call.
1264 s.addrMap[getAddressKey(addr)] = btcaddr
1265 s.importedAddrs = append(s.importedAddrs, btcaddr)
1266 // Create and return address.
1267 return addr, nil
1268 }
1269 1270 // ImportScript creates a new scriptAddress with a user-provided script and adds it to the key store.
1271 func (s *Store) ImportScript(script []byte, bs *BlockStamp) (btcaddr.Address, error) {
1272 s.mtx.Lock()
1273 defer s.mtx.Unlock()
1274 if s.flags.watchingOnly {
1275 return nil, ErrWatchingOnly
1276 }
1277 if _, ok := s.addrMap[addressKey(btcaddr.Hash160(script))]; ok {
1278 return nil, ErrDuplicate
1279 }
1280 // Create new address with this private key.
1281 scriptaddr, e := newScriptAddress(s, script, bs)
1282 if e != nil {
1283 return nil, e
1284 }
1285 // Mark as unsynced if import height is below currently-synced height.
1286 if len(s.recent.hashes) != 0 && bs.Height < s.recent.lastHeight {
1287 scriptaddr.flags.unsynced = true
1288 }
1289 // Add address to key store's bookkeeping structures. Adding to the map will result in the imported address being
1290 // serialized on the next WriteTo call.
1291 addr := scriptaddr.Address()
1292 s.addrMap[getAddressKey(addr)] = scriptaddr
1293 s.importedAddrs = append(s.importedAddrs, scriptaddr)
1294 // Create and return address.
1295 return addr, nil
1296 }
1297 1298 // CreateDate returns the Unix time of the key store creation time. This is used to compare the key store creation time
1299 // against block headers and set a better minimum block height of where to being rescans.
1300 func (s *Store) CreateDate() int64 {
1301 s.mtx.RLock()
1302 defer s.mtx.RUnlock()
1303 return s.createDate
1304 }
1305 1306 // ExportWatchingWallet creates and returns a new key store with the same addresses in w, but as a watching-only key
1307 // store without any private keys.
1308 //
1309 // New addresses created by the watching key store will match the new addresses created the original key store (thanks
1310 // to public key address chaining), but will be missing the associated private keys.
1311 func (s *Store) ExportWatchingWallet() (*Store, error) {
1312 s.mtx.RLock()
1313 defer s.mtx.RUnlock()
1314 // Don't continue if key store is already watching-only.
1315 if s.flags.watchingOnly {
1316 return nil, ErrWatchingOnly
1317 }
1318 // Copy members of w into a new key store, but mark as watching-only and do not include any private keys.
1319 ws := &Store{
1320 vers: s.vers,
1321 net: s.net,
1322 flags: walletFlags{
1323 useEncryption: false,
1324 watchingOnly: true,
1325 },
1326 name: s.name,
1327 desc: s.desc,
1328 createDate: s.createDate,
1329 highestUsed: s.highestUsed,
1330 recent: recentBlocks{
1331 lastHeight: s.recent.lastHeight,
1332 },
1333 addrMap: make(map[addressKey]walletAddress),
1334 // todo oga make me a list
1335 chainIdxMap: make(map[int64]btcaddr.Address),
1336 lastChainIdx: s.lastChainIdx,
1337 }
1338 kgwc := s.keyGenerator.watchingCopy(ws)
1339 ws.keyGenerator = *(kgwc.(*btcAddress))
1340 if len(s.recent.hashes) != 0 {
1341 ws.recent.hashes = make([]*chainhash.Hash, 0, len(s.recent.hashes))
1342 for _, hash := range s.recent.hashes {
1343 hashCpy := *hash
1344 ws.recent.hashes = append(ws.recent.hashes, &hashCpy)
1345 }
1346 }
1347 for apkh, addr := range s.addrMap {
1348 if !addr.Imported() {
1349 // Must be a btcAddress if !imported.
1350 btcAddr := addr.(*btcAddress)
1351 ws.chainIdxMap[btcAddr.chainIndex] =
1352 addr.Address()
1353 }
1354 apkhCopy := apkh
1355 ws.addrMap[apkhCopy] = addr.watchingCopy(ws)
1356 }
1357 if len(s.importedAddrs) != 0 {
1358 ws.importedAddrs = make(
1359 []walletAddress, 0,
1360 len(s.importedAddrs),
1361 )
1362 for _, addr := range s.importedAddrs {
1363 ws.importedAddrs = append(ws.importedAddrs, addr.watchingCopy(ws))
1364 }
1365 }
1366 return ws, nil
1367 }
1368 1369 // SyncStatus is the interface type for all sync variants.
1370 type SyncStatus interface {
1371 ImplementsSyncStatus()
1372 }
1373 type (
1374 // Unsynced is a type representing an unsynced address. When this is returned by a key store method, the value is
1375 // the recorded first seen block height.
1376 Unsynced int32
1377 // PartialSync is a type representing a partially synced address (for example, due to the result of a
1378 // partially-completed rescan).
1379 PartialSync int32
1380 // FullSync is a type representing an address that is in sync with the recently seen blocks.
1381 FullSync struct{}
1382 )
1383 1384 // ImplementsSyncStatus is implemented to make Unsynced a SyncStatus.
1385 func (u Unsynced) ImplementsSyncStatus() {
1386 }
1387 1388 // ImplementsSyncStatus is implemented to make PartialSync a SyncStatus.
1389 func (p PartialSync) ImplementsSyncStatus() {
1390 }
1391 1392 // ImplementsSyncStatus is implemented to make FullSync a SyncStatus.
1393 func (f FullSync) ImplementsSyncStatus() {
1394 }
1395 1396 // WalletAddress is an interface that provides acces to information regarding an address managed by a key store.
1397 // Concrete implementations of this type may provide further fields to provide information specific to that type of
1398 // address.
1399 type WalletAddress interface {
1400 // Address returns a util.Address for the backing address.
1401 Address() btcaddr.Address
1402 // AddrHash returns the key or script hash related to the address
1403 AddrHash() string
1404 // FirstBlock returns the first block an address could be in.
1405 FirstBlock() int32
1406 // Imported returns true if the backing address was imported instead
1407 // of being part of an address chain.
1408 Imported() bool
1409 // Change returns true if the backing address was created for a change output
1410 // of a transaction.
1411 Change() bool
1412 // Compressed returns true if the backing address is compressed.
1413 Compressed() bool
1414 // SyncStatus returns the current synced state of an address.
1415 SyncStatus() SyncStatus
1416 }
1417 1418 // SortedActiveAddresses returns all key store addresses that have been requested to be generated. These do not include
1419 // unused addresses in the key pool. Use this when ordered addresses are needed. Otherwise, ActiveAddresses is
1420 // preferred.
1421 func (s *Store) SortedActiveAddresses() []WalletAddress {
1422 s.mtx.RLock()
1423 defer s.mtx.RUnlock()
1424 addrs := make(
1425 []WalletAddress, 0,
1426 s.highestUsed+int64(len(s.importedAddrs))+1,
1427 )
1428 for i := int64(rootKeyChainIdx); i <= s.highestUsed; i++ {
1429 a := s.chainIdxMap[i]
1430 info, ok := s.addrMap[getAddressKey(a)]
1431 if ok {
1432 addrs = append(addrs, info)
1433 }
1434 }
1435 for _, addr := range s.importedAddrs {
1436 addrs = append(addrs, addr)
1437 }
1438 return addrs
1439 }
1440 1441 // ActiveAddresses returns a map between active payment addresses and their full info. These do not include unused
1442 // addresses in the key pool. If addresses must be sorted, use SortedActiveAddresses.
1443 func (s *Store) ActiveAddresses() map[btcaddr.Address]WalletAddress {
1444 s.mtx.RLock()
1445 defer s.mtx.RUnlock()
1446 addrs := make(map[btcaddr.Address]WalletAddress)
1447 for i := int64(rootKeyChainIdx); i <= s.highestUsed; i++ {
1448 a := s.chainIdxMap[i]
1449 addr := s.addrMap[getAddressKey(a)]
1450 addrs[addr.Address()] = addr
1451 }
1452 for _, addr := range s.importedAddrs {
1453 addrs[addr.Address()] = addr
1454 }
1455 return addrs
1456 }
1457 1458 // ExtendActiveAddresses gets or creates the next n addresses from the address chain and marks each as active. This is
1459 // used to recover deterministic (not imported) addresses from a key store backup, or to keep the active addresses in
1460 // sync between an encrypted key store with private keys and an exported watching key store without.
1461 //
1462 // A slice is returned with the util.Address of each new address. The blockchain must be rescanned for these addresses.
1463 func (s *Store) ExtendActiveAddresses(n int) ([]btcaddr.Address, error) {
1464 s.mtx.Lock()
1465 defer s.mtx.Unlock()
1466 last := s.addrMap[getAddressKey(s.chainIdxMap[s.highestUsed])]
1467 bs := &BlockStamp{Height: last.FirstBlock()}
1468 addrs := make([]btcaddr.Address, n)
1469 for i := 0; i < n; i++ {
1470 addr, e := s.nextChainedAddress(bs)
1471 if e != nil {
1472 return nil, e
1473 }
1474 addrs[i] = addr
1475 }
1476 return addrs, nil
1477 }
1478 1479 type walletFlags struct {
1480 useEncryption bool
1481 watchingOnly bool
1482 }
1483 1484 func (wf *walletFlags) ReadFrom(r io.Reader) (int64, error) {
1485 var b [8]byte
1486 n, e := io.ReadFull(r, b[:])
1487 if e != nil {
1488 return int64(n), e
1489 }
1490 wf.useEncryption = b[0]&(1<<0) != 0
1491 wf.watchingOnly = b[0]&(1<<1) != 0
1492 return int64(n), nil
1493 }
1494 func (wf *walletFlags) WriteTo(w io.Writer) (int64, error) {
1495 var b [8]byte
1496 if wf.useEncryption {
1497 b[0] |= 1 << 0
1498 }
1499 if wf.watchingOnly {
1500 b[0] |= 1 << 1
1501 }
1502 n, e := w.Write(b[:])
1503 return int64(n), e
1504 }
1505 1506 type addrFlags struct {
1507 hasPrivKey bool
1508 hasPubKey bool
1509 encrypted bool
1510 createPrivKeyNextUnlock bool
1511 compressed bool
1512 change bool
1513 unsynced bool
1514 partialSync bool
1515 }
1516 1517 func (af *addrFlags) ReadFrom(r io.Reader) (int64, error) {
1518 var b [8]byte
1519 n, e := io.ReadFull(r, b[:])
1520 if e != nil {
1521 return int64(n), e
1522 }
1523 af.hasPrivKey = b[0]&(1<<0) != 0
1524 af.hasPubKey = b[0]&(1<<1) != 0
1525 af.encrypted = b[0]&(1<<2) != 0
1526 af.createPrivKeyNextUnlock = b[0]&(1<<3) != 0
1527 af.compressed = b[0]&(1<<4) != 0
1528 af.change = b[0]&(1<<5) != 0
1529 af.unsynced = b[0]&(1<<6) != 0
1530 af.partialSync = b[0]&(1<<7) != 0
1531 // Currently (at least until watching-only key stores are implemented) btcwallet shall refuse to open any
1532 // unencrypted addresses. This check only makes sense if there is a private key to encrypt, which there may not be
1533 // if the keypool was extended from just the last public key and no private keys were written.
1534 if af.hasPrivKey && !af.encrypted {
1535 return int64(n), errors.New("private key is unencrypted")
1536 }
1537 return int64(n), nil
1538 }
1539 func (af *addrFlags) WriteTo(w io.Writer) (int64, error) {
1540 var b [8]byte
1541 if af.hasPrivKey {
1542 b[0] |= 1 << 0
1543 }
1544 if af.hasPubKey {
1545 b[0] |= 1 << 1
1546 }
1547 if af.hasPrivKey && !af.encrypted {
1548 // We only support encrypted privkeys.
1549 return 0, errors.New("address must be encrypted")
1550 }
1551 if af.encrypted {
1552 b[0] |= 1 << 2
1553 }
1554 if af.createPrivKeyNextUnlock {
1555 b[0] |= 1 << 3
1556 }
1557 if af.compressed {
1558 b[0] |= 1 << 4
1559 }
1560 if af.change {
1561 b[0] |= 1 << 5
1562 }
1563 if af.unsynced {
1564 b[0] |= 1 << 6
1565 }
1566 if af.partialSync {
1567 b[0] |= 1 << 7
1568 }
1569 n, e := w.Write(b[:])
1570 return int64(n), e
1571 }
1572 1573 // recentBlocks holds at most the last 20 seen block hashes as well as the block height of the most recently seen block.
1574 type recentBlocks struct {
1575 hashes []*chainhash.Hash
1576 lastHeight int32
1577 }
1578 1579 func (rb *recentBlocks) readFromVersion(v ksVersion, r io.Reader) (int64, error) {
1580 if !v.LT(Vers20LastBlocks) {
1581 // Use current ksVersion.
1582 return rb.ReadFrom(r)
1583 }
1584 // Old file versions only saved the most recently seen block height and hash, not the last 20.
1585 var read int64
1586 // Read height.
1587 var heightBytes [4]byte // 4 bytes for a int32
1588 n, e := io.ReadFull(r, heightBytes[:])
1589 read += int64(n)
1590 if e != nil {
1591 return read, e
1592 }
1593 rb.lastHeight = int32(binary.LittleEndian.Uint32(heightBytes[:]))
1594 // If height is -1, the last synced block is unknown, so don't try to read a block hash.
1595 if rb.lastHeight == -1 {
1596 rb.hashes = nil
1597 return read, nil
1598 }
1599 // Read block hash.
1600 var syncedBlockHash chainhash.Hash
1601 n, e = io.ReadFull(r, syncedBlockHash[:])
1602 read += int64(n)
1603 if e != nil {
1604 return read, e
1605 }
1606 rb.hashes = []*chainhash.Hash{
1607 &syncedBlockHash,
1608 }
1609 return read, nil
1610 }
1611 func (rb *recentBlocks) ReadFrom(r io.Reader) (int64, error) {
1612 var read int64
1613 // Read number of saved blocks. This should not exceed 20.
1614 var nBlockBytes [4]byte // 4 bytes for a uint32
1615 n, e := io.ReadFull(r, nBlockBytes[:])
1616 read += int64(n)
1617 if e != nil {
1618 return read, e
1619 }
1620 nBlocks := binary.LittleEndian.Uint32(nBlockBytes[:])
1621 if nBlocks > 20 {
1622 return read, errors.New("number of last seen blocks exceeds maximum of 20")
1623 }
1624 // Read most recently seen block height.
1625 var heightBytes [4]byte // 4 bytes for a int32
1626 n, e = io.ReadFull(r, heightBytes[:])
1627 read += int64(n)
1628 if e != nil {
1629 return read, e
1630 }
1631 height := int32(binary.LittleEndian.Uint32(heightBytes[:]))
1632 // height should not be -1 (or any other negative number) since at this point we should be reading in at least one
1633 // known block.
1634 if height < 0 {
1635 return read, errors.New("expected a block but specified height is negative")
1636 }
1637 // Set last seen height.
1638 rb.lastHeight = height
1639 // Read nBlocks block hashes. Merkles are expected to be in order of oldest to newest, but there's no way to check
1640 // that here.
1641 rb.hashes = make([]*chainhash.Hash, 0, nBlocks)
1642 for i := uint32(0); i < nBlocks; i++ {
1643 var blockHash chainhash.Hash
1644 n, e := io.ReadFull(r, blockHash[:])
1645 read += int64(n)
1646 if e != nil {
1647 return read, e
1648 }
1649 rb.hashes = append(rb.hashes, &blockHash)
1650 }
1651 return read, nil
1652 }
1653 func (rb *recentBlocks) WriteTo(w io.Writer) (int64, error) {
1654 var written int64
1655 // Write number of saved blocks. This should not exceed 20.
1656 nBlocks := uint32(len(rb.hashes))
1657 if nBlocks > 20 {
1658 return written, errors.New("number of last seen blocks exceeds maximum of 20")
1659 }
1660 if nBlocks != 0 && rb.lastHeight < 0 {
1661 return written, errors.New("number of block hashes is positive, but height is negative")
1662 }
1663 var nBlockBytes [4]byte // 4 bytes for a uint32
1664 binary.LittleEndian.PutUint32(nBlockBytes[:], nBlocks)
1665 n, e := w.Write(nBlockBytes[:])
1666 written += int64(n)
1667 if e != nil {
1668 return written, e
1669 }
1670 // Write most recently seen block height.
1671 var heightBytes [4]byte // 4 bytes for a int32
1672 binary.LittleEndian.PutUint32(heightBytes[:], uint32(rb.lastHeight))
1673 n, e = w.Write(heightBytes[:])
1674 written += int64(n)
1675 if e != nil {
1676 return written, e
1677 }
1678 // Write block hashes.
1679 for _, hash := range rb.hashes {
1680 n, e := w.Write(hash[:])
1681 written += int64(n)
1682 if e != nil {
1683 return written, e
1684 }
1685 }
1686 return written, nil
1687 }
1688 1689 // BlockIterator allows for the forwards and backwards iteration of recently seen blocks.
1690 type BlockIterator struct {
1691 storeMtx *sync.RWMutex
1692 height int32
1693 index int
1694 rb *recentBlocks
1695 }
1696 1697 func (rb *recentBlocks) iter(s *Store) *BlockIterator {
1698 if rb.lastHeight == -1 || len(rb.hashes) == 0 {
1699 return nil
1700 }
1701 return &BlockIterator{
1702 storeMtx: &s.mtx,
1703 height: rb.lastHeight,
1704 index: len(rb.hashes) - 1,
1705 rb: rb,
1706 }
1707 }
1708 1709 // Next is
1710 func (it *BlockIterator) Next() bool {
1711 it.storeMtx.RLock()
1712 defer it.storeMtx.RUnlock()
1713 if it.index+1 >= len(it.rb.hashes) {
1714 return false
1715 }
1716 it.index++
1717 return true
1718 }
1719 1720 // Prev is
1721 func (it *BlockIterator) Prev() bool {
1722 it.storeMtx.RLock()
1723 defer it.storeMtx.RUnlock()
1724 if it.index-1 < 0 {
1725 return false
1726 }
1727 it.index--
1728 return true
1729 }
1730 1731 // BlockStamp is
1732 func (it *BlockIterator) BlockStamp() BlockStamp {
1733 it.storeMtx.RLock()
1734 defer it.storeMtx.RUnlock()
1735 return BlockStamp{
1736 Height: it.rb.lastHeight - int32(len(it.rb.hashes)-1-it.index),
1737 Hash: it.rb.hashes[it.index],
1738 }
1739 }
1740 1741 // unusedSpace is a wrapper type to read or write one or more types that btcwallet fits into an unused space left by
1742 // Armory's key store file format.
1743 type unusedSpace struct {
1744 nBytes int // number of unused bytes that armory left.
1745 rfvs []readerFromVersion
1746 }
1747 1748 func newUnusedSpace(nBytes int, rfvs ...readerFromVersion) *unusedSpace {
1749 return &unusedSpace{
1750 nBytes: nBytes,
1751 rfvs: rfvs,
1752 }
1753 }
1754 func (u *unusedSpace) readFromVersion(v ksVersion, r io.Reader) (int64, error) {
1755 var read int64
1756 for _, rfv := range u.rfvs {
1757 n, e := rfv.readFromVersion(v, r)
1758 if e != nil {
1759 return read + n, e
1760 }
1761 read += n
1762 if read > int64(u.nBytes) {
1763 return read, errors.New("read too much from armory's unused space")
1764 }
1765 }
1766 // Read rest of actually unused bytes.
1767 unused := make([]byte, u.nBytes-int(read))
1768 n, e := io.ReadFull(r, unused)
1769 return read + int64(n), e
1770 }
1771 func (u *unusedSpace) WriteTo(w io.Writer) (int64, error) {
1772 var written int64
1773 for _, wt := range u.rfvs {
1774 n, e := wt.WriteTo(w)
1775 if e != nil {
1776 return written + n, e
1777 }
1778 written += n
1779 if written > int64(u.nBytes) {
1780 return written, errors.New("wrote too much to armory's unused space")
1781 }
1782 }
1783 // Write rest of actually unused bytes.
1784 unused := make([]byte, u.nBytes-int(written))
1785 n, e := w.Write(unused)
1786 return written + int64(n), e
1787 }
1788 1789 // walletAddress is the internal interface used to abstracted around the different address types.
1790 type walletAddress interface {
1791 io.ReaderFrom
1792 io.WriterTo
1793 WalletAddress
1794 watchingCopy(*Store) walletAddress
1795 setSyncStatus(SyncStatus)
1796 }
1797 type btcAddress struct {
1798 store *Store
1799 address btcaddr.Address
1800 flags addrFlags
1801 chaincode [32]byte
1802 chainIndex int64
1803 chainDepth int64 // unused
1804 initVector [16]byte
1805 privKey [32]byte
1806 pubKey *ec.PublicKey
1807 firstSeen int64
1808 lastSeen int64
1809 firstBlock int32
1810 partialSyncHeight int32 // This is reappropriated from armory's `lastBlock` field.
1811 privKeyCT []byte // non-nil if unlocked.
1812 }
1813 1814 const (
1815 // Root address has a chain index of -1. Each subsequent chained address increments the index.
1816 rootKeyChainIdx = -1
1817 // Imported private keys are not part of the chain, and have a special index of -2.
1818 importedKeyChainIdx = -2
1819 )
1820 const (
1821 pubkeyCompressed byte = 0x2
1822 pubkeyUncompressed byte = 0x4
1823 )
1824 1825 type publicKey []byte
1826 1827 func (k *publicKey) ReadFrom(r io.Reader) (n int64, e error) {
1828 var read int64
1829 var format byte
1830 read, e = binaryRead(r, binary.LittleEndian, &format)
1831 if e != nil {
1832 return n + read, e
1833 }
1834 n += read
1835 // Remove the oddness from the format
1836 noodd := format
1837 noodd &= ^byte(0x1)
1838 var s []byte
1839 switch noodd {
1840 case pubkeyUncompressed:
1841 // Read the remaining 64 bytes.
1842 s = make([]byte, 64)
1843 case pubkeyCompressed:
1844 // Read the remaining 32 bytes.
1845 s = make([]byte, 32)
1846 default:
1847 return n, errors.New("unrecognized pubkey format")
1848 }
1849 read, e = binaryRead(r, binary.LittleEndian, &s)
1850 if e != nil {
1851 return n + read, e
1852 }
1853 n += read
1854 *k = append([]byte{format}, s...)
1855 return
1856 }
1857 func (k *publicKey) WriteTo(w io.Writer) (n int64, e error) {
1858 return binaryWrite(w, binary.LittleEndian, []byte(*k))
1859 }
1860 1861 // PubKeyAddress implements WalletAddress and additionally provides the pubkey for a pubkey-based address.
1862 type PubKeyAddress interface {
1863 WalletAddress
1864 // PubKey returns the public key associated with the address.
1865 PubKey() *ec.PublicKey
1866 // ExportPubKey returns the public key associated with the address serialised as a hex encoded string.
1867 ExportPubKey() string
1868 // PrivKey returns the private key for the address. It can fail if the key store is watching only, the key store is
1869 // locked, or the address doesn't have any keys.
1870 PrivKey() (*ec.PrivateKey, error)
1871 // ExportPrivKey exports the WIF private key.
1872 ExportPrivKey() (*util.WIF, error)
1873 }
1874 1875 // newBtcAddress initializes and returns a new address. privkey must be 32 bytes. iv must be 16 bytes, or nil (in which
1876 // case it is randomly generated).
1877 func newBtcAddress(wallet *Store, privkey, iv []byte, bs *BlockStamp, compressed bool) (addr *btcAddress, e error) {
1878 if len(privkey) != 32 {
1879 return nil, errors.New("private key is not 32 bytes")
1880 }
1881 addr, e = newBtcAddressWithoutPrivkey(
1882 wallet,
1883 pubkeyFromPrivkey(privkey, compressed), iv, bs,
1884 )
1885 if e != nil {
1886 return nil, e
1887 }
1888 addr.flags.createPrivKeyNextUnlock = false
1889 addr.flags.hasPrivKey = true
1890 addr.privKeyCT = privkey
1891 return addr, nil
1892 }
1893 1894 // newBtcAddressWithoutPrivkey initializes and returns a new address with an unknown (at the time) private key that must
1895 // be found later. pubkey must be 33 or 65 bytes, and iv must be 16 bytes or empty (in which case it is randomly
1896 // generated).
1897 func newBtcAddressWithoutPrivkey(s *Store, pubkey, iv []byte, bs *BlockStamp) (addr *btcAddress, e error) {
1898 var compressed bool
1899 switch n := len(pubkey); n {
1900 case ec.PubKeyBytesLenCompressed:
1901 compressed = true
1902 case ec.PubKeyBytesLenUncompressed:
1903 compressed = false
1904 default:
1905 return nil, fmt.Errorf("invalid pubkey length %d", n)
1906 }
1907 if len(iv) == 0 {
1908 iv = make([]byte, 16)
1909 if _, e = rand.Read(iv); E.Chk(e) {
1910 return nil, e
1911 }
1912 } else if len(iv) != 16 {
1913 return nil, errors.New("init vector must be nil or 16 bytes large")
1914 }
1915 pk, e := ec.ParsePubKey(pubkey, ec.S256())
1916 if e != nil {
1917 return nil, e
1918 }
1919 address, e := btcaddr.NewPubKeyHash(btcaddr.Hash160(pubkey), s.netParams())
1920 if e != nil {
1921 return nil, e
1922 }
1923 addr = &btcAddress{
1924 flags: addrFlags{
1925 hasPrivKey: false,
1926 hasPubKey: true,
1927 encrypted: false,
1928 createPrivKeyNextUnlock: true,
1929 compressed: compressed,
1930 change: false,
1931 unsynced: false,
1932 },
1933 store: s,
1934 address: address,
1935 firstSeen: time.Now().Unix(),
1936 firstBlock: bs.Height,
1937 pubKey: pk,
1938 }
1939 copy(addr.initVector[:], iv)
1940 return addr, nil
1941 }
1942 1943 // newRootBtcAddress generates a new address, also setting the chaincode and chain index to represent this address as a
1944 // root address.
1945 func newRootBtcAddress(
1946 s *Store, privKey, iv, chaincode []byte,
1947 bs *BlockStamp,
1948 ) (addr *btcAddress, e error) {
1949 if len(chaincode) != 32 {
1950 return nil, errors.New("chaincode is not 32 bytes")
1951 }
1952 // Create new btcAddress with provided inputs. This will always use a compressed pubkey.
1953 addr, e = newBtcAddress(s, privKey, iv, bs, true)
1954 if e != nil {
1955 return nil, e
1956 }
1957 copy(addr.chaincode[:], chaincode)
1958 addr.chainIndex = rootKeyChainIdx
1959 return addr, e
1960 }
1961 1962 // verifyKeypairs creates a signature using the parsed private key and verifies the signature with the parsed public
1963 // key. If either of these steps fail, the keypair generation failed and any funds sent to this address will be
1964 // unspendable. This step requires an unencrypted or unlocked btcAddress.
1965 func (a *btcAddress) verifyKeypairs() (e error) {
1966 if len(a.privKeyCT) != 32 {
1967 return errors.New("private key unavailable")
1968 }
1969 privKey := &ec.PrivateKey{
1970 PublicKey: *a.pubKey.ToECDSA(),
1971 D: new(big.Int).SetBytes(a.privKeyCT),
1972 }
1973 data := "String to sign."
1974 sig, e := privKey.Sign([]byte(data))
1975 if e != nil {
1976 return e
1977 }
1978 ok := sig.Verify([]byte(data), privKey.PubKey())
1979 if !ok {
1980 return errors.New("pubkey verification failed")
1981 }
1982 return nil
1983 }
1984 1985 // ReadFrom reads an encrypted address from an io.Reader.
1986 func (a *btcAddress) ReadFrom(r io.Reader) (n int64, e error) {
1987 var read int64
1988 // Checksums
1989 var chkPubKeyHash uint32
1990 var chkChaincode uint32
1991 var chkInitVector uint32
1992 var chkPrivKey uint32
1993 var chkPubKey uint32
1994 var pubKeyHash [ripemd160.Size]byte
1995 var pubKey publicKey
1996 // Read serialized key store into addr fields and checksums.
1997 datas := []interface{}{
1998 &pubKeyHash,
1999 &chkPubKeyHash,
2000 make([]byte, 4), // ksVersion
2001 &a.flags,
2002 &a.chaincode,
2003 &chkChaincode,
2004 &a.chainIndex,
2005 &a.chainDepth,
2006 &a.initVector,
2007 &chkInitVector,
2008 &a.privKey,
2009 &chkPrivKey,
2010 &pubKey,
2011 &chkPubKey,
2012 &a.firstSeen,
2013 &a.lastSeen,
2014 &a.firstBlock,
2015 &a.partialSyncHeight,
2016 }
2017 for _, data := range datas {
2018 if rf, ok := data.(io.ReaderFrom); ok {
2019 read, e = rf.ReadFrom(r)
2020 } else {
2021 read, e = binaryRead(r, binary.LittleEndian, data)
2022 }
2023 if e != nil {
2024 return n + read, e
2025 }
2026 n += read
2027 }
2028 // Verify checksums, correct errors where possible.
2029 checks := []struct {
2030 data []byte
2031 chk uint32
2032 }{
2033 {pubKeyHash[:], chkPubKeyHash},
2034 {a.chaincode[:], chkChaincode},
2035 {a.initVector[:], chkInitVector},
2036 {a.privKey[:], chkPrivKey},
2037 {pubKey, chkPubKey},
2038 }
2039 for i := range checks {
2040 if e = verifyAndFix(checks[i].data, checks[i].chk); E.Chk(e) {
2041 return n, e
2042 }
2043 }
2044 if !a.flags.hasPubKey {
2045 return n, errors.New("read in an address without a public key")
2046 }
2047 pk, e := ec.ParsePubKey(pubKey, ec.S256())
2048 if e != nil {
2049 return n, e
2050 }
2051 a.pubKey = pk
2052 addr, e := btcaddr.NewPubKeyHash(pubKeyHash[:], a.store.netParams())
2053 if e != nil {
2054 return n, e
2055 }
2056 a.address = addr
2057 return n, nil
2058 }
2059 func (a *btcAddress) WriteTo(w io.Writer) (n int64, e error) {
2060 var written int64
2061 pubKey := a.pubKeyBytes()
2062 hash := a.address.ScriptAddress()
2063 datas := []interface{}{
2064 &hash,
2065 walletHash(hash),
2066 make([]byte, 4), // ksVersion
2067 &a.flags,
2068 &a.chaincode,
2069 walletHash(a.chaincode[:]),
2070 &a.chainIndex,
2071 &a.chainDepth,
2072 &a.initVector,
2073 walletHash(a.initVector[:]),
2074 &a.privKey,
2075 walletHash(a.privKey[:]),
2076 &pubKey,
2077 walletHash(pubKey),
2078 &a.firstSeen,
2079 &a.lastSeen,
2080 &a.firstBlock,
2081 &a.partialSyncHeight,
2082 }
2083 for _, data := range datas {
2084 if wt, ok := data.(io.WriterTo); ok {
2085 written, e = wt.WriteTo(w)
2086 } else {
2087 written, e = binaryWrite(w, binary.LittleEndian, data)
2088 }
2089 if e != nil {
2090 return n + written, e
2091 }
2092 n += written
2093 }
2094 return n, nil
2095 }
2096 2097 // encrypt attempts to encrypt an address's clear text private key, failing if the address is already encrypted or if
2098 // the private key is not 32 bytes. If successful, the encryption flag is set.
2099 func (a *btcAddress) encrypt(key []byte) (e error) {
2100 if a.flags.encrypted {
2101 return ErrAlreadyEncrypted
2102 }
2103 if len(a.privKeyCT) != 32 {
2104 return errors.New("invalid clear text private key")
2105 }
2106 aesBlockEncrypter, e := aes.NewCipher(key)
2107 if e != nil {
2108 return e
2109 }
2110 aesEncrypter := cipher.NewCFBEncrypter(aesBlockEncrypter, a.initVector[:])
2111 aesEncrypter.XORKeyStream(a.privKey[:], a.privKeyCT)
2112 a.flags.hasPrivKey = true
2113 a.flags.encrypted = true
2114 return nil
2115 }
2116 2117 // lock removes the reference this address holds to its clear text private key. This function fails if the address is
2118 // not encrypted.
2119 func (a *btcAddress) lock() (e error) {
2120 if !a.flags.encrypted {
2121 return errors.New("unable to lock unencrypted address")
2122 }
2123 zero(a.privKeyCT)
2124 a.privKeyCT = nil
2125 return nil
2126 }
2127 2128 // unlock decrypts and stores a pointer to an address's private key, failing if the address is not encrypted, or the
2129 // provided key is incorrect.
2130 //
2131 // The returned clear text private key will always be a copy that may be safely used by the caller without worrying
2132 // about it being zeroed during an address lock.
2133 func (a *btcAddress) unlock(key []byte) (privKeyCT []byte, e error) {
2134 if !a.flags.encrypted {
2135 return nil, errors.New("unable to unlock unencrypted address")
2136 }
2137 // Decrypt private key with AES key.
2138 aesBlockDecryptor, e := aes.NewCipher(key)
2139 if e != nil {
2140 return nil, e
2141 }
2142 aesDecryptor := cipher.NewCFBDecrypter(aesBlockDecryptor, a.initVector[:])
2143 privkey := make([]byte, 32)
2144 aesDecryptor.XORKeyStream(privkey, a.privKey[:])
2145 // If secret is already saved, simply compare the bytes.
2146 if len(a.privKeyCT) == 32 {
2147 if !bytes.Equal(a.privKeyCT, privkey) {
2148 return nil, ErrWrongPassphrase
2149 }
2150 privKeyCT := make([]byte, 32)
2151 copy(privKeyCT, a.privKeyCT)
2152 return privKeyCT, nil
2153 }
2154 x, y := ec.S256().ScalarBaseMult(privkey)
2155 if x.Cmp(a.pubKey.X) != 0 || y.Cmp(a.pubKey.Y) != 0 {
2156 return nil, ErrWrongPassphrase
2157 }
2158 privkeyCopy := make([]byte, 32)
2159 copy(privkeyCopy, privkey)
2160 a.privKeyCT = privkey
2161 return privkeyCopy, nil
2162 }
2163 2164 // changeEncryptionKey re-encrypts the private keys for an address with a new AES encryption key. oldkey must be the old
2165 // AES encryption key and is used to decrypt the private key.
2166 func (a *btcAddress) changeEncryptionKey(oldkey, newkey []byte) (e error) {
2167 // Address must have a private key and be encrypted to continue.
2168 if !a.flags.hasPrivKey {
2169 return errors.New("no private key")
2170 }
2171 if !a.flags.encrypted {
2172 return errors.New("address is not encrypted")
2173 }
2174 privKeyCT, e := a.unlock(oldkey)
2175 if e != nil {
2176 return e
2177 }
2178 aesBlockEncrypter, e := aes.NewCipher(newkey)
2179 if e != nil {
2180 return e
2181 }
2182 newIV := make([]byte, len(a.initVector))
2183 if _, e = rand.Read(newIV); E.Chk(e) {
2184 return e
2185 }
2186 copy(a.initVector[:], newIV)
2187 aesEncrypter := cipher.NewCFBEncrypter(aesBlockEncrypter, a.initVector[:])
2188 aesEncrypter.XORKeyStream(a.privKey[:], privKeyCT)
2189 return nil
2190 }
2191 2192 // Address returns the pub key address, implementing AddressInfo.
2193 func (a *btcAddress) Address() btcaddr.Address {
2194 return a.address
2195 }
2196 2197 // AddrHash returns the pub key hash, implementing WalletAddress.
2198 func (a *btcAddress) AddrHash() string {
2199 return string(a.address.ScriptAddress())
2200 }
2201 2202 // FirstBlock returns the first block the address is seen in, implementing AddressInfo.
2203 func (a *btcAddress) FirstBlock() int32 {
2204 return a.firstBlock
2205 }
2206 2207 // Imported returns the pub if the address was imported, or a chained address, implementing AddressInfo.
2208 func (a *btcAddress) Imported() bool {
2209 return a.chainIndex == importedKeyChainIdx
2210 }
2211 2212 // Change returns true if the address was created as a change address, implementing AddressInfo.
2213 func (a *btcAddress) Change() bool {
2214 return a.flags.change
2215 }
2216 2217 // Compressed returns true if the address backing key is compressed, implementing AddressInfo.
2218 func (a *btcAddress) Compressed() bool {
2219 return a.flags.compressed
2220 }
2221 2222 // SyncStatus returns a SyncStatus type for how the address is currently synced. For an Unsynced type, the value is the
2223 // recorded first seen block height of the address.
2224 func (a *btcAddress) SyncStatus() SyncStatus {
2225 switch {
2226 case a.flags.unsynced && !a.flags.partialSync:
2227 return Unsynced(a.firstBlock)
2228 case a.flags.unsynced && a.flags.partialSync:
2229 return PartialSync(a.partialSyncHeight)
2230 default:
2231 return FullSync{}
2232 }
2233 }
2234 2235 // PubKey returns the hex encoded pubkey for the address. Implementing PubKeyAddress.
2236 func (a *btcAddress) PubKey() *ec.PublicKey {
2237 return a.pubKey
2238 }
2239 func (a *btcAddress) pubKeyBytes() []byte {
2240 if a.Compressed() {
2241 return a.pubKey.SerializeCompressed()
2242 }
2243 return a.pubKey.SerializeUncompressed()
2244 }
2245 2246 // ExportPubKey returns the public key associated with the address serialised as a hex encoded string. Implements
2247 // PubKeyAddress
2248 func (a *btcAddress) ExportPubKey() string {
2249 return hex.EncodeToString(a.pubKeyBytes())
2250 }
2251 2252 // PrivKey implements PubKeyAddress by returning the private key, or an error if the key store is locked, watching only
2253 // or the private key is missing.
2254 func (a *btcAddress) PrivKey() (*ec.PrivateKey, error) {
2255 if a.store.flags.watchingOnly {
2256 return nil, ErrWatchingOnly
2257 }
2258 if !a.flags.hasPrivKey {
2259 return nil, errors.New("no private key for address")
2260 }
2261 // Key store must be unlocked to decrypt the private key.
2262 if a.store.isLocked() {
2263 return nil, ErrLocked
2264 }
2265 // Unlock address with key store secret. unlock returns a copy of the clear text private key, and may be used safely
2266 // even during an address lock.
2267 privKeyCT, e := a.unlock(a.store.secret)
2268 if e != nil {
2269 return nil, e
2270 }
2271 return &ec.PrivateKey{
2272 PublicKey: *a.pubKey.ToECDSA(),
2273 D: new(big.Int).SetBytes(privKeyCT),
2274 }, nil
2275 }
2276 2277 // ExportPrivKey exports the private key as a WIF for encoding as a string in the Wallet Import Format.
2278 func (a *btcAddress) ExportPrivKey() (*util.WIF, error) {
2279 pk, e := a.PrivKey()
2280 if e != nil {
2281 return nil, e
2282 }
2283 // NewWIF only errors if the network is nil. In this case, panic, as our program's assumptions are so broken that
2284 // this needs to be caught immediately, and a stack trace here is more useful than elsewhere.
2285 wif, e := util.NewWIF(
2286 pk, a.store.netParams(),
2287 a.Compressed(),
2288 )
2289 if e != nil {
2290 panic(e)
2291 }
2292 return wif, nil
2293 }
2294 2295 // watchingCopy creates a copy of an address without a private key. This is used to fill a watching a key store with
2296 // addresses from a normal key store.
2297 func (a *btcAddress) watchingCopy(s *Store) walletAddress {
2298 return &btcAddress{
2299 store: s,
2300 address: a.address,
2301 flags: addrFlags{
2302 hasPrivKey: false,
2303 hasPubKey: true,
2304 encrypted: false,
2305 createPrivKeyNextUnlock: false,
2306 compressed: a.flags.compressed,
2307 change: a.flags.change,
2308 unsynced: a.flags.unsynced,
2309 },
2310 chaincode: a.chaincode,
2311 chainIndex: a.chainIndex,
2312 chainDepth: a.chainDepth,
2313 pubKey: a.pubKey,
2314 firstSeen: a.firstSeen,
2315 lastSeen: a.lastSeen,
2316 firstBlock: a.firstBlock,
2317 partialSyncHeight: a.partialSyncHeight,
2318 }
2319 }
2320 2321 // setSyncStatus sets the address flags and possibly the partial sync height depending on the type of s.
2322 func (a *btcAddress) setSyncStatus(s SyncStatus) {
2323 switch e := s.(type) {
2324 case Unsynced:
2325 a.flags.unsynced = true
2326 a.flags.partialSync = false
2327 a.partialSyncHeight = 0
2328 case PartialSync:
2329 a.flags.unsynced = true
2330 a.flags.partialSync = true
2331 a.partialSyncHeight = int32(e)
2332 case FullSync:
2333 a.flags.unsynced = false
2334 a.flags.partialSync = false
2335 a.partialSyncHeight = 0
2336 }
2337 }
2338 2339 // note that there is no encrypted bit here since if we had a script encrypted and then used it on the blockchain this
2340 // provides a simple known plaintext in the key store file.
2341 //
2342 // It was determined that the script in a p2sh transaction is not a secret and any sane situation would also require a
2343 // signature (which does have a secret).
2344 type scriptFlags struct {
2345 hasScript bool
2346 change bool
2347 unsynced bool
2348 partialSync bool
2349 }
2350 2351 // ReadFrom implements the io.ReaderFrom interface by reading from r into sf.
2352 func (sf *scriptFlags) ReadFrom(r io.Reader) (int64, error) {
2353 var b [8]byte
2354 n, e := io.ReadFull(r, b[:])
2355 if e != nil {
2356 return int64(n), e
2357 }
2358 // We match bits from addrFlags for similar fields. hence hasScript uses the same bit as hasPubKey and the change
2359 // bit is the same for both.
2360 sf.hasScript = b[0]&(1<<1) != 0
2361 sf.change = b[0]&(1<<5) != 0
2362 sf.unsynced = b[0]&(1<<6) != 0
2363 sf.partialSync = b[0]&(1<<7) != 0
2364 return int64(n), nil
2365 }
2366 2367 // WriteTo implements the io.WriteTo interface by writing sf into w.
2368 func (sf *scriptFlags) WriteTo(w io.Writer) (int64, error) {
2369 var b [8]byte
2370 if sf.hasScript {
2371 b[0] |= 1 << 1
2372 }
2373 if sf.change {
2374 b[0] |= 1 << 5
2375 }
2376 if sf.unsynced {
2377 b[0] |= 1 << 6
2378 }
2379 if sf.partialSync {
2380 b[0] |= 1 << 7
2381 }
2382 n, e := w.Write(b[:])
2383 return int64(n), e
2384 }
2385 2386 // p2SHScript represents the variable length script entry in a key store.
2387 type p2SHScript []byte
2388 2389 // ReadFrom implements the ReaderFrom interface by reading the P2SH script from r in the format <4 bytes little endian
2390 // length><script bytes>
2391 func (a *p2SHScript) ReadFrom(r io.Reader) (n int64, e error) {
2392 // read length
2393 var lenBytes [4]byte
2394 read, e := io.ReadFull(r, lenBytes[:])
2395 n += int64(read)
2396 if e != nil {
2397 return n, e
2398 }
2399 length := binary.LittleEndian.Uint32(lenBytes[:])
2400 script := make([]byte, length)
2401 read, e = io.ReadFull(r, script)
2402 n += int64(read)
2403 if e != nil {
2404 return n, e
2405 }
2406 *a = script
2407 return n, nil
2408 }
2409 2410 // WriteTo implements the WriterTo interface by writing the P2SH script to w in the format <4 bytes little endian
2411 // length><script bytes>
2412 func (a *p2SHScript) WriteTo(w io.Writer) (n int64, e error) {
2413 // Prepare and write 32-bit little-endian length header
2414 var lenBytes [4]byte
2415 binary.LittleEndian.PutUint32(lenBytes[:], uint32(len(*a)))
2416 written, e := w.Write(lenBytes[:])
2417 n += int64(written)
2418 if e != nil {
2419 return n, e
2420 }
2421 // Now write the bytes themselves.
2422 written, e = w.Write(*a)
2423 return n + int64(written), e
2424 }
2425 2426 type scriptAddress struct {
2427 store *Store
2428 address btcaddr.Address
2429 class txscript.ScriptClass
2430 addresses []btcaddr.Address
2431 reqSigs int
2432 flags scriptFlags
2433 script p2SHScript // variable length
2434 firstSeen int64
2435 lastSeen int64
2436 firstBlock int32
2437 partialSyncHeight int32
2438 }
2439 2440 // ScriptAddress is an interface representing a Pay-to-Script-Hash style of bitcoind address.
2441 type ScriptAddress interface {
2442 WalletAddress
2443 // Script Returns the script associated with the address.
2444 Script() []byte
2445 // ScriptClass Returns the class of the script associated with the address.
2446 ScriptClass() txscript.ScriptClass
2447 // Addresses Returns the addresses that are required to sign transactions from the script address.
2448 Addresses() []btcaddr.Address
2449 // RequiredSigs Returns the number of signatures required by the script address.
2450 RequiredSigs() int
2451 }
2452 2453 // newScriptAddress initializes and returns a new P2SH address. iv must be 16 bytes, or nil (in which case it is
2454 // randomly generated).
2455 func newScriptAddress(s *Store, script []byte, bs *BlockStamp) (addr *scriptAddress, e error) {
2456 class, addresses, reqSigs, e := txscript.ExtractPkScriptAddrs(script, s.netParams())
2457 if e != nil {
2458 return nil, e
2459 }
2460 scriptHash := btcaddr.Hash160(script)
2461 var a *btcaddr.ScriptHash
2462 a, e = btcaddr.NewScriptHashFromHash(scriptHash, s.netParams())
2463 if e != nil {
2464 return nil, e
2465 }
2466 addr = &scriptAddress{
2467 store: s,
2468 address: a,
2469 addresses: addresses,
2470 class: class,
2471 reqSigs: reqSigs,
2472 flags: scriptFlags{
2473 hasScript: true,
2474 change: false,
2475 },
2476 script: script,
2477 firstSeen: time.Now().Unix(),
2478 firstBlock: bs.Height,
2479 }
2480 return addr, nil
2481 }
2482 2483 // ReadFrom reads an script address from an io.Reader.
2484 func (sa *scriptAddress) ReadFrom(r io.Reader) (n int64, e error) {
2485 var read int64
2486 // Checksums
2487 var chkScriptHash uint32
2488 var chkScript uint32
2489 var scriptHash [ripemd160.Size]byte
2490 // Read serialized key store into addr fields and checksums.
2491 datas := []interface{}{
2492 &scriptHash,
2493 &chkScriptHash,
2494 make([]byte, 4), // ksVersion
2495 &sa.flags,
2496 &sa.script,
2497 &chkScript,
2498 &sa.firstSeen,
2499 &sa.lastSeen,
2500 &sa.firstBlock,
2501 &sa.partialSyncHeight,
2502 }
2503 for _, data := range datas {
2504 if rf, ok := data.(io.ReaderFrom); ok {
2505 read, e = rf.ReadFrom(r)
2506 } else {
2507 read, e = binaryRead(r, binary.LittleEndian, data)
2508 }
2509 if e != nil {
2510 return n + read, e
2511 }
2512 n += read
2513 }
2514 // Verify checksums, correct errors where possible.
2515 checks := []struct {
2516 data []byte
2517 chk uint32
2518 }{
2519 {scriptHash[:], chkScriptHash},
2520 {sa.script, chkScript},
2521 }
2522 for i := range checks {
2523 if e = verifyAndFix(checks[i].data, checks[i].chk); E.Chk(e) {
2524 return n, e
2525 }
2526 }
2527 address, e := btcaddr.NewScriptHashFromHash(
2528 scriptHash[:],
2529 sa.store.netParams(),
2530 )
2531 if e != nil {
2532 return n, e
2533 }
2534 sa.address = address
2535 if !sa.flags.hasScript {
2536 return n, errors.New("read in an addresss with no script")
2537 }
2538 class, addresses, reqSigs, err :=
2539 txscript.ExtractPkScriptAddrs(sa.script, sa.store.netParams())
2540 if e != nil {
2541 return n, err
2542 }
2543 sa.class = class
2544 sa.addresses = addresses
2545 sa.reqSigs = reqSigs
2546 return n, nil
2547 }
2548 2549 // WriteTo implements io.WriterTo by writing the scriptAddress to w.
2550 func (sa *scriptAddress) WriteTo(w io.Writer) (n int64, e error) {
2551 var written int64
2552 hash := sa.address.ScriptAddress()
2553 datas := []interface{}{
2554 &hash,
2555 walletHash(hash),
2556 make([]byte, 4), // ksVersion
2557 &sa.flags,
2558 &sa.script,
2559 walletHash(sa.script),
2560 &sa.firstSeen,
2561 &sa.lastSeen,
2562 &sa.firstBlock,
2563 &sa.partialSyncHeight,
2564 }
2565 for _, data := range datas {
2566 if wt, ok := data.(io.WriterTo); ok {
2567 written, e = wt.WriteTo(w)
2568 } else {
2569 written, e = binaryWrite(w, binary.LittleEndian, data)
2570 }
2571 if e != nil {
2572 return n + written, e
2573 }
2574 n += written
2575 }
2576 return n, nil
2577 }
2578 2579 // Address returns a util.ScriptHash for a btcAddress.
2580 func (sa *scriptAddress) Address() btcaddr.Address {
2581 return sa.address
2582 }
2583 2584 // AddrHash returns the script hash, implementing AddressInfo.
2585 func (sa *scriptAddress) AddrHash() string {
2586 return string(sa.address.ScriptAddress())
2587 }
2588 2589 // FirstBlock returns the first blockheight the address is known at.
2590 func (sa *scriptAddress) FirstBlock() int32 {
2591 return sa.firstBlock
2592 }
2593 2594 // Imported currently always returns true since script addresses are always imported addressed and not part of any
2595 // chain.
2596 func (sa *scriptAddress) Imported() bool {
2597 return true
2598 }
2599 2600 // Change returns true if the address was created as a change address.
2601 func (sa *scriptAddress) Change() bool {
2602 return sa.flags.change
2603 }
2604 2605 // Compressed returns false since script addresses are never compressed. Implements WalletAddress.
2606 func (sa *scriptAddress) Compressed() bool {
2607 return false
2608 }
2609 2610 // Script returns the script that is represented by the address. It should not be modified.
2611 func (sa *scriptAddress) Script() []byte {
2612 return sa.script
2613 }
2614 2615 // Addresses returns the list of addresses that must sign the script.
2616 func (sa *scriptAddress) Addresses() []btcaddr.Address {
2617 return sa.addresses
2618 }
2619 2620 // ScriptClass returns the type of script the address is.
2621 func (sa *scriptAddress) ScriptClass() txscript.ScriptClass {
2622 return sa.class
2623 }
2624 2625 // RequiredSigs returns the number of signatures required by the script.
2626 func (sa *scriptAddress) RequiredSigs() int {
2627 return sa.reqSigs
2628 }
2629 2630 // SyncStatus returns a SyncStatus type for how the address is currently synced. For an Unsynced type, the value is the
2631 // recorded first seen block height of the address.
2632 //
2633 // Implements WalletAddress.
2634 func (sa *scriptAddress) SyncStatus() SyncStatus {
2635 switch {
2636 case sa.flags.unsynced && !sa.flags.partialSync:
2637 return Unsynced(sa.firstBlock)
2638 case sa.flags.unsynced && sa.flags.partialSync:
2639 return PartialSync(sa.partialSyncHeight)
2640 default:
2641 return FullSync{}
2642 }
2643 }
2644 2645 // setSyncStatus sets the address flags and possibly the partial sync height depending on the type of s.
2646 func (sa *scriptAddress) setSyncStatus(s SyncStatus) {
2647 switch e := s.(type) {
2648 case Unsynced:
2649 sa.flags.unsynced = true
2650 sa.flags.partialSync = false
2651 sa.partialSyncHeight = 0
2652 case PartialSync:
2653 sa.flags.unsynced = true
2654 sa.flags.partialSync = true
2655 sa.partialSyncHeight = int32(e)
2656 case FullSync:
2657 sa.flags.unsynced = false
2658 sa.flags.partialSync = false
2659 sa.partialSyncHeight = 0
2660 }
2661 }
2662 2663 // watchingCopy creates a copy of an address without a private key.
2664 //
2665 // This is used to fill a watching key store with addresses from a normal key store.
2666 func (sa *scriptAddress) watchingCopy(s *Store) walletAddress {
2667 return &scriptAddress{
2668 store: s,
2669 address: sa.address,
2670 addresses: sa.addresses,
2671 class: sa.class,
2672 reqSigs: sa.reqSigs,
2673 flags: scriptFlags{
2674 change: sa.flags.change,
2675 unsynced: sa.flags.unsynced,
2676 },
2677 script: sa.script,
2678 firstSeen: sa.firstSeen,
2679 lastSeen: sa.lastSeen,
2680 firstBlock: sa.firstBlock,
2681 partialSyncHeight: sa.partialSyncHeight,
2682 }
2683 }
2684 func walletHash(b []byte) uint32 {
2685 sum := chainhash.DoubleHashB(b)
2686 return binary.LittleEndian.Uint32(sum)
2687 }
2688 2689 // TODO(jrick) add error correction.
2690 func verifyAndFix(b []byte, chk uint32) (e error) {
2691 if walletHash(b) != chk {
2692 return ErrChecksumMismatch
2693 }
2694 return nil
2695 }
2696 2697 type kdfParameters struct {
2698 mem uint64
2699 nIter uint32
2700 salt [32]byte
2701 }
2702 2703 // computeKdfParameters returns best guess parameters to the memory-hard key derivation function to make the computation
2704 // last targetSec seconds, while using no more than maxMem bytes of memory.
2705 func computeKdfParameters(targetSec float64, maxMem uint64) (params *kdfParameters, e error) {
2706 params = &kdfParameters{}
2707 if _, e = rand.Read(params.salt[:]); E.Chk(e) {
2708 return nil, e
2709 }
2710 testKey := []byte("This is an example key to test KDF iteration speed")
2711 memoryReqtBytes := uint64(1024)
2712 approxSec := float64(0)
2713 for approxSec <= targetSec/4 && memoryReqtBytes < maxMem {
2714 memoryReqtBytes *= 2
2715 before := time.Now()
2716 _ = keyOneIter(testKey, params.salt[:], memoryReqtBytes)
2717 approxSec = time.Since(before).Seconds()
2718 }
2719 allItersSec := float64(0)
2720 nIter := uint32(1)
2721 for allItersSec < 0.02 { // This is a magic number straight from armory's source.
2722 nIter *= 2
2723 before := time.Now()
2724 for i := uint32(0); i < nIter; i++ {
2725 _ = keyOneIter(testKey, params.salt[:], memoryReqtBytes)
2726 }
2727 allItersSec = time.Since(before).Seconds()
2728 }
2729 params.mem = memoryReqtBytes
2730 params.nIter = nIter
2731 return params, nil
2732 }
2733 func (params *kdfParameters) WriteTo(w io.Writer) (n int64, e error) {
2734 var written int64
2735 memBytes := make([]byte, 8)
2736 nIterBytes := make([]byte, 4)
2737 binary.LittleEndian.PutUint64(memBytes, params.mem)
2738 binary.LittleEndian.PutUint32(nIterBytes, params.nIter)
2739 chkedBytes := append(memBytes, nIterBytes...)
2740 chkedBytes = append(chkedBytes, params.salt[:]...)
2741 datas := []interface{}{
2742 ¶ms.mem,
2743 ¶ms.nIter,
2744 ¶ms.salt,
2745 walletHash(chkedBytes),
2746 make([]byte, 256-(binary.Size(params)+4)), // padding
2747 }
2748 for _, data := range datas {
2749 if written, e = binaryWrite(w, binary.LittleEndian, data); E.Chk(e) {
2750 return n + written, e
2751 }
2752 n += written
2753 }
2754 return n, nil
2755 }
2756 func (params *kdfParameters) ReadFrom(r io.Reader) (n int64, e error) {
2757 var read int64
2758 // These must be read in but are not saved directly to chaincfg.
2759 chkedBytes := make([]byte, 44)
2760 var chk uint32
2761 padding := make([]byte, 256-(binary.Size(params)+4))
2762 datas := []interface{}{
2763 chkedBytes,
2764 &chk,
2765 padding,
2766 }
2767 for _, data := range datas {
2768 if read, e = binaryRead(r, binary.LittleEndian, data); E.Chk(e) {
2769 return n + read, e
2770 }
2771 n += read
2772 }
2773 // Verify checksum
2774 if e = verifyAndFix(chkedBytes, chk); E.Chk(e) {
2775 return n, e
2776 }
2777 // Read netparams
2778 buf := bytes.NewBuffer(chkedBytes)
2779 datas = []interface{}{
2780 ¶ms.mem,
2781 ¶ms.nIter,
2782 ¶ms.salt,
2783 }
2784 for _, data := range datas {
2785 if e = binary.Read(buf, binary.LittleEndian, data); E.Chk(e) {
2786 return n, e
2787 }
2788 }
2789 return n, nil
2790 }
2791 2792 type addrEntry struct {
2793 pubKeyHash160 [ripemd160.Size]byte
2794 addr btcAddress
2795 }
2796 2797 func (ae *addrEntry) WriteTo(w io.Writer) (n int64, e error) {
2798 var written int64
2799 // Write header
2800 if written, e = binaryWrite(w, binary.LittleEndian, addrHeader); E.Chk(e) {
2801 return n + written, e
2802 }
2803 n += written
2804 // Write hash
2805 if written, e = binaryWrite(w, binary.LittleEndian, &ae.pubKeyHash160); E.Chk(e) {
2806 return n + written, e
2807 }
2808 n += written
2809 // Write btcAddress
2810 written, e = ae.addr.WriteTo(w)
2811 n += written
2812 return n, e
2813 }
2814 func (ae *addrEntry) ReadFrom(r io.Reader) (n int64, e error) {
2815 var read int64
2816 if read, e = binaryRead(r, binary.LittleEndian, &ae.pubKeyHash160); E.Chk(e) {
2817 return n + read, e
2818 }
2819 n += read
2820 read, e = ae.addr.ReadFrom(r)
2821 return n + read, e
2822 }
2823 2824 // scriptEntry is the entry type for a P2SH script.
2825 type scriptEntry struct {
2826 scriptHash160 [ripemd160.Size]byte
2827 script scriptAddress
2828 }
2829 2830 // WriteTo implements io.WriterTo by writing the entry to w.
2831 func (se *scriptEntry) WriteTo(w io.Writer) (n int64, e error) {
2832 var written int64
2833 // Write header
2834 if written, e = binaryWrite(w, binary.LittleEndian, scriptHeader); E.Chk(e) {
2835 return n + written, e
2836 }
2837 n += written
2838 // Write hash
2839 if written, e = binaryWrite(w, binary.LittleEndian, &se.scriptHash160); E.Chk(e) {
2840 return n + written, e
2841 }
2842 n += written
2843 // Write btcAddress
2844 written, e = se.script.WriteTo(w)
2845 n += written
2846 return n, e
2847 }
2848 2849 // ReadFrom implements io.ReaderFrom by reading the entry from e.
2850 func (se *scriptEntry) ReadFrom(r io.Reader) (n int64, e error) {
2851 var read int64
2852 if read, e = binaryRead(r, binary.LittleEndian, &se.scriptHash160); E.Chk(e) {
2853 return n + read, e
2854 }
2855 n += read
2856 read, e = se.script.ReadFrom(r)
2857 return n + read, e
2858 }
2859 2860 // BlockStamp defines a block (by height and a unique hash) and is used to mark a point in the blockchain that a key
2861 // store element is synced to.
2862 type BlockStamp struct {
2863 Hash *chainhash.Hash
2864 Height int32
2865 }
2866