From: Sergey Matveev Date: Mon, 7 Aug 2023 13:02:21 +0000 (+0300) Subject: gost3410.Public/Private keys BE/LE marshalling X-Git-Tag: v5.13.0~1 X-Git-Url: http://www.git.cypherpunks.ru/?p=gogost.git;a=commitdiff_plain;h=e077d5f903e233fbefed0815be21be5f8f482017 gost3410.Public/Private keys BE/LE marshalling --- diff --git a/gogost.go b/gogost.go index 496885e..b7d04d9 100644 --- a/gogost.go +++ b/gogost.go @@ -1,4 +1,4 @@ // Pure Go GOST cryptographic functions library. package gogost -const Version = "5.12.0" +const Version = "5.13.0" diff --git a/gost3410/private.go b/gost3410/private.go index 983d8d2..18549a2 100644 --- a/gost3410/private.go +++ b/gost3410/private.go @@ -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 { diff --git a/gost3410/public.go b/gost3410/public.go index d2c01bc..ef5926b 100644 --- a/gost3410/public.go +++ b/gost3410/public.go @@ -23,12 +23,11 @@ import ( type PublicKey struct { C *Curve - X *big.Int - Y *big.Int + X, Y *big.Int } // Unmarshal LE(X)||LE(Y) public key. "raw" must be 2*c.PointSize() length. -func NewPublicKey(c *Curve, raw []byte) (*PublicKey, error) { +func NewPublicKeyLE(c *Curve, raw []byte) (*PublicKey, error) { pointSize := c.PointSize() key := make([]byte, 2*pointSize) if len(raw) != len(key) { @@ -44,10 +43,28 @@ func NewPublicKey(c *Curve, raw []byte) (*PublicKey, error) { }, nil } +// 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) Raw() (raw []byte) { +func (pub *PublicKey) RawLE() []byte { pointSize := pub.C.PointSize() - raw = append( + raw := append( pad(pub.Y.Bytes(), pointSize), pad(pub.X.Bytes(), pointSize)..., ) @@ -55,6 +72,20 @@ func (pub *PublicKey) Raw() (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 { diff --git a/news.texi b/news.texi index 01a789a..022b9a6 100644 --- a/news.texi +++ b/news.texi @@ -3,6 +3,18 @@ @table @strong +@anchor{Release 5.13.0} +@item 5.13.0 + @itemize + @item + @code{gost3410.NewPublicKeyLE}, @code{gost3410.PublicKey.RawLE}, + @code{gost3410.NewPublicKeyBE}, @code{gost3410.PublicKey.RawBE}, + @code{gost3410.NewPrivateKeyLE}, @code{gost3410.PrivateKey.RawLE}, + @code{gost3410.NewPrivateKeyBE}, @code{gost3410.PrivateKey.RawBE}, + functions appeared, to simplify dealing with different endianness + keys serialisation + @end itemize + @anchor{Release 5.12.0} @item 5.12.0 Updated dependencies.