10#include <botan/ber_dec.h>
11#include <botan/der_enc.h>
12#include <botan/ec_group.h>
13#include <botan/hash.h>
15#include <botan/mem_ops.h>
16#include <botan/pk_ops.h>
17#include <botan/internal/ct_utils.h>
18#include <botan/internal/fmt.h>
27 m_group(key.domain()), m_peer(key._public_ec_point()) {
32 size_t max_input_bits()
const override {
37 size_t ciphertext_length(
size_t ptext_len)
const override {
38 const size_t elem_size = m_group.get_order_bytes();
39 const size_t der_overhead = 16;
41 return der_overhead + 2 * elem_size + m_hash->output_length() + ptext_len;
44 std::vector<uint8_t>
encrypt(std::span<const uint8_t> msg, RandomNumberGenerator& rng)
override {
50 const EC_AffinePoint kPB = m_peer.mul(k, rng);
52 const auto x2_bytes = kPB.x_bytes();
53 const auto y2_bytes = kPB.y_bytes();
56 kdf_input += x2_bytes;
57 kdf_input += y2_bytes;
59 const auto kdf_output = m_kdf->derive_key(msg.size(), kdf_input);
65 if(!msg.empty() &&
CT::all_zeros(kdf_output.data(), kdf_output.size()).as_bool()) {
69 std::vector<uint8_t> masked_msg(msg.size());
70 xor_buf(masked_msg, msg, kdf_output);
72 m_hash->update(x2_bytes);
74 m_hash->update(y2_bytes);
75 const auto C3 = m_hash->final<std::vector<uint8_t>>();
77 std::vector<uint8_t> ctext;
80 .encode(BigInt(C1.x_bytes()))
81 .encode(BigInt(C1.y_bytes()))
91 const EC_Group m_group;
92 const EC_AffinePoint m_peer;
93 std::unique_ptr<HashFunction> m_hash;
94 std::unique_ptr<KDF> m_kdf;
100 RandomNumberGenerator& rng,
101 std::string_view kdf_hash) :
102 m_group(key.domain()), m_x(key._private_key()), m_rng(rng) {
105 const std::string kdf_name =
fmt(
"KDF2({})", kdf_hash);
109 size_t plaintext_length(
size_t ptext_len)
const override {
114 const size_t elem_size = m_group.get_order_bytes();
116 if(ptext_len < 2 * elem_size + m_hash->output_length()) {
120 return ptext_len - (2 * elem_size + m_hash->output_length());
123 size_t ciphertext_length(
size_t ptext_len)
const override {
124 const size_t elem_size = m_group.get_order_bytes();
125 const size_t der_overhead = 16;
127 return der_overhead + 2 * elem_size + m_hash->output_length() + ptext_len;
131 const size_t p_bytes = m_group.get_p_bytes();
136 if(ctext.size() < 1 + p_bytes * 2 + m_hash->output_length()) {
155 if(C3.size() != m_hash->output_length()) {
166 const auto dbC1 = C1->mul(m_x, m_rng);
167 const auto x2_bytes = dbC1.x_bytes();
168 const auto y2_bytes = dbC1.y_bytes();
170 const auto kdf_output = m_kdf->derive_key(masked_msg.size(), dbC1.xy_bytes());
176 const auto kdf_nonzero =
179 xor_buf(masked_msg.data(), kdf_output.data(), kdf_output.size());
181 m_hash->update(x2_bytes);
182 m_hash->update(masked_msg);
183 m_hash->update(y2_bytes);
184 const auto u = m_hash->final();
187 valid_mask = mac_ok.if_set_return(0xFF);
190 (~mac_ok).if_set_zero_out(masked_msg.data(), masked_msg.size());
192 masked_msg.resize(output_len);
197 const EC_Group m_group;
199 RandomNumberGenerator& m_rng;
200 std::unique_ptr<HashFunction> m_hash;
201 std::unique_ptr<KDF> m_kdf;
207 std::string_view params,
208 std::string_view provider)
const {
211 if(provider ==
"base" || provider.empty()) {
213 return std::make_unique<SM2_Encryption_Operation>(*
this,
"SM3");
215 return std::make_unique<SM2_Encryption_Operation>(*
this, params);
223 std::string_view params,
224 std::string_view provider)
const {
225 if(provider ==
"base" || provider.empty()) {
227 return std::make_unique<SM2_Decryption_Operation>(*
this, rng,
"SM3");
229 return std::make_unique<SM2_Decryption_Operation>(*
this, rng, params);
static constexpr Mask< T > set()
static constexpr Mask< T > expand(T v)
static std::optional< EC_AffinePoint > from_bigint_xy(const EC_Group &group, const BigInt &x, const BigInt &y)
static EC_AffinePoint g_mul(const EC_Scalar &scalar, RandomNumberGenerator &rng)
Multiply by the group generator returning a complete point.
static EC_Scalar random(const EC_Group &group, RandomNumberGenerator &rng)
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
static std::unique_ptr< KDF > create_or_throw(std::string_view algo_spec, std::string_view provider="")
std::unique_ptr< PK_Ops::Decryption > create_decryption_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
std::unique_ptr< PK_Ops::Encryption > create_encryption_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
std::string algo_name() const override
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
constexpr CT::Mask< T > all_zeros(const T elem[], size_t len)
std::string decrypt(std::span< const uint8_t > input, std::string_view passphrase)
std::string encrypt(const uint8_t input[], size_t input_len, std::string_view passphrase, RandomNumberGenerator &rng)
SM2_PublicKey SM2_Encryption_PublicKey
std::string fmt(std::string_view format, const T &... args)
SM2_PrivateKey SM2_Encryption_PrivateKey
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
std::vector< T, secure_allocator< T > > secure_vector