From f98dd1a338867a408f7c72d73fbad7fe7fc93e3a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 3 Feb 2016 21:58:02 +0000 Subject: libgo: Update to go1.6rc1. Reviewed-on: https://go-review.googlesource.com/19200 From-SVN: r233110 --- libgo/go/crypto/ecdsa/ecdsa.go | 39 ++++++++++++++++++++++++++++----- libgo/go/crypto/ecdsa/ecdsa_test.go | 43 +++++++++++++++++++++++++++++++++---- 2 files changed, 73 insertions(+), 9 deletions(-) (limited to 'libgo/go/crypto/ecdsa') diff --git a/libgo/go/crypto/ecdsa/ecdsa.go b/libgo/go/crypto/ecdsa/ecdsa.go index 8d66477..0731f2b 100644 --- a/libgo/go/crypto/ecdsa/ecdsa.go +++ b/libgo/go/crypto/ecdsa/ecdsa.go @@ -27,6 +27,17 @@ import ( "math/big" ) +// A invertible implements fast inverse mod Curve.Params().N +type invertible interface { + // Inverse returns the inverse of k in GF(P) + Inverse(k *big.Int) *big.Int +} + +// combinedMult implements fast multiplication S1*g + S2*p (g - generator, p - arbitrary point) +type combinedMult interface { + CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int) +} + const ( aesIV = "IV for ECDSA CTR" ) @@ -179,7 +190,12 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err return } - kInv = fermatInverse(k, N) + if in, ok := priv.Curve.(invertible); ok { + kInv = in.Inverse(k) + } else { + kInv = fermatInverse(k, N) + } + r, _ = priv.Curve.ScalarBaseMult(k.Bytes()) r.Mod(r, N) if r.Sign() != 0 { @@ -214,16 +230,29 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { return false } e := hashToInt(hash, c) - w := new(big.Int).ModInverse(s, N) + + var w *big.Int + if in, ok := c.(invertible); ok { + w = in.Inverse(s) + } else { + w = new(big.Int).ModInverse(s, N) + } u1 := e.Mul(e, w) u1.Mod(u1, N) u2 := w.Mul(r, w) u2.Mod(u2, N) - x1, y1 := c.ScalarBaseMult(u1.Bytes()) - x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes()) - x, y := c.Add(x1, y1, x2, y2) + // Check if implements S1*g + S2*p + var x, y *big.Int + if opt, ok := c.(combinedMult); ok { + x, y = opt.CombinedMult(pub.X, pub.Y, u1.Bytes(), u2.Bytes()) + } else { + x1, y1 := c.ScalarBaseMult(u1.Bytes()) + x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes()) + x, y = c.Add(x1, y1, x2, y2) + } + if x.Sign() == 0 && y.Sign() == 0 { return false } diff --git a/libgo/go/crypto/ecdsa/ecdsa_test.go b/libgo/go/crypto/ecdsa/ecdsa_test.go index 169944d..62a3fcc 100644 --- a/libgo/go/crypto/ecdsa/ecdsa_test.go +++ b/libgo/go/crypto/ecdsa/ecdsa_test.go @@ -42,6 +42,41 @@ func TestKeyGeneration(t *testing.T) { testKeyGeneration(t, elliptic.P521(), "p521") } +func BenchmarkSignP256(b *testing.B) { + b.ResetTimer() + p256 := elliptic.P256() + hashed := []byte("testing") + priv, _ := GenerateKey(p256, rand.Reader) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _, _ = Sign(rand.Reader, priv, hashed) + } +} + +func BenchmarkVerifyP256(b *testing.B) { + b.ResetTimer() + p256 := elliptic.P256() + hashed := []byte("testing") + priv, _ := GenerateKey(p256, rand.Reader) + r, s, _ := Sign(rand.Reader, priv, hashed) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + Verify(&priv.PublicKey, hashed, r, s) + } +} + +func BenchmarkKeyGeneration(b *testing.B) { + b.ResetTimer() + p256 := elliptic.P256() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + GenerateKey(p256, rand.Reader) + } +} + func testSignAndVerify(t *testing.T, c elliptic.Curve, tag string) { priv, _ := GenerateKey(c, rand.Reader) @@ -91,11 +126,11 @@ func testNonceSafety(t *testing.T, c elliptic.Curve, tag string) { if s0.Cmp(s1) == 0 { // This should never happen. - t.Errorf("%s: the signatures on two different messages were the same") + t.Errorf("%s: the signatures on two different messages were the same", tag) } if r0.Cmp(r1) == 0 { - t.Errorf("%s: the nonce used for two diferent messages was the same") + t.Errorf("%s: the nonce used for two diferent messages was the same", tag) } } @@ -126,11 +161,11 @@ func testINDCCA(t *testing.T, c elliptic.Curve, tag string) { } if s0.Cmp(s1) == 0 { - t.Errorf("%s: two signatures of the same message produced the same result") + t.Errorf("%s: two signatures of the same message produced the same result", tag) } if r0.Cmp(r1) == 0 { - t.Errorf("%s: two signatures of the same message produced the same nonce") + t.Errorf("%s: two signatures of the same message produced the same nonce", tag) } } -- cgit v1.1