From dec688f7cc518669ade24a9270f79a496222fa2d Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Tue, 26 Nov 2024 17:48:32 +0800 Subject: [PATCH] ecdh: update comments --- ecdh/ecdh.go | 19 +++++++++++++++---- ecdh/sm2ec.go | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ecdh/ecdh.go b/ecdh/ecdh.go index f688117..81d0f04 100644 --- a/ecdh/ecdh.go +++ b/ecdh/ecdh.go @@ -5,6 +5,7 @@ package ecdh import ( "crypto" "crypto/subtle" + "errors" "hash" "io" "sync" @@ -13,7 +14,11 @@ import ( ) type Curve interface { - // GenerateKey generates a new PrivateKey from rand. + // GenerateKey generates a random PrivateKey. + // + // Most applications should use [crypto/rand.Reader] as rand. Note that the + // returned key does not depend deterministically on the bytes read from rand, + // and may change between calls and/or between versions. GenerateKey(rand io.Reader) (*PrivateKey, error) // NewPrivateKey checks that key is valid and returns a PrivateKey. @@ -108,7 +113,7 @@ func (k *PublicKey) SM2ZA(md hash.Hash, uid []byte) ([]byte, error) { return k.curve.sm2za(md, k, uid) } -// SM2SharedKey performs SM2 key derivation to generate shared keying data, the uv was generated by SM2MQV. +// SM2SharedKey performs SM2 key derivation to generate shared keying data, the uv was generated by [SM2MQV]. func (uv *PublicKey) SM2SharedKey(isResponder bool, kenLen int, sPub, sRemote *PublicKey, uid []byte, remoteUID []byte) ([]byte, error) { var buffer [128]byte copy(buffer[:], uv.publicKey[1:]) @@ -154,11 +159,17 @@ type PrivateKey struct { // For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If // the result is the all-zero value, ECDH returns an error. func (k *PrivateKey) ECDH(remote *PublicKey) ([]byte, error) { + if k.curve != remote.curve { + return nil, errors.New("ecdh: private key and public key curves do not match") + } return k.curve.ecdh(k, remote) } // SM2MQV performs a SM2 specific style ECMQV exchange and return the shared secret. func (k *PrivateKey) SM2MQV(eLocal *PrivateKey, sRemote, eRemote *PublicKey) (*PublicKey, error) { + if k.curve != eLocal.curve || k.curve != sRemote.curve || k.curve != eRemote.curve { + return nil, errors.New("ecdh: private key and public key curves do not match") + } return k.curve.sm2mqv(k, eLocal, sRemote, eRemote) } @@ -173,7 +184,7 @@ func (k *PrivateKey) Bytes() []byte { // Equal returns whether x represents the same private key as k. // // Note that there can be equivalent private keys with different encodings which -// would return false from this check but behave the same way as inputs to ECDH. +// would return false from this check but behave the same way as inputs to [ECDH]. // // This check is performed in constant time as long as the key types and their // curve match. @@ -198,7 +209,7 @@ func (k *PrivateKey) PublicKey() *PublicKey { } // Public implements the implicit interface of all standard library private -// keys. See the docs of crypto.PrivateKey. +// keys. See the docs of [crypto.PrivateKey]. func (k *PrivateKey) Public() crypto.PublicKey { return k.PublicKey() } diff --git a/ecdh/sm2ec.go b/ecdh/sm2ec.go index 8d9956c..bc1103b 100644 --- a/ecdh/sm2ec.go +++ b/ecdh/sm2ec.go @@ -174,7 +174,7 @@ func (c *sm2Curve) sm2za(md hash.Hash, pub *PublicKey, uid []byte) ([]byte, erro return md.Sum(nil), nil } -// P256 returns a Curve which implements SM2, also known as sm2p256v1 +// P256 returns a [Curve] which implements SM2, also known as sm2p256v1 // // Multiple invocations of this function will return the same value, so it can // be used for equality checks and switch statements.