ceremonyclient/node/protobufs/keys.go
2023-09-03 18:47:09 -05:00

217 lines
4.9 KiB
Go

package protobufs
import (
"golang.org/x/crypto/sha3"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/zkp/schnorr"
"github.com/cloudflare/circl/sign/ed448"
"github.com/pkg/errors"
)
func (p *ProvingKeyAnnouncement) Verify() error {
if p.ProvingKeySignature == nil {
return errors.Wrap(errors.New("proving key signature nil"), "verify")
}
msg := append(
append([]byte{}, p.IdentityCommitment...),
p.PrekeyCommitment...,
)
switch k := p.ProvingKeySignature.(type) {
case *ProvingKeyAnnouncement_ProvingKeySignatureEd448:
return k.ProvingKeySignatureEd448.Verify(msg)
default:
return errors.Wrap(errors.New("unsupported signature type"), "verify")
}
}
func (p *ProvingKeyAnnouncement) PublicKey() []byte {
switch k := p.ProvingKeySignature.(type) {
case *ProvingKeyAnnouncement_ProvingKeySignatureEd448:
return k.ProvingKeySignatureEd448.PublicKey.KeyValue
default:
return nil
}
}
func (k *KeyBundleAnnouncement) Verify(
provingKey *ProvingKeyAnnouncement,
) error {
var curve *curves.Curve
if k.IdentityKey == nil {
return errors.Wrap(errors.New("identity key is nil"), "verify")
}
if k.IdentityKey.IdentityKeySignature == nil {
return errors.Wrap(errors.New("identity key signature is nil"), "verify")
}
if k.SignedPreKey == nil {
return errors.Wrap(errors.New("signed pre key is nil"), "verify")
}
if k.SignedPreKey.SignedPreKeySignature == nil {
return errors.Wrap(errors.New("signed pre key signature is nil"), "verify")
}
switch s := k.IdentityKey.IdentityKeySignature.(type) {
case *IdentityKey_PublicKeySignatureEd448:
err := s.PublicKeySignatureEd448.VerifyCrossSigned(
k.ProvingKeyBytes,
)
if err != nil {
return err
}
v := k.SignedPreKey.SignedPreKeySignature
spk := v.(*SignedPreKey_PublicKeySignatureEd448)
if spk == nil {
return errors.Wrap(errors.New("curve mismatch"), "verify")
}
err = spk.PublicKeySignatureEd448.VerifyCrossSigned(
k.ProvingKeyBytes,
)
if err != nil {
return err
}
curve = curves.ED448()
}
idkc, err := curve.NewScalar().SetBytes(k.IdentityKey.Challenge)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "challenge invalid"),
"verify",
)
}
idks, err := curve.NewScalar().SetBytes(k.IdentityKey.Response)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "response invalid"),
"verify",
)
}
idkStatement, err := curve.NewGeneratorPoint().FromAffineCompressed(
k.IdentityKey.Statement,
)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "statement invalid"),
"verify",
)
}
spkc, err := curve.NewScalar().SetBytes(k.SignedPreKey.Challenge)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "challenge invalid"),
"verify",
)
}
spks, err := curve.NewScalar().SetBytes(k.SignedPreKey.Response)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "response invalid"),
"verify",
)
}
spkStatement, err := curve.NewGeneratorPoint().FromAffineCompressed(
k.SignedPreKey.Statement,
)
if err != nil {
return errors.Wrap(
errors.Wrap(err, "statement invalid"),
"verify",
)
}
if err := schnorr.DecommitVerify(
&schnorr.Proof{
Statement: idkStatement,
C: idkc,
S: idks,
},
provingKey.IdentityCommitment,
curve,
sha3.New256(),
curve.NewGeneratorPoint(),
[]byte{},
); err != nil {
return errors.Wrap(err, "verify")
}
if err := schnorr.DecommitVerify(
&schnorr.Proof{
Statement: spkStatement,
C: spkc,
S: spks,
},
provingKey.PrekeyCommitment,
curve,
sha3.New256(),
curve.NewGeneratorPoint(),
[]byte{},
); err != nil {
return errors.Wrap(err, "verify")
}
return nil
}
func (s *Ed448Signature) Verify(msg []byte) error {
if s.PublicKey == nil {
return errors.Wrap(errors.New("public key nil"), "verify")
}
if s.Signature == nil {
return errors.Wrap(errors.New("signature nil"), "verify")
}
if len(s.PublicKey.KeyValue) != 57 {
return errors.Wrap(errors.New("invalid length for public key"), "verify")
}
if len(s.Signature) != 114 {
return errors.Wrap(errors.New("invalid length for signature"), "verify")
}
if !ed448.Verify(s.PublicKey.KeyValue, msg, s.Signature, "") {
return errors.Wrap(errors.New("invalid signature for public key"), "verify")
}
return nil
}
func (s *Ed448Signature) VerifyCrossSigned(
publicKey []byte,
) error {
if s.PublicKey == nil {
return errors.Wrap(errors.New("public key nil"), "verify")
}
if s.Signature == nil {
return errors.Wrap(errors.New("signature nil"), "verify")
}
if len(s.PublicKey.KeyValue) != 57 {
return errors.Wrap(errors.New("invalid length for public key"), "verify")
}
if len(s.Signature) != 114 {
return errors.Wrap(errors.New("invalid length for signature"), "verify")
}
if !ed448.Verify(publicKey, s.PublicKey.KeyValue, s.Signature, "") {
return errors.Wrap(errors.New("invalid signature for public key"), "verify")
}
return nil
}