type PublicKey … // ECDH returns k as a [ecdh.PublicKey]. It returns an error if the key is // invalid according to the definition of [ecdh.Curve.NewPublicKey], or if the // Curve is not supported by crypto/ecdh. func (k *PublicKey) ECDH() (*ecdh.PublicKey, error) { … } // Equal reports whether pub and x have the same value. // // Two keys are only considered to have the same value if they have the same Curve value. // Note that for example [elliptic.P256] and elliptic.P256().Params() are different // values, as the latter is a generic not constant time implementation. func (pub *PublicKey) Equal(x crypto.PublicKey) bool { … } type PrivateKey … // ECDH returns k as a [ecdh.PrivateKey]. It returns an error if the key is // invalid according to the definition of [ecdh.Curve.NewPrivateKey], or if the // Curve is not supported by [crypto/ecdh]. func (k *PrivateKey) ECDH() (*ecdh.PrivateKey, error) { … } func curveToECDH(c elliptic.Curve) ecdh.Curve { … } // Public returns the public key corresponding to priv. func (priv *PrivateKey) Public() crypto.PublicKey { … } // Equal reports whether priv and x have the same value. // // See [PublicKey.Equal] for details on how Curve is compared. func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool { … } // bigIntEqual reports whether a and b are equal leaking only their bit length // through timing side-channels. func bigIntEqual(a, b *big.Int) bool { … } // Sign signs digest with priv, reading randomness from rand. The opts argument // is not currently used but, in keeping with the crypto.Signer interface, // should be the hash function used to digest the message. // // This method implements crypto.Signer, which is an interface to support keys // where the private part is kept in, for example, a hardware module. Common // uses can use the [SignASN1] function in this package directly. func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) { … } // GenerateKey generates a new ECDSA private key for the specified curve. // // 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. func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) { … } func generateNISTEC[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (*PrivateKey, error) { … } // randomPoint returns a random scalar and the corresponding point using the // procedure given in FIPS 186-4, Appendix B.5.2 (rejection sampling). func randomPoint[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (k *bigmod.Nat, p Point, err error) { … } var testingOnlyRejectionSamplingLooped … var errNoAsm … // SignASN1 signs a hash (which should be the result of hashing a larger message) // using the private key, priv. If the hash is longer than the bit-length of the // private key's curve order, the hash will be truncated to that length. It // returns the ASN.1 encoded signature. // // The signature is randomized. Most applications should use [crypto/rand.Reader] // as rand. Note that the returned signature does not depend deterministically on // the bytes read from rand, and may change between calls and/or between versions. func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { … } func signNISTEC[Point nistPoint[Point]](c *nistCurve[Point], priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) { … } func encodeSignature(r, s []byte) ([]byte, error) { … } // addASN1IntBytes encodes in ASN.1 a positive integer represented as // a big-endian byte slice with zero or more leading zeroes. func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) { … } // inverse sets kInv to the inverse of k modulo the order of the curve. func inverse[Point nistPoint[Point]](c *nistCurve[Point], kInv, k *bigmod.Nat) { … } // hashToNat sets e to the left-most bits of hash, according to // SEC 1, Section 4.1.3, point 5 and Section 4.1.4, point 3. func hashToNat[Point nistPoint[Point]](c *nistCurve[Point], e *bigmod.Nat, hash []byte) { … } // mixedCSPRNG returns a CSPRNG that mixes entropy from rand with the message // and the private key, to protect the key in case rand fails. This is // equivalent in security to RFC 6979 deterministic nonce generation, but still // produces randomized signatures. func mixedCSPRNG(rand io.Reader, priv *PrivateKey, hash []byte) (io.Reader, error) { … } type zr … var zeroReader … // Read replaces the contents of dst with zeros. It is safe for concurrent use. func (zr) Read(dst []byte) (n int, err error) { … } // VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the // public key, pub. Its return value records whether the signature is valid. // // The inputs are not considered confidential, and may leak through timing side // channels, or if an attacker has control of part of the inputs. func VerifyASN1(pub *PublicKey, hash, sig []byte) bool { … } func verifyNISTEC[Point nistPoint[Point]](c *nistCurve[Point], pub *PublicKey, hash, sig []byte) bool { … } func parseSignature(sig []byte) (r, s []byte, err error) { … } type nistCurve … type nistPoint … // pointFromAffine is used to convert the PublicKey to a nistec Point. func (curve *nistCurve[Point]) pointFromAffine(x, y *big.Int) (p Point, err error) { … } // pointToAffine is used to convert a nistec Point to a PublicKey. func (curve *nistCurve[Point]) pointToAffine(p Point) (x, y *big.Int, err error) { … } var p224Once … var _p224 … func p224() *nistCurve[*nistec.P224Point] { … } var p256Once … var _p256 … func p256() *nistCurve[*nistec.P256Point] { … } var p384Once … var _p384 … func p384() *nistCurve[*nistec.P384Point] { … } var p521Once … var _p521 … func p521() *nistCurve[*nistec.P521Point] { … } func precomputeParams[Point nistPoint[Point]](c *nistCurve[Point], curve elliptic.Curve) { … }