xref: /aosp_15_r20/external/tink/cc/internal/ec_util.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang // Copyright 2021 Google LLC
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang //     http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ///////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang #ifndef TINK_INTERNAL_EC_UTIL_H_
17*e7b1675dSTing-Kang Chang #define TINK_INTERNAL_EC_UTIL_H_
18*e7b1675dSTing-Kang Chang 
19*e7b1675dSTing-Kang Chang #include <stdint.h>
20*e7b1675dSTing-Kang Chang 
21*e7b1675dSTing-Kang Chang #include <memory>
22*e7b1675dSTing-Kang Chang #include <string>
23*e7b1675dSTing-Kang Chang 
24*e7b1675dSTing-Kang Chang #include "absl/strings/string_view.h"
25*e7b1675dSTing-Kang Chang #include "openssl/ec.h"
26*e7b1675dSTing-Kang Chang #include "tink/internal/ssl_unique_ptr.h"
27*e7b1675dSTing-Kang Chang #include "tink/subtle/common_enums.h"
28*e7b1675dSTing-Kang Chang #include "tink/util/secret_data.h"
29*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
30*e7b1675dSTing-Kang Chang 
31*e7b1675dSTing-Kang Chang namespace crypto {
32*e7b1675dSTing-Kang Chang namespace tink {
33*e7b1675dSTing-Kang Chang namespace internal {
34*e7b1675dSTing-Kang Chang 
X25519KeyPubKeySize()35*e7b1675dSTing-Kang Chang constexpr int64_t X25519KeyPubKeySize() { return 32; }
X25519KeyPrivKeySize()36*e7b1675dSTing-Kang Chang constexpr int64_t X25519KeyPrivKeySize() { return 32; }
X25519KeySharedKeySize()37*e7b1675dSTing-Kang Chang constexpr int64_t X25519KeySharedKeySize() { return 32; }
38*e7b1675dSTing-Kang Chang 
Ed25519KeyPubKeySize()39*e7b1675dSTing-Kang Chang constexpr int64_t Ed25519KeyPubKeySize() { return 32; }
Ed25519KeyPrivKeySize()40*e7b1675dSTing-Kang Chang constexpr int64_t Ed25519KeyPrivKeySize() { return 32; }
41*e7b1675dSTing-Kang Chang 
42*e7b1675dSTing-Kang Chang struct EcKey {
43*e7b1675dSTing-Kang Chang   subtle::EllipticCurveType curve;
44*e7b1675dSTing-Kang Chang   // Affine coordinates in bigendian representation.
45*e7b1675dSTing-Kang Chang   std::string pub_x;
46*e7b1675dSTing-Kang Chang   std::string pub_y;
47*e7b1675dSTing-Kang Chang   // Big integer in bigendian representation.
48*e7b1675dSTing-Kang Chang   crypto::tink::util::SecretData priv;
49*e7b1675dSTing-Kang Chang };
50*e7b1675dSTing-Kang Chang 
51*e7b1675dSTing-Kang Chang struct X25519Key {
52*e7b1675dSTing-Kang Chang   uint8_t public_value[X25519KeyPubKeySize()];
53*e7b1675dSTing-Kang Chang   uint8_t private_key[X25519KeyPrivKeySize()];
54*e7b1675dSTing-Kang Chang };
55*e7b1675dSTing-Kang Chang 
56*e7b1675dSTing-Kang Chang struct Ed25519Key {
57*e7b1675dSTing-Kang Chang   std::string public_key;
58*e7b1675dSTing-Kang Chang   std::string private_key;
59*e7b1675dSTing-Kang Chang };
60*e7b1675dSTing-Kang Chang 
61*e7b1675dSTing-Kang Chang // EcKey.
62*e7b1675dSTing-Kang Chang 
63*e7b1675dSTing-Kang Chang // Returns a new EC key for the specified curve.
64*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<EcKey> NewEcKey(
65*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve_type);
66*e7b1675dSTing-Kang Chang 
67*e7b1675dSTing-Kang Chang // Returns a new EC key for the specified curve derived from a secret seed.
68*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<EcKey> NewEcKey(
69*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve_type,
70*e7b1675dSTing-Kang Chang     const crypto::tink::util::SecretData &secret_seed);
71*e7b1675dSTing-Kang Chang 
72*e7b1675dSTing-Kang Chang // X25519Key Utils.
73*e7b1675dSTing-Kang Chang 
74*e7b1675dSTing-Kang Chang // Returns a new X25519Key key. It returns a kInternal error status if the
75*e7b1675dSTing-Kang Chang // OpenSSL/BoringSSL APIs fail.
76*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<X25519Key>> NewX25519Key();
77*e7b1675dSTing-Kang Chang 
78*e7b1675dSTing-Kang Chang // Returns a X25519Key matching the specified EcKey.
79*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<X25519Key>> X25519KeyFromEcKey(
80*e7b1675dSTing-Kang Chang     const EcKey &ec_key);
81*e7b1675dSTing-Kang Chang 
82*e7b1675dSTing-Kang Chang // Returns an EcKey matching the specified X25519Key.
83*e7b1675dSTing-Kang Chang EcKey EcKeyFromX25519Key(const X25519Key *x25519_key);
84*e7b1675dSTing-Kang Chang 
85*e7b1675dSTing-Kang Chang // Generates a shared secret using `private_key` and `peer_public_key`; keys
86*e7b1675dSTing-Kang Chang // must be X25519 keys otherwise an error is returned.
87*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<util::SecretData> ComputeX25519SharedSecret(
88*e7b1675dSTing-Kang Chang     EVP_PKEY *private_key, EVP_PKEY *peer_public_key);
89*e7b1675dSTing-Kang Chang 
90*e7b1675dSTing-Kang Chang // Computes the corresponding public+private key for the supplied private key.
91*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<X25519Key>>
92*e7b1675dSTing-Kang Chang X25519KeyFromPrivateKey(const crypto::tink::util::SecretData &private_key);
93*e7b1675dSTing-Kang Chang 
94*e7b1675dSTing-Kang Chang // Ed25519Key Utils.
95*e7b1675dSTing-Kang Chang 
96*e7b1675dSTing-Kang Chang // Returns a new ED25519 key.
97*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<Ed25519Key>> NewEd25519Key();
98*e7b1675dSTing-Kang Chang 
99*e7b1675dSTing-Kang Chang // Returns a new ED25519 key generated from a 32-byte secret seed.
100*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<Ed25519Key>> NewEd25519Key(
101*e7b1675dSTing-Kang Chang     const crypto::tink::util::SecretData &secret_seed);
102*e7b1675dSTing-Kang Chang 
103*e7b1675dSTing-Kang Chang // EC_POINT Encode/Decode.
104*e7b1675dSTing-Kang Chang 
105*e7b1675dSTing-Kang Chang // Given x, y as curve_size_in_bytes big-endian byte array, encoding is as
106*e7b1675dSTing-Kang Chang // follows:
107*e7b1675dSTing-Kang Chang // - The uncompressed point is encoded as 0x04 || x || y.
108*e7b1675dSTing-Kang Chang // - The compressed point is encoded as:
109*e7b1675dSTing-Kang Chang //   - 0x03 || x if the least significant bit of y is 1;
110*e7b1675dSTing-Kang Chang //   - 0x02 || x otherwise.
111*e7b1675dSTing-Kang Chang 
112*e7b1675dSTing-Kang Chang // Returns OpenSSL/BoringSSL's EC_POINT constructed from curve type
113*e7b1675dSTing-Kang Chang // `curve_type`, point `format` and encoded public key's point `encoded_point`.
114*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<SslUniquePtr<EC_POINT>> EcPointDecode(
115*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve_type,
116*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EcPointFormat format,
117*e7b1675dSTing-Kang Chang     absl::string_view encoded_point);
118*e7b1675dSTing-Kang Chang 
119*e7b1675dSTing-Kang Chang // Returns the encoded public key based on curve type `curve_type`, point
120*e7b1675dSTing-Kang Chang // `format` and OpenSSL/BoringSSL's EC_POINT public key `point`.
121*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::string> EcPointEncode(
122*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve_type,
123*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EcPointFormat format, const EC_POINT *point);
124*e7b1675dSTing-Kang Chang 
125*e7b1675dSTing-Kang Chang // Returns the encoding size of a point on the specified elliptic curve
126*e7b1675dSTing-Kang Chang // `curve_type` when the given point `format` is used.
127*e7b1675dSTing-Kang Chang util::StatusOr<int32_t> EcPointEncodingSizeInBytes(
128*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve_type,
129*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EcPointFormat format);
130*e7b1675dSTing-Kang Chang 
131*e7b1675dSTing-Kang Chang // Returns the size (in bytes) of an element of the field over which
132*e7b1675dSTing-Kang Chang // the curve `curve_type` is defined.
133*e7b1675dSTing-Kang Chang util::StatusOr<int32_t> EcFieldSizeInBytes(
134*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve_type);
135*e7b1675dSTing-Kang Chang 
136*e7b1675dSTing-Kang Chang // EC_GROUP Utils.
137*e7b1675dSTing-Kang Chang 
138*e7b1675dSTing-Kang Chang // Returns OpenSSL/BoringSSL's EC_GROUP constructed from the given `curve_type`.
139*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<SslUniquePtr<EC_GROUP>> EcGroupFromCurveType(
140*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve_type);
141*e7b1675dSTing-Kang Chang 
142*e7b1675dSTing-Kang Chang // Returns the curve type associated with the given `group`.
143*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<crypto::tink::subtle::EllipticCurveType>
144*e7b1675dSTing-Kang Chang CurveTypeFromEcGroup(const EC_GROUP *group);
145*e7b1675dSTing-Kang Chang 
146*e7b1675dSTing-Kang Chang // Returns OpenSSL/BoringSSL's EC_POINT constructed from the curve type,
147*e7b1675dSTing-Kang Chang // big-endian representation of public key's x-coordinate and y-coordinate.
148*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<SslUniquePtr<EC_POINT>> GetEcPoint(
149*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve, absl::string_view pubx,
150*e7b1675dSTing-Kang Chang     absl::string_view puby);
151*e7b1675dSTing-Kang Chang 
152*e7b1675dSTing-Kang Chang // Transforms ECDSA IEEE_P1363 signature encoding to DER encoding.
153*e7b1675dSTing-Kang Chang //
154*e7b1675dSTing-Kang Chang // The IEEE_P1363 signature's format is r || s, where r and s are zero-padded
155*e7b1675dSTing-Kang Chang // and have the same size in bytes as the order of the curve. For example, for
156*e7b1675dSTing-Kang Chang // NIST P-256 curve, r and s are zero-padded to 32 bytes.
157*e7b1675dSTing-Kang Chang //
158*e7b1675dSTing-Kang Chang // The DER signature is encoded using ASN.1
159*e7b1675dSTing-Kang Chang // (https://tools.ietf.org/html/rfc5480#appendix-A):
160*e7b1675dSTing-Kang Chang //   ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }.
161*e7b1675dSTing-Kang Chang // In particular, the encoding is:
162*e7b1675dSTing-Kang Chang //   0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s
163*e7b1675dSTing-Kang Chang util::StatusOr<std::string> EcSignatureIeeeToDer(const EC_GROUP *group,
164*e7b1675dSTing-Kang Chang                                                  absl::string_view ieee_sig);
165*e7b1675dSTing-Kang Chang 
166*e7b1675dSTing-Kang Chang // Returns the ECDH's shared secret between two peers A and B using A's private
167*e7b1675dSTing-Kang Chang // key `priv_key` and B's public key `pub_key`. Returns error if `pub_key`
168*e7b1675dSTing-Kang Chang // is not on `priv_key`'s curve `curve`.
169*e7b1675dSTing-Kang Chang util::StatusOr<util::SecretData> ComputeEcdhSharedSecret(
170*e7b1675dSTing-Kang Chang     crypto::tink::subtle::EllipticCurveType curve, const BIGNUM *priv_key,
171*e7b1675dSTing-Kang Chang     const EC_POINT *pub_key);
172*e7b1675dSTing-Kang Chang 
173*e7b1675dSTing-Kang Chang }  // namespace internal
174*e7b1675dSTing-Kang Chang }  // namespace tink
175*e7b1675dSTing-Kang Chang }  // namespace crypto
176*e7b1675dSTing-Kang Chang 
177*e7b1675dSTing-Kang Chang #endif  // TINK_INTERNAL_EC_UTIL_H_
178