Files
crypto/signatures/bbs/public_key.go
T

78 lines
1.7 KiB
Go
Raw Normal View History

2025-10-09 15:10:39 -04:00
//
// Copyright Coinbase, Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
package bbs
import (
"errors"
"fmt"
"github.com/sonr-io/crypto/core/curves"
2025-10-09 15:10:39 -04:00
)
// PublicKey is a BBS+ verification key
type PublicKey struct {
value curves.PairingPoint
}
func (pk *PublicKey) Init(curve *curves.PairingCurve) *PublicKey {
pk.value = curve.NewG2IdentityPoint()
return pk
}
func (pk PublicKey) MarshalBinary() ([]byte, error) {
return pk.value.ToAffineCompressed(), nil
}
func (pk *PublicKey) UnmarshalBinary(in []byte) error {
value, err := pk.value.FromAffineCompressed(in)
if err != nil {
return err
}
var ok bool
pk.value, ok = value.(curves.PairingPoint)
if !ok {
return errors.New("incorrect type conversion")
}
return nil
}
// Verify checks a signature where all messages are known to the verifier
func (pk PublicKey) Verify(
signature *Signature,
generators *MessageGenerators,
msgs []curves.Scalar,
) error {
if generators.length < len(msgs) {
return fmt.Errorf("not enough message generators")
}
if len(msgs) < 1 {
return fmt.Errorf("invalid messages")
}
// Identity Point will always return true which is not what we want
if pk.value.IsIdentity() {
return fmt.Errorf("invalid public key")
}
if signature.a.IsIdentity() {
return fmt.Errorf("invalid signature")
}
a, ok := pk.value.Generator().Mul(signature.e).Add(pk.value).(curves.PairingPoint)
if !ok {
return fmt.Errorf("not a valid point")
}
b, ok := computeB(signature.s, msgs, generators).Neg().(curves.PairingPoint)
if !ok {
return fmt.Errorf("not a valid point")
}
res := a.MultiPairing(signature.a, a, b, pk.value.Generator().(curves.PairingPoint))
if !res.IsOne() {
return fmt.Errorf("invalid result")
}
return nil
}