1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2022 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 type PublicKey struct {
30 func NewPublicKey(c *Curve, raw []byte) (*PublicKey, error) {
31 pointSize := c.PointSize()
32 key := make([]byte, 2*pointSize)
33 if len(raw) != len(key) {
34 return nil, fmt.Errorf("gogost/gost3410: len(key) != %d", len(key))
36 for i := 0; i < len(key); i++ {
37 key[i] = raw[len(raw)-i-1]
41 bytes2big(key[pointSize : 2*pointSize]),
42 bytes2big(key[:pointSize]),
46 func (pub *PublicKey) Raw() []byte {
47 pointSize := pub.C.PointSize()
49 pad(pub.Y.Bytes(), pointSize),
50 pad(pub.X.Bytes(), pointSize)...,
56 func (pub *PublicKey) VerifyDigest(digest, signature []byte) (bool, error) {
57 pointSize := pub.C.PointSize()
58 if len(signature) != 2*pointSize {
59 return false, fmt.Errorf("gogost/gost3410: len(signature) != %d", 2*pointSize)
61 s := bytes2big(signature[:pointSize])
62 r := bytes2big(signature[pointSize:])
63 if r.Cmp(zero) <= 0 ||
64 r.Cmp(pub.C.Q) >= 0 ||
69 e := bytes2big(digest)
75 v.ModInverse(e, pub.C.Q)
83 p1x, p1y, err := pub.C.Exp(z1, pub.C.X, pub.C.Y)
87 q1x, q1y, err := pub.C.Exp(z2, pub.X, pub.Y)
96 lm.ModInverse(lm, pub.C.P)
105 if lm.Cmp(zero) < 0 {
109 return lm.Cmp(r) == 0, nil
112 func (our *PublicKey) Equal(theirKey crypto.PublicKey) bool {
113 their, ok := theirKey.(*PublicKey)
117 return our.X.Cmp(their.X) == 0 && our.Y.Cmp(their.Y) == 0 && our.C.Equal(their.C)