), nil
}
-// Sign the digest. opts argument is unused.
-func (prv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+// Sign the digest. opts argument is unused. That is identical to SignDigest,
+// but kept to be friendly to crypto.Signer.
+func (prv *PrivateKey) Sign(
+ rand io.Reader, digest []byte, opts crypto.SignerOpts,
+) ([]byte, error) {
return prv.SignDigest(digest, rand)
}
return prv.Prv.Public()
}
-func (prv *PrivateKeyReverseDigest) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
- d := make([]byte, len(digest))
- copy(d, digest)
- reverse(d)
- return prv.Prv.Sign(rand, d, opts)
+func (prv *PrivateKeyReverseDigest) Sign(
+ rand io.Reader, digest []byte, opts crypto.SignerOpts,
+) ([]byte, error) {
+ dgst := make([]byte, len(digest))
+ for i := 0; i < len(digest); i++ {
+ dgst[i] = digest[len(digest)-i-1]
+ }
+ return prv.Prv.Sign(rand, dgst, opts)
}
type PrivateKeyReverseDigestAndSignature struct {
return prv.Prv.Public()
}
-func (prv *PrivateKeyReverseDigestAndSignature) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
- d := make([]byte, len(digest))
- copy(d, digest)
- reverse(d)
- sign, err := prv.Prv.Sign(rand, d, opts)
+func (prv *PrivateKeyReverseDigestAndSignature) Sign(
+ rand io.Reader, digest []byte, opts crypto.SignerOpts,
+) ([]byte, error) {
+ dgst := make([]byte, len(digest))
+ for i := 0; i < len(digest); i++ {
+ dgst[i] = digest[len(digest)-i-1]
+ }
+ sign, err := prv.Prv.Sign(rand, dgst, opts)
if err != nil {
return sign, err
}
import (
"crypto"
"crypto/rand"
+ "io"
"testing"
)
func TestSignerInterface(t *testing.T) {
- prvRaw := make([]byte, 32)
- rand.Read(prvRaw)
- prv, err := NewPrivateKey(CurveIdGostR34102001TestParamSet(), prvRaw)
+ c := CurveIdGostR34102001TestParamSet()
+ prvRaw := make([]byte, c.PointSize())
+ _, err := io.ReadFull(rand.Reader, prvRaw)
+ if err != nil {
+ t.Fatal(err)
+ }
+ prv, err := NewPrivateKey(c, prvRaw)
if err != nil {
t.Fatal(err)
}
var _ crypto.Signer = prv
+ var _ crypto.Signer = &PrivateKeyReverseDigest{prv}
+ var _ crypto.Signer = &PrivateKeyReverseDigestAndSignature{prv}
+}
+
+func TestSignerReverseDigest(t *testing.T) {
+ dgst := make([]byte, 32)
+ _, err := io.ReadFull(rand.Reader, dgst)
+ if err != nil {
+ t.Fatal(err)
+ }
+ prv0, err := GenPrivateKey(CurveIdGostR34102001TestParamSet(), rand.Reader)
+ if err != nil {
+ t.Fatal(err)
+ }
+ pub0 := prv0.Public().(*PublicKey)
+ sign, err := prv0.Sign(rand.Reader, dgst, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ valid, err := pub0.VerifyDigest(dgst, sign)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !valid {
+ t.FailNow()
+ }
+ var _ crypto.PublicKey = pub0
+
+ prv1 := PrivateKeyReverseDigest{prv0}
+ pub1 := PublicKeyReverseDigest{prv1.Public().(*PublicKey)}
+ sign, err = prv1.Sign(rand.Reader, dgst, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ valid, err = pub1.VerifyDigest(dgst, sign)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !valid {
+ t.FailNow()
+ }
+
+ prv2 := PrivateKeyReverseDigestAndSignature{prv0}
+ pub2 := PublicKeyReverseDigestAndSignature{prv2.Public().(*PublicKey)}
+ sign, err = prv2.Sign(rand.Reader, dgst, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ valid, err = pub2.VerifyDigest(dgst, sign)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !valid {
+ t.FailNow()
+ }
}
)
type PublicKey struct {
- C *Curve
+ C *Curve
X, Y *big.Int
}
}
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)
+}
@code{gost3410.NewPrivateKeyBE}, @code{gost3410.PrivateKey.RawBE},
functions appeared, to simplify dealing with different endianness
keys serialisation
+ @item
+ @code{gost3410.PublicKeyReverseDigest} and
+ @code{gost3410.PublicKeyReverseDigestAndSignature} wrappers appeared
@end itemize
@anchor{Release 5.12.0}