diff options
-rw-r--r-- | src/lib/pubkey/ec_group/curve_gfp.cpp | 89 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/curve_gfp.h | 26 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.cpp | 3 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/point_gfp.cpp | 34 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/point_gfp.h | 16 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/point_mul.cpp | 116 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/point_mul.h | 20 | ||||
-rw-r--r-- | src/lib/pubkey/sm2/sm2_enc.cpp | 16 |
8 files changed, 174 insertions, 146 deletions
diff --git a/src/lib/pubkey/ec_group/curve_gfp.cpp b/src/lib/pubkey/ec_group/curve_gfp.cpp index a9fa2d614..8ce8a6732 100644 --- a/src/lib/pubkey/ec_group/curve_gfp.cpp +++ b/src/lib/pubkey/ec_group/curve_gfp.cpp @@ -66,17 +66,17 @@ class CurveGFp_Montgomery final : public CurveGFp_Repr void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override; - void curve_mul(BigInt& z, const BigInt& x, const BigInt& y, - secure_vector<word>& ws) const override; - void curve_mul_words(BigInt& z, const word x_words[], const size_t x_size, const BigInt& y, secure_vector<word>& ws) const override; - void curve_sqr(BigInt& z, const BigInt& x, - secure_vector<word>& ws) const override; + void curve_sqr_words(BigInt& z, + const word x_words[], + size_t x_size, + secure_vector<word>& ws) const override; + private: BigInt m_p; BigInt m_a, m_b; @@ -120,35 +120,14 @@ void CurveGFp_Montgomery::from_curve_rep(BigInt& z, secure_vector<word>& ws) con ws.data(), ws.size()); } -void CurveGFp_Montgomery::curve_mul(BigInt& z, const BigInt& x, const BigInt& y, - secure_vector<word>& ws) const - { - if(ws.size() < get_ws_size()) - ws.resize(get_ws_size()); - - const size_t output_size = 2*m_p_words + 2; - if(z.size() < output_size) - z.grow_to(output_size); - - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); - - bigint_mul(z.mutable_data(), z.size(), - x.data(), x.size(), std::min(m_p_words, x.size()), - y.data(), y.size(), std::min(m_p_words, y.size()), - ws.data(), ws.size()); - - bigint_monty_redc(z.mutable_data(), - m_p.data(), m_p_words, m_p_dash, - ws.data(), ws.size()); - } - void CurveGFp_Montgomery::curve_mul_words(BigInt& z, const word x_w[], size_t x_size, const BigInt& y, secure_vector<word>& ws) const { + BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); + if(ws.size() < get_ws_size()) ws.resize(get_ws_size()); @@ -156,8 +135,6 @@ void CurveGFp_Montgomery::curve_mul_words(BigInt& z, if(z.size() < output_size) z.grow_to(output_size); - BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); - bigint_mul(z.mutable_data(), z.size(), x_w, x_size, std::min(m_p_words, x_size), y.data(), y.size(), std::min(m_p_words, y.size()), @@ -168,8 +145,10 @@ void CurveGFp_Montgomery::curve_mul_words(BigInt& z, ws.data(), ws.size()); } -void CurveGFp_Montgomery::curve_sqr(BigInt& z, const BigInt& x, - secure_vector<word>& ws) const +void CurveGFp_Montgomery::curve_sqr_words(BigInt& z, + const word x[], + size_t x_size, + secure_vector<word>& ws) const { if(ws.size() < get_ws_size()) ws.resize(get_ws_size()); @@ -178,10 +157,8 @@ void CurveGFp_Montgomery::curve_sqr(BigInt& z, const BigInt& x, if(z.size() < output_size) z.grow_to(output_size); - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - bigint_sqr(z.mutable_data(), z.size(), - x.data(), x.size(), std::min(m_p_words, x.size()), + x, x_size, std::min(m_p_words, x_size), ws.data(), ws.size()); bigint_monty_redc(z.mutable_data(), @@ -225,9 +202,6 @@ class CurveGFp_NIST : public CurveGFp_Repr BigInt invert_element(const BigInt& x, secure_vector<word>& ws) const override; - void curve_mul(BigInt& z, const BigInt& x, const BigInt& y, - secure_vector<word>& ws) const override; - void curve_mul_words(BigInt& z, const word x_words[], const size_t x_size, @@ -246,8 +220,10 @@ class CurveGFp_NIST : public CurveGFp_Repr x.swap(tmp); } - void curve_sqr(BigInt& z, const BigInt& x, - secure_vector<word>& ws) const override; + void curve_sqr_words(BigInt& z, + const word x_words[], + size_t x_size, + secure_vector<word>& ws) const override; private: virtual void redc(BigInt& x, secure_vector<word>& ws) const = 0; @@ -263,33 +239,14 @@ BigInt CurveGFp_NIST::invert_element(const BigInt& x, secure_vector<word>& ws) c return inverse_mod(x, get_p()); } -void CurveGFp_NIST::curve_mul(BigInt& z, const BigInt& x, const BigInt& y, - secure_vector<word>& ws) const - { - if(ws.size() < get_ws_size()) - ws.resize(get_ws_size()); - - const size_t output_size = 2*m_p_words + 2; - if(z.size() < output_size) - z.grow_to(output_size); - - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); - - bigint_mul(z.mutable_data(), z.size(), - x.data(), x.size(), std::min(m_p_words, x.size()), - y.data(), y.size(), std::min(m_p_words, y.size()), - ws.data(), ws.size()); - - this->redc(z, ws); - } - void CurveGFp_NIST::curve_mul_words(BigInt& z, const word x_w[], size_t x_size, const BigInt& y, secure_vector<word>& ws) const { + BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); + if(ws.size() < get_ws_size()) ws.resize(get_ws_size()); @@ -297,8 +254,6 @@ void CurveGFp_NIST::curve_mul_words(BigInt& z, if(z.size() < output_size) z.grow_to(output_size); - BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); - bigint_mul(z.mutable_data(), z.size(), x_w, x_size, std::min(m_p_words, x_size), y.data(), y.size(), std::min(m_p_words, y.size()), @@ -307,8 +262,8 @@ void CurveGFp_NIST::curve_mul_words(BigInt& z, this->redc(z, ws); } -void CurveGFp_NIST::curve_sqr(BigInt& z, const BigInt& x, - secure_vector<word>& ws) const +void CurveGFp_NIST::curve_sqr_words(BigInt& z, const word x[], size_t x_size, + secure_vector<word>& ws) const { if(ws.size() < get_ws_size()) ws.resize(get_ws_size()); @@ -317,10 +272,8 @@ void CurveGFp_NIST::curve_sqr(BigInt& z, const BigInt& x, if(z.size() < output_size) z.grow_to(output_size); - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - bigint_sqr(z.mutable_data(), output_size, - x.data(), x.size(), std::min(m_p_words, x.size()), + x, x_size, std::min(m_p_words, x_size), ws.data(), ws.size()); this->redc(z, ws); diff --git a/src/lib/pubkey/ec_group/curve_gfp.h b/src/lib/pubkey/ec_group/curve_gfp.h index 888f87d46..85640b442 100644 --- a/src/lib/pubkey/ec_group/curve_gfp.h +++ b/src/lib/pubkey/ec_group/curve_gfp.h @@ -55,8 +55,12 @@ class BOTAN_UNSTABLE_API CurveGFp_Repr virtual void from_curve_rep(BigInt& x, secure_vector<word>& ws) const = 0; - virtual void curve_mul(BigInt& z, const BigInt& x, const BigInt& y, - secure_vector<word>& ws) const = 0; + void curve_mul(BigInt& z, const BigInt& x, const BigInt& y, + secure_vector<word>& ws) const + { + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + curve_mul_words(z, x.data(), x.size(), y, ws); + } virtual void curve_mul_words(BigInt& z, const word x_words[], @@ -64,8 +68,17 @@ class BOTAN_UNSTABLE_API CurveGFp_Repr const BigInt& y, secure_vector<word>& ws) const = 0; - virtual void curve_sqr(BigInt& z, const BigInt& x, - secure_vector<word>& ws) const = 0; + void curve_sqr(BigInt& z, const BigInt& x, + secure_vector<word>& ws) const + { + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + curve_sqr_words(z, x.data(), x.size(), ws); + } + + virtual void curve_sqr_words(BigInt& z, + const word x_words[], + size_t x_size, + secure_vector<word>& ws) const = 0; }; /** @@ -172,6 +185,11 @@ class BOTAN_UNSTABLE_API CurveGFp final m_repr->curve_sqr(z, x, ws); } + void sqr(BigInt& z, const word x_w[], size_t x_size, secure_vector<word>& ws) const + { + m_repr->curve_sqr_words(z, x_w, x_size, ws); + } + BigInt mul(const BigInt& x, const BigInt& y, secure_vector<word>& ws) const { return mul_to_tmp(x, y, ws); diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp index 2dfcdc0d9..c859fc2fc 100644 --- a/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/lib/pubkey/ec_group/ec_group.cpp @@ -557,8 +557,7 @@ PointGFp EC_Group::blinded_var_point_multiply(const PointGFp& point, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const { - PointGFp_Var_Point_Precompute mul(point); - mul.randomize_repr(rng, ws); + PointGFp_Var_Point_Precompute mul(point, rng, ws); return mul.mul(k, rng, get_order(), ws); } diff --git a/src/lib/pubkey/ec_group/point_gfp.cpp b/src/lib/pubkey/ec_group/point_gfp.cpp index 206c8e749..26b2ec371 100644 --- a/src/lib/pubkey/ec_group/point_gfp.cpp +++ b/src/lib/pubkey/ec_group/point_gfp.cpp @@ -179,19 +179,31 @@ void PointGFp::add_affine(const word x_words[], size_t x_size, m_coord_z = T3; } -// Point addition -void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) +void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& workspace) { BOTAN_ASSERT_NOMSG(m_curve == rhs.m_curve); - if(rhs.is_zero()) + const size_t p_words = m_curve.get_p_words(); + add(rhs.m_coord_x.data(), std::min(p_words, rhs.m_coord_x.size()), + rhs.m_coord_y.data(), std::min(p_words, rhs.m_coord_y.size()), + rhs.m_coord_z.data(), std::min(p_words, rhs.m_coord_z.size()), + workspace); + } + +void PointGFp::add(const word x_words[], size_t x_size, + const word y_words[], size_t y_size, + const word z_words[], size_t z_size, + std::vector<BigInt>& ws_bn) + { + if(all_zeros(x_words, x_size) && all_zeros(z_words, z_size)) return; if(is_zero()) { - m_coord_x = rhs.m_coord_x; - m_coord_y = rhs.m_coord_y; - m_coord_z = rhs.m_coord_z; + // FIXME avoid the copy here + m_coord_x = BigInt(x_words, x_size); + m_coord_y = BigInt(y_words, y_size); + m_coord_z = BigInt(z_words, z_size); return; } @@ -213,16 +225,16 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) const BigInt& p = m_curve.get_p(); - m_curve.sqr(T0, rhs.m_coord_z, ws); // z2^2 + m_curve.sqr(T0, z_words, z_size, ws); // z2^2 m_curve.mul(T1, m_coord_x, T0, ws); // x1*z2^2 - m_curve.mul(T3, rhs.m_coord_z, T0, ws); // z2^3 + m_curve.mul(T3, z_words, z_size, T0, ws); // z2^3 m_curve.mul(T2, m_coord_y, T3, ws); // y1*z2^3 m_curve.sqr(T3, m_coord_z, ws); // z1^2 - m_curve.mul(T4, rhs.m_coord_x, T3, ws); // x2*z1^2 + m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2 m_curve.mul(T5, m_coord_z, T3, ws); // z1^3 - m_curve.mul(T0, rhs.m_coord_y, T5, ws); // y2*z1^3 + m_curve.mul(T0, y_words, y_size, T5, ws); // y2*z1^3 T4.mod_sub(T1, p, sub_ws); // x2*z1^2 - x1*z2^2 @@ -261,7 +273,7 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) m_coord_y.mod_sub(T3, p, sub_ws); - m_curve.mul(T3, m_coord_z, rhs.m_coord_z, ws); + m_curve.mul(T3, z_words, z_size, m_coord_z, ws); m_curve.mul(m_coord_z, T3, T4, ws); } diff --git a/src/lib/pubkey/ec_group/point_gfp.h b/src/lib/pubkey/ec_group/point_gfp.h index 39188ba21..bc8a8571f 100644 --- a/src/lib/pubkey/ec_group/point_gfp.h +++ b/src/lib/pubkey/ec_group/point_gfp.h @@ -218,6 +218,22 @@ class BOTAN_PUBLIC_API(2,0) PointGFp final void add(const PointGFp& other, std::vector<BigInt>& workspace); /** + * Point addition. Array version. + * + * @param x_words the words of the x coordinate of the other point + * @param x_size size of x_words + * @param y_words the words of the y coordinate of the other point + * @param y_size size of y_words + * @param z_words the words of the y coordinate of the other point + * @param z_size size of y_words + * @param workspace temp space, at least WORKSPACE_SIZE elements + */ + void add(const word x_words[], size_t x_size, + const word y_words[], size_t y_size, + const word z_words[], size_t z_size, + std::vector<BigInt>& workspace); + + /** * Point addition - mixed J+A * @param other affine point to add - assumed to be affine! * @param workspace temp space, at least WORKSPACE_SIZE elements diff --git a/src/lib/pubkey/ec_group/point_mul.cpp b/src/lib/pubkey/ec_group/point_mul.cpp index df51037a5..d0c0e2034 100644 --- a/src/lib/pubkey/ec_group/point_mul.cpp +++ b/src/lib/pubkey/ec_group/point_mul.cpp @@ -26,7 +26,8 @@ Blinded_Point_Multiply::Blinded_Point_Multiply(const PointGFp& base, m_order(order) { BOTAN_UNUSED(h); - m_point_mul.reset(new PointGFp_Var_Point_Precompute(base)); + Null_RNG null_rng; + m_point_mul.reset(new PointGFp_Var_Point_Precompute(base, null_rng, m_ws)); } Blinded_Point_Multiply::~Blinded_Point_Multiply() @@ -159,56 +160,68 @@ PointGFp PointGFp_Base_Point_Precompute::mul(const BigInt& k, return R; } -PointGFp_Var_Point_Precompute::PointGFp_Var_Point_Precompute(const PointGFp& point) +PointGFp_Var_Point_Precompute::PointGFp_Var_Point_Precompute(const PointGFp& point, + RandomNumberGenerator& rng, + std::vector<BigInt>& ws) : + m_curve(point.get_curve()), + m_p_words(m_curve.get_p().sig_words()), + m_window_bits(4) { - m_window_bits = 4; - - std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE); + if(ws.size() < PointGFp::WORKSPACE_SIZE) + ws.resize(PointGFp::WORKSPACE_SIZE); - m_U.resize(1U << m_window_bits); - m_U[0] = point.zero(); - m_U[1] = point; + std::vector<PointGFp> U(1U << m_window_bits); + U[0] = point.zero(); + U[1] = point; - for(size_t i = 2; i < m_U.size(); i += 2) + for(size_t i = 2; i < U.size(); i += 2) { - m_U[i] = m_U[i/2].double_of(ws); - m_U[i+1] = m_U[i].plus(point, ws); + U[i] = U[i/2].double_of(ws); + U[i+1] = U[i].plus(point, ws); } - } -void PointGFp_Var_Point_Precompute::randomize_repr(RandomNumberGenerator& rng, - std::vector<BigInt>& ws_bn) - { - if(ws_bn.size() < 7) - ws_bn.resize(7); + // Hack to handle Blinded_Point_Multiply + if(rng.is_seeded()) + { + BigInt& mask = ws[0]; + BigInt& mask2 = ws[1]; + BigInt& mask3 = ws[2]; + BigInt& new_x = ws[3]; + BigInt& new_y = ws[4]; + BigInt& new_z = ws[5]; + secure_vector<word>& tmp = ws[6].get_word_vector(); - BigInt& mask = ws_bn[0]; - BigInt& mask2 = ws_bn[1]; - BigInt& mask3 = ws_bn[2]; - BigInt& new_x = ws_bn[3]; - BigInt& new_y = ws_bn[4]; - BigInt& new_z = ws_bn[5]; - secure_vector<word>& ws = ws_bn[6].get_word_vector(); + const CurveGFp& curve = U[0].get_curve(); - const CurveGFp& curve = m_U[0].get_curve(); + const size_t p_bits = curve.get_p().bits(); - const size_t p_bits = curve.get_p().bits(); + // Skipping zero point since it can't be randomized + for(size_t i = 1; i != U.size(); ++i) + { + mask.randomize(rng, p_bits - 1, false); + // Easy way of ensuring mask != 0 + mask.set_bit(0); - // Skipping zero point since it can't be randomized - for(size_t i = 1; i != m_U.size(); ++i) - { - mask.randomize(rng, p_bits - 1, false); - // Easy way of ensuring mask != 0 - mask.set_bit(0); + curve.sqr(mask2, mask, tmp); + curve.mul(mask3, mask, mask2, tmp); - curve.sqr(mask2, mask, ws); - curve.mul(mask3, mask, mask2, ws); + curve.mul(new_x, U[i].get_x(), mask2, tmp); + curve.mul(new_y, U[i].get_y(), mask3, tmp); + curve.mul(new_z, U[i].get_z(), mask, tmp); + + U[i].swap_coords(new_x, new_y, new_z); + } + } - curve.mul(new_x, m_U[i].get_x(), mask2, ws); - curve.mul(new_y, m_U[i].get_y(), mask3, ws); - curve.mul(new_z, m_U[i].get_z(), mask, ws); + m_T.resize(U.size() * 3 * m_p_words); - m_U[i].swap_coords(new_x, new_y, new_z); + word* p = &m_T[0]; + for(size_t i = 0; i != U.size(); ++i) + { + U[i].get_x().encode_words(p , m_p_words); + U[i].get_y().encode_words(p + m_p_words, m_p_words); + U[i].get_z().encode_words(p + 2*m_p_words, m_p_words); + p += 3*m_p_words; } } @@ -227,17 +240,20 @@ PointGFp PointGFp_Var_Point_Precompute::mul(const BigInt& k, const BigInt scalar = k + group_order * mask; const size_t scalar_bits = scalar.bits(); + const size_t elem_size = 3*m_p_words; size_t windows = round_up(scalar_bits, m_window_bits) / m_window_bits; - PointGFp R = m_U[0]; + PointGFp R(m_curve); if(windows > 0) { windows--; - const uint32_t nibble = scalar.get_substring(windows*m_window_bits, m_window_bits); + // cache side channel here, we are relying on blinding... - R.add(m_U[nibble], ws); + const uint32_t nibble = scalar.get_substring(windows*m_window_bits, m_window_bits); + const word* w = &m_T[nibble * elem_size]; + R.add(w, m_p_words, w + m_p_words, m_p_words, w + 2*m_p_words, m_p_words, ws); /* Randomize after adding the first nibble as before the addition R @@ -245,16 +261,18 @@ PointGFp PointGFp_Var_Point_Precompute::mul(const BigInt& k, representation of the zero point. */ R.randomize_repr(rng); + } - while(windows) - { - R.mult2i(m_window_bits, ws); + while(windows) + { + R.mult2i(m_window_bits, ws); - const uint32_t inner_nibble = scalar.get_substring((windows-1)*m_window_bits, m_window_bits); - // cache side channel here, we are relying on blinding... - R.add(m_U[inner_nibble], ws); - windows--; - } + // cache side channel here, we are relying on blinding... + const uint32_t nibble = scalar.get_substring((windows-1)*m_window_bits, m_window_bits); + const word* w = &m_T[nibble * elem_size]; + R.add(w, m_p_words, w + m_p_words, m_p_words, w + 2*m_p_words, m_p_words, ws); + + windows--; } BOTAN_DEBUG_ASSERT(R.on_the_curve()); diff --git a/src/lib/pubkey/ec_group/point_mul.h b/src/lib/pubkey/ec_group/point_mul.h index a85c2bee9..dbaae2995 100644 --- a/src/lib/pubkey/ec_group/point_mul.h +++ b/src/lib/pubkey/ec_group/point_mul.h @@ -41,18 +41,26 @@ class PointGFp_Base_Point_Precompute final class PointGFp_Var_Point_Precompute final { public: - PointGFp_Var_Point_Precompute(const PointGFp& point); - - void randomize_repr(RandomNumberGenerator& rng, - std::vector<BigInt>& ws); + PointGFp_Var_Point_Precompute(const PointGFp& point, + RandomNumberGenerator& rng, + std::vector<BigInt>& ws); PointGFp mul(const BigInt& k, RandomNumberGenerator& rng, const BigInt& group_order, std::vector<BigInt>& ws) const; private: - size_t m_window_bits; - std::vector<PointGFp> m_U; + const CurveGFp m_curve; + const size_t m_p_words; + const size_t m_window_bits; + + /* + * Table of 2^window_bits * 3*2*p_word words + * Kept in locked vector since the base point might be sensitive + * (normally isn't in most protocols but hard to say anything + * categorically.) + */ + secure_vector<word> m_T; }; class PointGFp_Multi_Point_Precompute final diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp index e3553d5b3..587cad44f 100644 --- a/src/lib/pubkey/sm2/sm2_enc.cpp +++ b/src/lib/pubkey/sm2/sm2_enc.cpp @@ -46,10 +46,13 @@ namespace { class SM2_Encryption_Operation final : public PK_Ops::Encryption { public: - SM2_Encryption_Operation(const SM2_Encryption_PublicKey& key, const std::string& kdf_hash) : + SM2_Encryption_Operation(const SM2_Encryption_PublicKey& key, + RandomNumberGenerator& rng, + const std::string& kdf_hash) : m_group(key.domain()), - m_mul_public_point(key.public_point()), - m_kdf_hash(kdf_hash) + m_kdf_hash(kdf_hash), + m_ws(PointGFp::WORKSPACE_SIZE), + m_mul_public_point(key.public_point(), rng, m_ws) {} size_t max_input_bits() const override @@ -114,9 +117,10 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption private: const EC_Group m_group; - PointGFp_Var_Point_Precompute m_mul_public_point; const std::string m_kdf_hash; + std::vector<BigInt> m_ws; + PointGFp_Var_Point_Precompute m_mul_public_point; }; class SM2_Decryption_Operation final : public PK_Ops::Decryption @@ -213,14 +217,14 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption } std::unique_ptr<PK_Ops::Encryption> -SM2_Encryption_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/, +SM2_Encryption_PublicKey::create_encryption_op(RandomNumberGenerator& rng, const std::string& params, const std::string& provider) const { if(provider == "base" || provider.empty()) { const std::string kdf_hash = (params.empty() ? "SM3" : params); - return std::unique_ptr<PK_Ops::Encryption>(new SM2_Encryption_Operation(*this, kdf_hash)); + return std::unique_ptr<PK_Ops::Encryption>(new SM2_Encryption_Operation(*this, rng, kdf_hash)); } throw Provider_Not_Found(algo_name(), provider); |