File: ecdsa.go

package info (click to toggle)
golang-github-tink-crypto-tink-go 2.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 12,952 kB
  • sloc: sh: 864; makefile: 6
file content (103 lines) | stat: -rw-r--r-- 3,068 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package subtle

import (
	"errors"
	"fmt"
	"math/big"

	"github.com/tink-crypto/tink-go/v2/internal/signature/ecdsa"
)

var errUnsupportedEncoding = errors.New("ecdsa: unsupported encoding")

// ECDSASignature is a struct holding the r and s values of an ECDSA signature.
type ECDSASignature struct {
	R, S *big.Int
}

// NewECDSASignature creates a new ECDSASignature instance.
func NewECDSASignature(r, s *big.Int) *ECDSASignature {
	return &ECDSASignature{R: r, S: s}
}

// EncodeECDSASignature converts the signature to the given encoding format.
func (sig *ECDSASignature) EncodeECDSASignature(encoding, curveName string) ([]byte, error) {
	s := &ecdsa.Signature{R: sig.R, S: sig.S}
	var enc []byte
	var err error
	switch encoding {
	case "IEEE_P1363":
		enc, err = ecdsa.IEEEP1363Encode(s, curveName)
	case "DER":
		enc, err = ecdsa.ASN1Encode(s)
	default:
		err = errUnsupportedEncoding
	}
	if err != nil {
		return nil, fmt.Errorf("ecdsa: can't convert ECDSA signature to %s encoding: %v", encoding, err)
	}
	return enc, nil
}

// DecodeECDSASignature creates a new ECDSA signature using the given byte slice.
// The function assumes that the byte slice is the concatenation of the BigEndian
// representation of two big integer r and s.
func DecodeECDSASignature(encodedBytes []byte, encoding string) (*ECDSASignature, error) {
	var sig *ecdsa.Signature
	var err error
	switch encoding {
	case "IEEE_P1363":
		sig, err = ecdsa.IEEEP1363Decode(encodedBytes)
	case "DER":
		sig, err = ecdsa.ASN1Decode(encodedBytes)
	default:
		err = errUnsupportedEncoding
	}
	if err != nil {
		return nil, fmt.Errorf("ecdsa: %s", err)
	}
	return &ECDSASignature{R: sig.R, S: sig.S}, nil
}

// ValidateECDSAParams validates ECDSA parameters.
// The hash's strength must not be weaker than the curve's strength.
// DER and IEEE_P1363 encodings are supported.
func ValidateECDSAParams(hashAlg string, curve string, encoding string) error {
	switch encoding {
	case "DER":
	case "IEEE_P1363":
	default:
		return errUnsupportedEncoding
	}
	switch curve {
	case "NIST_P256":
		if hashAlg != "SHA256" {
			return errors.New("invalid hash type, expect SHA-256")
		}
	case "NIST_P384":
		if hashAlg != "SHA384" && hashAlg != "SHA512" {
			return errors.New("invalid hash type, expect SHA-384 or SHA-512")
		}
	case "NIST_P521":
		if hashAlg != "SHA512" {
			return errors.New("invalid hash type, expect SHA-512")
		}
	default:
		return fmt.Errorf("unsupported curve: %s", curve)
	}
	return nil
}