X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=gost3410%2Fprivate.go;h=8168fe00bbfda343b0d6f776cf4ccb04b5c1c773;hb=HEAD;hp=983d8d2849399c80a5617e8a5917180f9b96eb75;hpb=0ad3c46736ab347028125436c7d8435003969f53;p=gogost.git diff --git a/gost3410/private.go b/gost3410/private.go index 983d8d2..89e0feb 100644 --- a/gost3410/private.go +++ b/gost3410/private.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 @@ -29,7 +29,7 @@ type PrivateKey struct { } // Unmarshal little-endian private key. "raw" must be c.PointSize() length. -func NewPrivateKey(c *Curve, raw []byte) (*PrivateKey, error) { +func NewPrivateKeyLE(c *Curve, raw []byte) (*PrivateKey, error) { pointSize := c.PointSize() if len(raw) != pointSize { return nil, fmt.Errorf("gogost/gost3410: len(key)=%d != %d", len(raw), pointSize) @@ -45,6 +45,24 @@ func NewPrivateKey(c *Curve, raw []byte) (*PrivateKey, error) { return &PrivateKey{c, k.Mod(k, c.Q)}, nil } +// Unmarshal big-endian private key. "raw" must be c.PointSize() length. +func NewPrivateKeyBE(c *Curve, raw []byte) (*PrivateKey, error) { + pointSize := c.PointSize() + if len(raw) != pointSize { + return nil, fmt.Errorf("gogost/gost3410: len(key)=%d != %d", len(raw), pointSize) + } + k := bytes2big(raw) + if k.Cmp(zero) == 0 { + return nil, errors.New("gogost/gost3410: zero private key") + } + return &PrivateKey{c, k.Mod(k, c.Q)}, nil +} + +// This is an alias for NewPrivateKeyLE(). +func NewPrivateKey(c *Curve, raw []byte) (*PrivateKey, error) { + return NewPrivateKeyLE(c, raw) +} + func GenPrivateKey(c *Curve, rand io.Reader) (*PrivateKey, error) { raw := make([]byte, c.PointSize()) if _, err := io.ReadFull(rand, raw); err != nil { @@ -54,12 +72,22 @@ func GenPrivateKey(c *Curve, rand io.Reader) (*PrivateKey, error) { } // Marshal little-endian private key. raw will be prv.C.PointSize() length. -func (prv *PrivateKey) Raw() (raw []byte) { +func (prv *PrivateKey) RawLE() (raw []byte) { raw = pad(prv.Key.Bytes(), prv.C.PointSize()) reverse(raw) return raw } +// Marshal big-endian private key. raw will be prv.C.PointSize() length. +func (prv *PrivateKey) RawBE() (raw []byte) { + return pad(prv.Key.Bytes(), prv.C.PointSize()) +} + +// This is an alias for RawLE(). +func (prv *PrivateKey) Raw() []byte { + return prv.RawLE() +} + func (prv *PrivateKey) PublicKey() (*PublicKey, error) { x, y, err := prv.C.Exp(prv.Key, prv.C.X, prv.C.Y) if err != nil { @@ -111,8 +139,11 @@ Retry: ), 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) } @@ -132,11 +163,14 @@ func (prv *PrivateKeyReverseDigest) Public() crypto.PublicKey { 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 { @@ -147,11 +181,14 @@ func (prv *PrivateKeyReverseDigestAndSignature) Public() crypto.PublicKey { 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 }