github.com/decred/dcrlnd@v0.7.6/amp/child.go (about) 1 package amp 2 3 import ( 4 "crypto/sha256" 5 "encoding/binary" 6 "fmt" 7 8 "github.com/decred/dcrlnd/lntypes" 9 ) 10 11 // Share represents an n-of-n sharing of a secret 32-byte value. The secret can 12 // be recovered by XORing all n shares together. 13 type Share [32]byte 14 15 // Xor stores the byte-wise xor of shares x and y in z. 16 func (z *Share) Xor(x, y *Share) { 17 for i := range z { 18 z[i] = x[i] ^ y[i] 19 } 20 } 21 22 // ChildDesc contains the information necessary to derive a child hash/preimage 23 // pair that is attached to a particular HTLC. This information will be known by 24 // both the sender and receiver in the process of fulfilling an AMP payment. 25 type ChildDesc struct { 26 // Share is one of n shares of the root seed. Once all n shares are 27 // known to the receiver, the Share will also provide entropy to the 28 // derivation of child hash and preimage. 29 Share Share 30 31 // Index is 32-bit value that can be used to derive up to 2^32 child 32 // hashes and preimages from a single Share. This allows the payment 33 // hashes sent over the network to be refreshed without needing to 34 // modify the Share. 35 Index uint32 36 } 37 38 // Child is a payment hash and preimage pair derived from the root seed. In 39 // addition to the derived values, a Child carries all information required in 40 // the derivation apart from the root seed (unless n=1). 41 type Child struct { 42 // ChildDesc contains the data required to derive the child hash and 43 // preimage below. 44 ChildDesc 45 46 // Preimage is the child payment preimage that can be used to settle the 47 // HTLC carrying Hash. 48 Preimage lntypes.Preimage 49 50 // Hash is the child payment hash that to be carried by the HTLC. 51 Hash lntypes.Hash 52 } 53 54 // String returns a human-readable description of a Child. 55 func (c *Child) String() string { 56 return fmt.Sprintf("share=%x, index=%d -> preimage=%v, hash=%v", 57 c.Share, c.Index, c.Preimage, c.Hash) 58 } 59 60 // DeriveChild computes the child preimage and child hash for a given (root, 61 // share, index) tuple. The derivation is defined as: 62 // 63 // child_preimage = SHA256(root || share || be32(index)), 64 // child_hash = SHA256(child_preimage). 65 func DeriveChild(root Share, desc ChildDesc) *Child { 66 var ( 67 indexBytes [4]byte 68 preimage lntypes.Preimage 69 hash lntypes.Hash 70 ) 71 72 // Serialize the child index in big-endian order. 73 binary.BigEndian.PutUint32(indexBytes[:], desc.Index) 74 75 // Compute child_preimage as SHA256(root || share || child_index). 76 h := sha256.New() 77 _, _ = h.Write(root[:]) 78 _, _ = h.Write(desc.Share[:]) 79 _, _ = h.Write(indexBytes[:]) 80 copy(preimage[:], h.Sum(nil)) 81 82 // Compute child_hash as SHA256(child_preimage). 83 h = sha256.New() 84 _, _ = h.Write(preimage[:]) 85 copy(hash[:], h.Sum(nil)) 86 87 return &Child{ 88 ChildDesc: desc, 89 Preimage: preimage, 90 Hash: hash, 91 } 92 }