shachain: complete shachain implementation

This commit is contained in:
Andrey Samokhvalov
2016-12-14 01:59:48 +03:00
committed by Olaoluwa Osuntokun
parent 3a647869b6
commit b40afeaa08
9 changed files with 1279 additions and 182 deletions

76
shachain/producer.go Normal file
View File

@@ -0,0 +1,76 @@
package shachain
import (
"github.com/roasbeef/btcd/chaincfg/chainhash"
)
// Producer is an interface which serves as an abstraction over data
// structure responsible for efficient generating the secrets by given index.
// The generation of secrets should be made in such way that secret store
// might efficiently store and retrieve the secrets.
type Producer interface {
// AtIndex produce secret by given index.
AtIndex(uint64) (*chainhash.Hash, error)
// ToBytes convert producer to the binary representation.
ToBytes() ([]byte, error)
}
// RevocationProducer implementation of Producer. This version of shachain
// slightly changed in terms of method naming. Initial concept might be found
// here:
// https://github.com/rustyrussell/ccan/blob/master/ccan/crypto/shachain/design.txt
type RevocationProducer struct {
// root is the element from which we may generate all hashes which
// corresponds to the index domain [281474976710655,0].
root *element
}
// A compile time check to ensure RevocationProducer implements the Producer
// interface.
var _ Producer = (*RevocationProducer)(nil)
// NewRevocationProducer create new instance of shachain producer.
func NewRevocationProducer(root *chainhash.Hash) *RevocationProducer {
return &RevocationProducer{
root: &element{
index: rootIndex,
hash: *root,
}}
}
// NewRevocationProducerFromBytes deserialize an instance of a RevocationProducer
// encoded in the passed byte slice, returning a fully initialize instance of a
// RevocationProducer.
func NewRevocationProducerFromBytes(data []byte) (*RevocationProducer, error) {
root, err := chainhash.NewHash(data)
if err != nil {
return nil, err
}
return &RevocationProducer{
root: &element{
index: rootIndex,
hash: *root,
},
}, nil
}
// AtIndex produce secret by given index.
// NOTE: Part of the Producer interface.
func (p *RevocationProducer) AtIndex(v uint64) (*chainhash.Hash, error) {
ind := newIndex(v)
element, err := p.root.derive(ind)
if err != nil {
return nil, err
}
return &element.hash, nil
}
// ToBytes convert producer to the binary representation.
// NOTE: Part of the Producer interface.
func (p *RevocationProducer) ToBytes() ([]byte, error) {
return p.root.hash.CloneBytes(), nil
}