xref: /aosp_15_r20/external/private-join-and-compute/private_join_and_compute/crypto/ec_point.cc (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 #include "private_join_and_compute/crypto/ec_point.h"
17 
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "absl/strings/str_cat.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 
ECPoint(const EC_GROUP * group,BN_CTX * bn_ctx)30 ECPoint::ECPoint(const EC_GROUP* group, BN_CTX* bn_ctx)
31     : bn_ctx_(bn_ctx), group_(group) {
32   point_ = ECPointPtr(EC_POINT_new(group_));
33 }
34 
ECPoint(const EC_GROUP * group,BN_CTX * bn_ctx,const BigNum & x,const BigNum & y)35 ECPoint::ECPoint(const EC_GROUP* group, BN_CTX* bn_ctx, const BigNum& x,
36                  const BigNum& y)
37     : ECPoint::ECPoint(group, bn_ctx) {
38   CRYPTO_CHECK(1 == EC_POINT_set_affine_coordinates_GFp(
39                         group_, point_.get(), x.GetConstBignumPtr(),
40                         y.GetConstBignumPtr(), bn_ctx_));
41 }
42 
ECPoint(const EC_GROUP * group,BN_CTX * bn_ctx,ECPointPtr point)43 ECPoint::ECPoint(const EC_GROUP* group, BN_CTX* bn_ctx, ECPointPtr point)
44     : ECPoint::ECPoint(group, bn_ctx) {
45   point_ = std::move(point);
46 }
47 
ToBytesCompressed() const48 StatusOr<std::string> ECPoint::ToBytesCompressed() const {
49   int length = EC_POINT_point2oct(
50       group_, point_.get(), POINT_CONVERSION_COMPRESSED, nullptr, 0, bn_ctx_);
51   std::vector<unsigned char> bytes(length);
52   if (0 == EC_POINT_point2oct(group_, point_.get(), POINT_CONVERSION_COMPRESSED,
53                               bytes.data(), length, bn_ctx_)) {
54     return InternalError(
55         absl::StrCat("EC_POINT_point2oct failed:", OpenSSLErrorString()));
56   }
57   return std::string(reinterpret_cast<char*>(bytes.data()), bytes.size());
58 }
59 
ToBytesUnCompressed() const60 StatusOr<std::string> ECPoint::ToBytesUnCompressed() const {
61   int length = EC_POINT_point2oct(
62       group_, point_.get(), POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, bn_ctx_);
63   std::vector<unsigned char> bytes(length);
64   if (0 == EC_POINT_point2oct(group_, point_.get(),
65                               POINT_CONVERSION_UNCOMPRESSED, bytes.data(),
66                               length, bn_ctx_)) {
67     return InternalError(
68         absl::StrCat("EC_POINT_point2oct failed:", OpenSSLErrorString()));
69   }
70   return std::string(reinterpret_cast<char*>(bytes.data()), bytes.size());
71 }
72 
Mul(const BigNum & scalar) const73 StatusOr<ECPoint> ECPoint::Mul(const BigNum& scalar) const {
74   ECPoint r = ECPoint(group_, bn_ctx_);
75   if (1 != EC_POINT_mul(group_, r.point_.get(), nullptr, point_.get(),
76                         scalar.GetConstBignumPtr(), bn_ctx_)) {
77     return InternalError(
78         absl::StrCat("EC_POINT_mul failed:", OpenSSLErrorString()));
79   }
80   return std::move(r);
81 }
82 
Add(const ECPoint & point) const83 StatusOr<ECPoint> ECPoint::Add(const ECPoint& point) const {
84   ECPoint r = ECPoint(group_, bn_ctx_);
85   if (1 != EC_POINT_add(group_, r.point_.get(), point_.get(),
86                         point.point_.get(), bn_ctx_)) {
87     return InternalError(
88         absl::StrCat("EC_POINT_add failed:", OpenSSLErrorString()));
89   }
90   return std::move(r);
91 }
92 
Clone() const93 StatusOr<ECPoint> ECPoint::Clone() const {
94   ECPoint r = ECPoint(group_, bn_ctx_);
95   if (1 != EC_POINT_copy(r.point_.get(), point_.get())) {
96     return InternalError(
97         absl::StrCat("EC_POINT_copy failed:", OpenSSLErrorString()));
98   }
99   return std::move(r);
100 }
101 
Inverse() const102 StatusOr<ECPoint> ECPoint::Inverse() const {
103   // Create a copy of this.
104   ASSIGN_OR_RETURN(ECPoint inv, Clone());
105   // Invert the copy in-place.
106   if (1 != EC_POINT_invert(group_, inv.point_.get(), bn_ctx_)) {
107     return InternalError(
108         absl::StrCat("EC_POINT_invert failed:", OpenSSLErrorString()));
109   }
110   return std::move(inv);
111 }
112 
IsPointAtInfinity() const113 bool ECPoint::IsPointAtInfinity() const {
114   return EC_POINT_is_at_infinity(group_, point_.get());
115 }
116 
CompareTo(const ECPoint & point) const117 bool ECPoint::CompareTo(const ECPoint& point) const {
118   return 0 == EC_POINT_cmp(group_, point_.get(), point.point_.get(), bn_ctx_);
119 }
120 
121 }  // namespace private_join_and_compute
122