X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=gost3410%2Fpublic.go;h=a5a4b7059b60d98a68f60ed435f8212bf2443b5c;hb=HEAD;hp=ea1906dc2ce883a1f7a1b598e83acf4de0a291ec;hpb=5afe1dcbfaf1043ed9e72e215a285966eaba3369;p=gogost.git diff --git a/gost3410/public.go b/gost3410/public.go index ea1906d..a8669cf 100644 --- a/gost3410/public.go +++ b/gost3410/public.go @@ -1,5 +1,5 @@ // GoGOST -- Pure Go GOST cryptographic functions library -// Copyright (C) 2015-2023 Sergey Matveev +// Copyright (C) 2015-2024 Sergey Matveev // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,12 +22,12 @@ import ( ) type PublicKey struct { - C *Curve - X *big.Int - Y *big.Int + C *Curve + X, Y *big.Int } -func NewPublicKey(c *Curve, raw []byte) (*PublicKey, error) { +// Unmarshal LE(X)||LE(Y) public key. "raw" must be 2*c.PointSize() length. +func NewPublicKeyLE(c *Curve, raw []byte) (*PublicKey, error) { pointSize := c.PointSize() key := make([]byte, 2*pointSize) if len(raw) != len(key) { @@ -43,7 +43,26 @@ func NewPublicKey(c *Curve, raw []byte) (*PublicKey, error) { }, nil } -func (pub *PublicKey) Raw() []byte { +// Unmarshal BE(X)||BE(Y) public key. "raw" must be 2*c.PointSize() length. +func NewPublicKeyBE(c *Curve, raw []byte) (*PublicKey, error) { + pointSize := c.PointSize() + if len(raw) != 2*pointSize { + return nil, fmt.Errorf("gogost/gost3410: len(key) != %d", 2*pointSize) + } + return &PublicKey{ + c, + bytes2big(raw[:pointSize]), + bytes2big(raw[pointSize:]), + }, nil +} + +// This is an alias for NewPublicKeyLE(). +func NewPublicKey(c *Curve, raw []byte) (*PublicKey, error) { + return NewPublicKeyLE(c, raw) +} + +// Marshal LE(X)||LE(Y) public key. raw will be 2*pub.C.PointSize() length. +func (pub *PublicKey) RawLE() []byte { pointSize := pub.C.PointSize() raw := append( pad(pub.Y.Bytes(), pointSize), @@ -53,10 +72,24 @@ func (pub *PublicKey) Raw() []byte { return raw } +// Marshal BE(X)||BE(Y) public key. raw will be 2*pub.C.PointSize() length. +func (pub *PublicKey) RawBE() []byte { + pointSize := pub.C.PointSize() + return append( + pad(pub.X.Bytes(), pointSize), + pad(pub.Y.Bytes(), pointSize)..., + ) +} + +// This is an alias for RawLE(). +func (pub *PublicKey) Raw() []byte { + return pub.RawLE() +} + func (pub *PublicKey) VerifyDigest(digest, signature []byte) (bool, error) { pointSize := pub.C.PointSize() if len(signature) != 2*pointSize { - return false, fmt.Errorf("gogost/gost3410: len(signature) != %d", 2*pointSize) + return false, fmt.Errorf("gogost/gost3410: len(signature)=%d != %d", len(signature), 2*pointSize) } s := bytes2big(signature[:pointSize]) r := bytes2big(signature[pointSize:]) @@ -116,3 +149,43 @@ func (our *PublicKey) Equal(theirKey crypto.PublicKey) bool { } return our.X.Cmp(their.X) == 0 && our.Y.Cmp(their.Y) == 0 && our.C.Equal(their.C) } + +type PublicKeyReverseDigest struct { + Pub *PublicKey +} + +func (pub PublicKeyReverseDigest) VerifyDigest( + digest, signature []byte, +) (bool, error) { + dgst := make([]byte, len(digest)) + for i := 0; i < len(digest); i++ { + dgst[i] = digest[len(digest)-i-1] + } + return pub.Pub.VerifyDigest(dgst, signature) +} + +func (pub PublicKeyReverseDigest) Equal(theirKey crypto.PublicKey) bool { + return pub.Pub.Equal(theirKey) +} + +type PublicKeyReverseDigestAndSignature struct { + Pub *PublicKey +} + +func (pub PublicKeyReverseDigestAndSignature) VerifyDigest( + digest, signature []byte, +) (bool, error) { + dgst := make([]byte, len(digest)) + for i := 0; i < len(digest); i++ { + dgst[i] = digest[len(digest)-i-1] + } + sign := make([]byte, len(signature)) + for i := 0; i < len(signature); i++ { + sign[i] = signature[len(signature)-i-1] + } + return pub.Pub.VerifyDigest(dgst, sign) +} + +func (pub PublicKeyReverseDigestAndSignature) Equal(theirKey crypto.PublicKey) bool { + return pub.Pub.Equal(theirKey) +}