diff --git a/ecgdsa/ecgdsa.go b/ecgdsa/ecgdsa.go index 05690ea6..c6ce16f0 100644 --- a/ecgdsa/ecgdsa.go +++ b/ecgdsa/ecgdsa.go @@ -174,6 +174,43 @@ func parseSignature(sig []byte) (r, s *big.Int, err error) { return } +// Sign data returns the Bytes encoded signature. +func SignBytes(rand io.Reader, priv *PrivateKey, h Hasher, data []byte) (sig []byte, err error) { + r, s, err := SignToRS(rand, priv, h, data) + if err != nil { + return nil, err + } + + byteLen := (priv.Curve.Params().BitSize + 7) / 8 + + sig = make([]byte, 2 * byteLen) + + r.FillBytes(sig[:byteLen]) + s.FillBytes(sig[byteLen:]) + + return +} + +// Verify verifies the Bytes encoded signature +func VerifyBytes(pub *PublicKey, h Hasher, data, sig []byte) bool { + byteLen := (pub.Curve.Params().BitSize + 7) / 8 + + if len(sig) != 2*byteLen { + return false + } + + r := new(big.Int).SetBytes(sig[:byteLen]) + s := new(big.Int).SetBytes(sig[byteLen:]) + + return VerifyWithRS( + pub, + h, + data, + r, + s, + ) +} + /** *| IUF - EC-GDSA signature *| @@ -274,6 +311,7 @@ func VerifyWithRS(pub *PublicKey, hashFunc Hasher, data []byte, r, s *big.Int) b !pub.Curve.IsOnCurve(pub.X, pub.Y) { return false } + if r.Sign() <= 0 || s.Sign() <= 0 { return false } diff --git a/ecgdsa/ecgdsa_test.go b/ecgdsa/ecgdsa_test.go index 208d1a30..5c970b26 100644 --- a/ecgdsa/ecgdsa_test.go +++ b/ecgdsa/ecgdsa_test.go @@ -128,6 +128,28 @@ func Test_SignVerify2(t *testing.T) { } +func Test_SignVerify3(t *testing.T) { + priv, err := GenerateKey(rand.Reader, elliptic.P224()) + if err != nil { + t.Fatal(err) + } + + pub := &priv.PublicKey + + data := []byte("test-data test-data test-data test-data test-data") + + sig, err := SignBytes(rand.Reader, priv, sha256.New, data) + if err != nil { + t.Fatal(err) + } + + res := VerifyBytes(pub, sha256.New, data, sig) + if !res { + t.Error("Verify fail") + } + +} + func Test_Marshal(t *testing.T) { private, err := GenerateKey(rand.Reader, elliptic.P224()) if err != nil { diff --git a/eckcdsa/eckcdsa.go b/eckcdsa/eckcdsa.go index d8bd7008..cd29fa4e 100644 --- a/eckcdsa/eckcdsa.go +++ b/eckcdsa/eckcdsa.go @@ -103,8 +103,8 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp } // Generate the paramters -func GenerateKey(c elliptic.Curve, randReader io.Reader) (*PrivateKey, error) { - d, err := randFieldElement(randReader, c) +func GenerateKey(random io.Reader, c elliptic.Curve) (*PrivateKey, error) { + d, err := randFieldElement(random, c) if err != nil { return nil, err } @@ -174,6 +174,47 @@ func parseSignature(sig []byte) (r, s *big.Int, err error) { return } +// Sign data returns the Bytes encoded signature. +func SignBytes(rand io.Reader, priv *PrivateKey, h Hasher, data []byte) (sig []byte, err error) { + r, s, err := SignToRS(rand, priv, h, data) + if err != nil { + return nil, err + } + + hsize := h().Size() + bitSize := priv.Curve.Params().BitSize + sigRLen := sigRLen(hsize, bitSize) + + sig = make([]byte, sigLen(hsize, bitSize)) + + r.FillBytes(sig[:sigRLen]) + s.FillBytes(sig[sigRLen:]) + + return +} + +// Verify verifies the Bytes encoded signature +func VerifyBytes(pub *PublicKey, h Hasher, data, sig []byte) bool { + hsize := h().Size() + bitSize := pub.Curve.Params().BitSize + sigRLen := sigRLen(hsize, bitSize) + + if len(sig) != sigLen(hsize, bitSize) { + return false + } + + r := new(big.Int).SetBytes(sig[:sigRLen]) + s := new(big.Int).SetBytes(sig[sigRLen:]) + + return VerifyWithRS( + pub, + h, + data, + r, + s, + ) +} + /** *| IUF - EC-KCDSA signature *| @@ -193,11 +234,11 @@ func parseSignature(sig []byte) (r, s *big.Int, err error) { *| F 10. return (r,s) * */ -func SignToRS(rand io.Reader, priv *PrivateKey, h Hasher, msg []byte) (r, s *big.Int, err error) { +func SignToRS(random io.Reader, priv *PrivateKey, h Hasher, msg []byte) (r, s *big.Int, err error) { var k *big.Int for { - k, err = randFieldElement(rand, priv.Curve) + k, err = randFieldElement(random, priv.Curve) if err != nil { return } @@ -454,3 +495,27 @@ func fermatInverse(a, N *big.Int) *big.Int { func bigIntEqual(a, b *big.Int) bool { return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1 } + +func sigRLen(hsize, n int) int { + return mathMin(hsize, byteceil(n)) +} + +func sigLLen(n int) int { + return byteceil(n) +} + +func sigLen(hsize, n int) int { + return sigRLen(hsize, n) + sigLLen(n) +} + +func mathMin(a, b int) int { + if a < b { + return a + } + + return b +} + +func byteceil(size int) int { + return (size + 7) / 8 +} diff --git a/eckcdsa/eckcdsa_test.go b/eckcdsa/eckcdsa_test.go index eb9dbcd5..19a59d06 100644 --- a/eckcdsa/eckcdsa_test.go +++ b/eckcdsa/eckcdsa_test.go @@ -233,12 +233,34 @@ func Test_Signing_With_DegenerateKeys(t *testing.T) { } } +func Test_SignBytes(t *testing.T) { + priv, err := GenerateKey(rand.Reader, p256) + if err != nil { + t.Fatal(err) + } + + pub := &priv.PublicKey + + data := []byte("test-data test-data test-data test-data test-data") + + sig, err := SignBytes(rand.Reader, priv, sha256.New, data) + if err != nil { + t.Fatal(err) + } + + res := VerifyBytes(pub, sha256.New, data, sig) + if !res { + t.Error("Verify fail") + } + +} + func testKCDSA( curve elliptic.Curve, h Hasher, ) func(t *testing.T) { return func(t *testing.T) { - priv, err := GenerateKey(curve, rand.Reader) + priv, err := GenerateKey(rand.Reader, curve) if err != nil { t.Errorf("error generating key: %s", err) return @@ -438,7 +460,7 @@ func Test_PKCS8PrivateKey(t *testing.T) { func test_PKCS8PrivateKey(t *testing.T, curue elliptic.Curve) { t.Run(fmt.Sprintf("%s", curue), func(t *testing.T) { - priv, err := GenerateKey(curue, rand.Reader) + priv, err := GenerateKey(rand.Reader, curue) if err != nil { t.Fatal(err) } @@ -488,7 +510,7 @@ func Test_PKCS1PrivateKey(t *testing.T) { func test_PKCS1PrivateKey(t *testing.T, curue elliptic.Curve) { t.Run(fmt.Sprintf("%s", curue), func(t *testing.T) { - priv, err := GenerateKey(curue, rand.Reader) + priv, err := GenerateKey(rand.Reader, curue) if err != nil { t.Fatal(err) } diff --git a/kcdsa/kcdsa.go b/kcdsa/kcdsa.go index 073ba740..d92e968c 100644 --- a/kcdsa/kcdsa.go +++ b/kcdsa/kcdsa.go @@ -336,19 +336,19 @@ func Sign(rand io.Reader, priv *PrivateKey, h Hasher, data []byte) (r, s *big.In return } -func Verify(pub *PublicKey, h Hasher, data []byte, R, S *big.Int) bool { +func Verify(pub *PublicKey, h Hasher, data []byte, r, s *big.Int) bool { if pub.P.Sign() <= 0 { return false } - if R.Sign() < 1 { + if r.Sign() < 1 { return false } - if S.Sign() < 1 || S.Cmp(pub.Q) >= 0 { + if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 { return false } - return verify(pub, h, data, R, S) + return verify(pub, h, data, r, s) } // Sign data returns the ASN.1 encoded signature.