package pijul
import (
"fmt"
"filippo.io/edwards25519"
)
// A State represents a set of changes. It is calculated from the hashes of
// the changes, using the Edwards 25519 curve.
type State struct {
p edwards25519.Point
}
func (s State) String() string {
return base32Encoding.EncodeToString(append(s.p.Bytes(), 1))
}
func StateFromBase32(b32 string) (State, error) {
b, err := base32Encoding.DecodeString(b32)
if err != nil {
return State{}, err
}
if len(b) != 33 {
return State{}, fmt.Errorf("expected 33 bytes, got %d", len(b))
}
if b[32] != 1 {
return State{}, fmt.Errorf("expected Ed25519 state, got type %d", b[32])
}
var p edwards25519.Point
_, err = p.SetBytes(b[:32])
if err != nil {
return State{}, err
}
return State{p}, nil
}
func mustStateFromBase32(b32 string) State {
s, err := StateFromBase32(b32)
if err != nil {
panic(err)
}
return s
}
// EmptyState is the State that represents the empty set.
var EmptyState = mustStateFromBase32("LBTGMZTGMZTGMZTGMZTGMZTGMZTGMZTGMZTGMZTGMZTGMZTGMZTAC")
func (s State) Add(h Hash) State {
var wideBytes [64]byte
copy(wideBytes[:], h[:])
var scalar edwards25519.Scalar
scalar.SetUniformBytes(wideBytes[:])
p := s.p
p.ScalarMult(&scalar, &p)
return State{p}
}