forked from cloudflare/gokey
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import deterministic ECDSA key generation code from Go 1.18 crypto/ec…
…dsa package Closes: cloudflare#61
- Loading branch information
Showing
3 changed files
with
78 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright 2011 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as | ||
// defined in FIPS 186-4 and SEC 1, Version 2.0. | ||
// | ||
// Signatures generated by this package are not deterministic, but entropy is | ||
// mixed with the private key and the message, achieving the same level of | ||
// security in case of randomness source failure. | ||
package ecdsa | ||
|
||
// [FIPS 186-4] references ANSI X9.62-2005 for the bulk of the ECDSA algorithm. | ||
// That standard is not freely available, which is a problem in an open source | ||
// implementation, because not only the implementer, but also any maintainer, | ||
// contributor, reviewer, auditor, and learner needs access to it. Instead, this | ||
// package references and follows the equivalent [SEC 1, Version 2.0]. | ||
// | ||
// [FIPS 186-4]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf | ||
// [SEC 1, Version 2.0]: https://www.secg.org/sec1-v2.pdf | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
"crypto/elliptic" | ||
"io" | ||
"math/big" | ||
) | ||
|
||
var one = new(big.Int).SetInt64(1) | ||
|
||
// randFieldElement returns a random element of the order of the given | ||
// curve using the procedure given in FIPS 186-4, Appendix B.5.1. | ||
func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) { | ||
params := c.Params() | ||
// Note that for P-521 this will actually be 63 bits more than the order, as | ||
// division rounds down, but the extra bit is inconsequential. | ||
b := make([]byte, params.BitSize/8+8) // TODO: use params.N.BitLen() | ||
_, err = io.ReadFull(rand, b) | ||
if err != nil { | ||
return | ||
} | ||
|
||
k = new(big.Int).SetBytes(b) | ||
n := new(big.Int).Sub(params.N, one) | ||
k.Mod(k, n) | ||
k.Add(k, one) | ||
return | ||
} | ||
|
||
// GenerateKey generates a public and private key pair. | ||
func GenerateKey(c elliptic.Curve, rand io.Reader) (*ecdsa.PrivateKey, error) { | ||
k, err := randFieldElement(c, rand) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
priv := new(ecdsa.PrivateKey) | ||
priv.PublicKey.Curve = c | ||
priv.D = k | ||
priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) | ||
return priv, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters