xref: /aosp_15_r20/external/private-join-and-compute/private_join_and_compute/crypto/ec_group.h (revision a6aa18fbfbf9cb5cd47356a9d1b057768998488c)
1 /*
2  * Copyright 2019 Google LLC.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     https://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PRIVATE_JOIN_AND_COMPUTE_CRYPTO_EC_GROUP_H_
17 #define PRIVATE_JOIN_AND_COMPUTE_CRYPTO_EC_GROUP_H_
18 
19 #include <memory>
20 #include <string>
21 
22 #include "absl/strings/string_view.h"
23 #include "private_join_and_compute/crypto/big_num.h"
24 #include "private_join_and_compute/crypto/context.h"
25 #include "private_join_and_compute/crypto/openssl.inc"
26 #include "private_join_and_compute/util/status.inc"
27 
28 namespace private_join_and_compute {
29 
30 class ECPoint;
31 
32 // Wrapper class for openssl EC_GROUP.
33 class ECGroup {
34  public:
35   // Deletes a EC_GROUP.
36   class ECGroupDeleter {
37    public:
operator()38     void operator()(EC_GROUP* group) { EC_GROUP_free(group); }
39   };
40   typedef std::unique_ptr<EC_GROUP, ECGroupDeleter> ECGroupPtr;
41 
42   // Constructs a new ECGroup object for the given named curve id.
43   // See openssl header obj_mac.h for the available built-in curves.
44   // Use a well-known prime curve such as NID_X9_62_prime256v1 recommended by
45   // NIST. Returns INTERNAL error code if there is a failure in crypto
46   // operations. Security: this function is secure only for prime order curves.
47   // (All supported curves in BoringSSL have prime order.)
48   static StatusOr<ECGroup> Create(int curve_id, Context* context);
49 
50   // Generates a new private key. The private key is a cryptographically strong
51   // pseudo-random number in the range (0, order).
52   BigNum GeneratePrivateKey() const;
53 
54   // Verifies that the random key is a valid number in the range (0, order).
55   // Returns Status::OK if the key is valid, otherwise returns INVALID_ARGUMENT.
56   Status CheckPrivateKey(const BigNum& priv_key) const;
57 
58   // Hashes m to a point on the elliptic curve y^2 = x^3 + ax + b over a
59   // prime field using SHA256 with "try-and-increment" method.
60   // See https://crypto.stanford.edu/~dabo/papers/bfibe.pdf, Section 5.2.
61   // Returns an INVALID_ARGUMENT error code if an error occurs.
62   //
63   // Security: The number of operations required to hash a string depends on the
64   // string, which could lead to a timing attack.
65   // Security: This function is only secure for curves of prime order.
66   StatusOr<ECPoint> GetPointByHashingToCurveSha256(absl::string_view m) const;
67   StatusOr<ECPoint> GetPointByHashingToCurveSha384(absl::string_view m) const;
68   StatusOr<ECPoint> GetPointByHashingToCurveSha512(absl::string_view m) const;
69   StatusOr<ECPoint> GetPointByHashingToCurveSswuRo(absl::string_view m,
70                                                    absl::string_view dst) const;
71 
72   // Returns y^2 for the given x. The returned value is computed as x^3 + ax + b
73   // mod p, where a and b are the parameters of the curve.
74   BigNum ComputeYSquare(const BigNum& x) const;
75 
76   // Returns a fixed generator for this group.
77   // Returns an INTERNAL error code if it fails.
78   StatusOr<ECPoint> GetFixedGenerator() const;
79 
80   // Returns a random generator for this group.
81   // Returns an INTERNAL error code if it fails.
82   StatusOr<ECPoint> GetRandomGenerator() const;
83 
84   // Creates an ECPoint from the given string.
85   // Returns an INTERNAL error code if creating the point fails.
86   // Returns an INVALID_ARGUMENT error code if the created point is not in this
87   // group or if it is the point at infinity.
88   StatusOr<ECPoint> CreateECPoint(absl::string_view bytes) const;
89 
90   // The parameters describing an elliptic curve given by the equation
91   // y^2 = x^3 + a * x + b over a prime field Fp.
92   struct CurveParams {
93     BigNum p;
94     BigNum a;
95     BigNum b;
96   };
97 
98   // Returns the order.
GetOrder()99   const BigNum& GetOrder() const { return order_; }
100 
101   // Returns the cofactor.
GetCofactor()102   const BigNum& GetCofactor() const { return cofactor_; }
103 
104   // Returns the curve id.
GetCurveId()105   int GetCurveId() const { return EC_GROUP_get_curve_name(group_.get()); }
106 
107   // Creates an ECPoint which is the identity.
108   StatusOr<ECPoint> GetPointAtInfinity() const;
109 
110  private:
111   ECGroup(Context* context, ECGroupPtr group, BigNum order, BigNum cofactor,
112           CurveParams curve_params, BigNum p_minus_one_over_two);
113 
114   // Creates an ECPoint object with the given x, y affine coordinates.
115   // Returns an INVALID_ARGUMENT error code if the point (x, y) is not in this
116   // group or if it is the point at infinity.
117   StatusOr<ECPoint> CreateECPoint(const BigNum& x, const BigNum& y) const;
118 
119   // Returns true if q is a quadratic residue modulo curve_params_.p_.
120   bool IsSquare(const BigNum& q) const;
121 
122   // Checks if the given point is valid. Returns false if the point is not in
123   // the group or if it is the point is at infinity.
124   bool IsValid(const ECPoint& point) const;
125 
126   // Returns true if the given point is in the group.
127   bool IsOnCurve(const ECPoint& point) const;
128 
129   // Returns true if the given point is at infinity.
130   bool IsAtInfinity(const ECPoint& point) const;
131 
132   Context* context_;
133   ECGroupPtr group_;
134   // The order of this group.
135   BigNum order_;
136   // The cofactor of this group.
137   BigNum cofactor_;
138   // The parameters of the curve. These values are used to hash a number to a
139   // point on the curve.
140   CurveParams curve_params_;
141   // Constant used to evaluate if a number is a quadratic residue.
142   BigNum p_minus_one_over_two_;
143 
144   StatusOr<ECPoint> GetPointByHashingToCurveInternal(const BigNum& x) const;
145 };
146 
147 }  // namespace private_join_and_compute
148 
149 #endif  // PRIVATE_JOIN_AND_COMPUTE_CRYPTO_EC_GROUP_H_
150