Exemple #1
0
// Update updates balloon with the slice of events, producing the next snapshot.
// Run by the author on trusted input.
func (balloon *Balloon) Update(events []Event, current *Snapshot,
	sk []byte) (next *Snapshot, err error) {
	if len(events) == 0 {
		return nil, errors.New("you need to add at least one event")
	}
	if !util.Equal(current.Roots.History, balloon.history.Root()) ||
		!util.Equal(current.Roots.Treap, balloon.treap.Root()) {
		return nil, errors.New("provided snapshot is not current")
	}

	sort.Sort(ByKey(events))

	// attempt to add events
	treap := balloon.treap
	ht := balloon.history.Clone()
	for i := 0; i < len(events); i++ {
		// add the hash of the entire event to the history tree
		_, err = ht.Add(util.Hash(append(events[i].Key, events[i].Value...)))
		if err != nil {
			return
		}

		// add to the treap the hash of the key pointing to the index (version) of the
		// hash of the event in the history tree
		treap, err = treap.Add(util.Hash(events[i].Key), util.Itob(ht.LatestVersion()))
		if err != nil {
			return
		}
	}

	// attempt to create next snapshot
	next = new(Snapshot)
	next.Index = current.Index + 1
	next.Roots.History = ht.Root()
	next.Roots.Treap = treap.Root()
	next.Roots.Version = ht.LatestVersion()
	next.Previous = current.Signature
	signature, err := util.Sign(balloon.sk,
		append(append([]byte("snapshot"), next.Roots.History...), append(next.Roots.Treap, next.Previous...)...))
	if err != nil {
		panic(err)
	}
	next.Signature = signature

	// all is OK, save result
	err = balloon.Storage.Store(events, *next)
	if err != nil {
		return nil, err
	}
	balloon.latestsnapshot = *next
	if len(events) > 0 {
		balloon.latesteventkey = events[len(events)-1].Key
	}
	balloon.treap = treap
	balloon.history = ht

	return
}
Exemple #2
0
// Setup creates a new balloon based on the slice of events (may be empty or nil). Returns the
// first snapshot. Run by the author on trusted input.
func Setup(events []Event, sk, vk []byte, storage EventStorage) (balloon *Balloon, snap *Snapshot, err error) {
	balloon = NewBalloon(storage)
	balloon.sk = sk
	balloon.vk = vk

	// do same as update, allow events to be empty
	if len(events) > 0 {
		sort.Sort(ByKey(events))

		// add events
		for i := 0; i < len(events); i++ {
			// add the hash of the entire event to the history tree
			_, err = balloon.history.Add(util.Hash(append(events[i].Key, events[i].Value...)))
			if err != nil {
				return nil, nil, err
			}

			// add to the treap the hash of the key pointing to the index (version) of the
			// hash of the event in the history tree
			balloon.treap, err = balloon.treap.Add(util.Hash(events[i].Key),
				util.Itob(balloon.history.LatestVersion()))
			if err != nil {
				return nil, nil, err
			}
		}
	}

	// create first snapshot
	snap = new(Snapshot)
	snap.Index = 0
	snap.Roots.History = balloon.history.Root()
	snap.Roots.Treap = balloon.treap.Root()
	snap.Roots.Version = balloon.history.LatestVersion()
	snap.Previous = nil

	signature, err := util.Sign(balloon.sk,
		append(append([]byte("snapshot"), snap.Roots.History...), append(snap.Roots.Treap, snap.Previous...)...))
	if err != nil {
		panic(err)
	}
	snap.Signature = signature

	// actually store events
	err = balloon.Storage.Store(events, *snap)
	if err != nil {
		return nil, nil, err
	}
	balloon.latestsnapshot = *snap
	if len(events) > 0 {
		balloon.latesteventkey = events[len(events)-1].Key
	}

	return
}
Exemple #3
0
// Update creates the next snapshot from adding the provided events in the balloon
// fixed by the current snapshot. This function depends on that the provided prune proof has
// been successfully verified for the answer true.
// Run by the author on input that should have been verified before by using Verify.
func (proof *PruneProof) Update(events []Event, current *Snapshot,
	sk []byte) (next *Snapshot, err error) {

	sort.Sort(ByKey(events))

	// calculate balloon internal keys and values based on events
	startIndex := current.Roots.Version + 1
	values := make([][]byte, len(events))
	treapKeys := make([][]byte, len(events))
	treapValues := make([][]byte, len(events))
	for i := 0; i < len(events); i++ {
		values[i] = util.Hash(append(events[i].Key, events[i].Value...))
		treapKeys[i] = util.Hash(events[i].Key)
		treapValues[i] = util.Itob(startIndex + i)
	}

	// calculate updated commitment on the history tree
	c, version, err := proof.QueryProof.HistoryProof.Update(values)
	if err != nil {
		return nil, err
	}

	// calculate updated hash treap root
	root, err := proof.TreapProof.Update(treapKeys, treapValues)
	if err != nil {
		return nil, err
	}

	next = new(Snapshot)
	next.Index = current.Index + 1
	next.Roots.History = c
	next.Roots.Treap = root
	next.Roots.Version = version
	next.Previous = current.Signature
	signature, err := util.Sign(sk,
		append(append([]byte("snapshot"), next.Roots.History...),
			append(next.Roots.Treap, next.Previous...)...))
	if err != nil {
		panic(err)
	}
	next.Signature = signature

	return
}