2021-01-16 01:51:51 +03:00
|
|
|
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
|
|
|
|
|
2021-01-16 01:52:00 +03:00
|
|
|
// 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]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-16 01:51:51 +03:00
|
|
|
// 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,
|
|
|
|
}
|
|
|
|
}
|