This repository has been archived by the owner on Sep 8, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 124
/
public_key.go
73 lines (63 loc) · 1.72 KB
/
public_key.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
// Copyright Coinbase, Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
package bbs
import (
"errors"
"fmt"
"github.com/coinbase/kryptology/pkg/core/curves"
)
// 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
}