sonr/crypto/secret/key.go

108 lines
3.3 KiB
Go
Raw Normal View History

2024-07-05 22:20:13 -04:00
package secret
import (
"errors"
"fmt"
"github.com/onsonr/hway/crypto"
"github.com/onsonr/hway/crypto/accumulator"
"github.com/onsonr/hway/crypto/core/curves"
)
// PrimaryKey is the secret key for the BLS scheme
type PrimaryKey struct {
*accumulator.SecretKey
}
// Element is the element for the BLS scheme
type Element = accumulator.Element
// NewKey creates a new primary key
func NewKey(propertyKey string, pubKey crypto.PublicKey) (*PrimaryKey, error) {
// Concatenate the controller's public key and the property key
input := append(pubKey.Bytes(), []byte(propertyKey)...)
hash := []byte(input)
// Use the hash as the seed for the secret key
curve := curves.BLS12381(&curves.PointBls12381G1{})
key, err := new(accumulator.SecretKey).New(curve, hash[:])
if err != nil {
return nil, errors.Join(err, fmt.Errorf("failed to create secret key"))
}
return &PrimaryKey{SecretKey: key}, nil
}
// CreateAccumulator creates a new accumulator
func (s *PrimaryKey) CreateAccumulator(values ...string) (*accumulator.Accumulator, error) {
curve := curves.BLS12381(&curves.PointBls12381G1{})
acc, err := new(accumulator.Accumulator).New(curve)
if err != nil {
return nil, err
}
fin, _, err := acc.Update(s.SecretKey, convertValuesToElements(values), nil)
if err != nil {
return nil, err
}
return fin, nil
}
// CreateWitness creates a witness for the accumulator for a given value
func (s *PrimaryKey) CreateWitness(acc *accumulator.Accumulator, value string) (*accumulator.MembershipWitness, error) {
curve := curves.BLS12381(&curves.PointBls12381G1{})
element := curve.Scalar.Hash([]byte(value))
mw, err := new(accumulator.MembershipWitness).New(element, acc, s.SecretKey)
if err != nil {
return nil, err
}
return mw, nil
}
// ProveMembership proves that a value is a member of the accumulator
func (s *PrimaryKey) VerifyWitness(acc *accumulator.Accumulator, witness *accumulator.MembershipWitness) error {
return witness.Verify(s.PublicKey(), acc)
}
// PublicKey returns the public key for the secret key
func (s *PrimaryKey) PublicKey() *accumulator.PublicKey {
curve := curves.BLS12381(&curves.PointBls12381G1{})
pk, err := s.GetPublicKey(curve)
if err != nil {
panic(err)
}
return pk
}
// UpdateAccumulator updates the accumulator with new values
func (s *PrimaryKey) UpdateAccumulator(acc *accumulator.Accumulator, addValues, removeValues []string) (*accumulator.Accumulator, error) {
acc, _, err := acc.Update(s.SecretKey, convertValuesToElements(addValues), convertValuesToElements(removeValues))
if err != nil {
return nil, err
}
return acc, nil
}
// MarshalAccumulator takes a *accumulator.Accumulator and returns a byte slice
func MarshalAccumulator(acc *accumulator.Accumulator) ([]byte, error) {
return acc.MarshalBinary()
}
// UnmarshalAccumulator takes a byte slice and returns a *accumulator.Accumulator
func UnmarshalAccumulator(data []byte) (*accumulator.Accumulator, error) {
acc := new(accumulator.Accumulator)
err := acc.UnmarshalBinary(data)
if err != nil {
return nil, err
}
return acc, nil
}
func convertValuesToElements(values []string) []accumulator.Element {
curve := curves.BLS12381(&curves.PointBls12381G1{})
elements := []accumulator.Element{}
for _, value := range values {
element := curve.Scalar.Hash([]byte(value))
elements = append(elements, element)
}
return elements
}