You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.7 KiB
92 lines
2.7 KiB
package amp |
|
|
|
import ( |
|
"crypto/sha256" |
|
"encoding/binary" |
|
"fmt" |
|
|
|
"github.com/lightningnetwork/lnd/lntypes" |
|
) |
|
|
|
// Share represents an n-of-n sharing of a secret 32-byte value. The secret can |
|
// be recovered by XORing all n shares together. |
|
type Share [32]byte |
|
|
|
// Xor stores the byte-wise xor of shares x and y in z. |
|
func (z *Share) Xor(x, y *Share) { |
|
for i := range z { |
|
z[i] = x[i] ^ y[i] |
|
} |
|
} |
|
|
|
// ChildDesc contains the information necessary to derive a child hash/preimage |
|
// pair that is attached to a particular HTLC. This information will be known by |
|
// both the sender and receiver in the process of fulfilling an AMP payment. |
|
type ChildDesc struct { |
|
// Share is one of n shares of the root seed. Once all n shares are |
|
// known to the receiver, the Share will also provide entropy to the |
|
// derivation of child hash and preimage. |
|
Share Share |
|
|
|
// Index is 32-bit value that can be used to derive up to 2^32 child |
|
// hashes and preimages from a single Share. This allows the payment |
|
// hashes sent over the network to be refreshed without needing to |
|
// modify the Share. |
|
Index uint32 |
|
} |
|
|
|
// Child is a payment hash and preimage pair derived from the root seed. In |
|
// addition to the derived values, a Child carries all information required in |
|
// the derivation apart from the root seed (unless n=1). |
|
type Child struct { |
|
// ChildDesc contains the data required to derive the child hash and |
|
// preimage below. |
|
ChildDesc |
|
|
|
// Preimage is the child payment preimage that can be used to settle the |
|
// HTLC carrying Hash. |
|
Preimage lntypes.Preimage |
|
|
|
// Hash is the child payment hash that to be carried by the HTLC. |
|
Hash lntypes.Hash |
|
} |
|
|
|
// String returns a human-readable description of a Child. |
|
func (c *Child) String() string { |
|
return fmt.Sprintf("share=%x, index=%d -> preimage=%v, hash=%v", |
|
c.Share, c.Index, c.Preimage, c.Hash) |
|
} |
|
|
|
// DeriveChild computes the child preimage and child hash for a given (root, |
|
// share, index) tuple. The derivation is defined as: |
|
// |
|
// child_preimage = SHA256(root || share || be32(index)), |
|
// child_hash = SHA256(child_preimage). |
|
func DeriveChild(root Share, desc ChildDesc) *Child { |
|
var ( |
|
indexBytes [4]byte |
|
preimage lntypes.Preimage |
|
hash lntypes.Hash |
|
) |
|
|
|
// Serialize the child index in big-endian order. |
|
binary.BigEndian.PutUint32(indexBytes[:], desc.Index) |
|
|
|
// Compute child_preimage as SHA256(root || share || child_index). |
|
h := sha256.New() |
|
_, _ = h.Write(root[:]) |
|
_, _ = h.Write(desc.Share[:]) |
|
_, _ = h.Write(indexBytes[:]) |
|
copy(preimage[:], h.Sum(nil)) |
|
|
|
// Compute child_hash as SHA256(child_preimage). |
|
h = sha256.New() |
|
_, _ = h.Write(preimage[:]) |
|
copy(hash[:], h.Sum(nil)) |
|
|
|
return &Child{ |
|
ChildDesc: desc, |
|
Preimage: preimage, |
|
Hash: hash, |
|
} |
|
}
|
|
|