Beispiel #1
0
PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1,
                            const PointGFp& p2, const BigInt& z2)
   {
   const PointGFp p3 = p1 + p2;

   PointGFp H(p1.curve); // create as zero
   size_t bits_left = std::max(z1.bits(), z2.bits());

   std::vector<BigInt> ws(9);

   while(bits_left)
      {
      H.mult2(ws);

      const bool z1_b = z1.get_bit(bits_left - 1);
      const bool z2_b = z2.get_bit(bits_left - 1);

      if(z1_b == true && z2_b == true)
         H.add(p3, ws);
      else if(z1_b)
         H.add(p1, ws);
      else if(z2_b)
         H.add(p2, ws);

      --bits_left;
      }

   if(z1.is_negative() != z2.is_negative())
      H.negate();

   return H;
   }
Beispiel #2
0
PointGFp multi_exponentiate(const PointGFp& x, const BigInt& z1,
                            const PointGFp& y, const BigInt& z2)
   {
   const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2);

   std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE);

   PointGFp x2 = x;
   x2.mult2(ws);

   const PointGFp x3(x2.plus(x, ws));

   PointGFp y2 = y;
   y2.mult2(ws);

   const PointGFp y3(y2.plus(y, ws));

   const PointGFp M[16] = {
      x.zero(),        // 0000
      x,               // 0001
      x2,              // 0010
      x3,              // 0011
      y,               // 0100
      y.plus(x, ws),   // 0101
      y.plus(x2, ws),  // 0110
      y.plus(x3, ws),  // 0111
      y2,              // 1000
      y2.plus(x, ws),  // 1001
      y2.plus(x2, ws), // 1010
      y2.plus(x3, ws), // 1011
      y3,              // 1100
      y3.plus(x, ws),  // 1101
      y3.plus(x2, ws), // 1110
      y3.plus(x3, ws), // 1111
   };

   PointGFp H = x.zero();

   for(size_t i = 0; i != z_bits; i += 2)
      {
      if(i > 0)
         {
         H.mult2(ws);
         H.mult2(ws);
         }

      const uint8_t z1_b = z1.get_substring(z_bits - i - 2, 2);
      const uint8_t z2_b = z2.get_substring(z_bits - i - 2, 2);

      const uint8_t z12 = (4*z2_b) + z1_b;

      H.add(M[z12], ws);
      }

   if(z1.is_negative() != z2.is_negative())
      H.negate();

   return H;
   }
Beispiel #3
0
BigInt Montgomery_Exponentation_State::exponentiation(const BigInt& scalar) const
   {
   const size_t exp_nibbles = (scalar.bits() + m_window_bits - 1) / m_window_bits;

   Montgomery_Int x(m_params, m_params->R1(), false);

   secure_vector<word> e_bits(m_params->p_words());
   secure_vector<word> ws;

   for(size_t i = exp_nibbles; i > 0; --i)
      {
      for(size_t j = 0; j != m_window_bits; ++j)
         {
         x.square_this(ws);
         }

      const uint32_t nibble = scalar.get_substring(m_window_bits*(i-1), m_window_bits);

      const_time_lookup(e_bits, m_g, nibble);

      x.mul_by(e_bits, ws);
      }

   return x.value();
   }
Beispiel #4
0
PointGFp operator*(const BigInt& scalar, const PointGFp& point)
   {
   //BOTAN_ASSERT(point.on_the_curve(), "Input is on the curve");

   const CurveGFp& curve = point.get_curve();

   const size_t scalar_bits = scalar.bits();

   std::vector<BigInt> ws(9);

   PointGFp R[2] = { PointGFp(curve), point };

   for(size_t i = scalar_bits; i > 0; i--)
      {
      const size_t b = scalar.get_bit(i - 1);
      R[b ^ 1].add(R[b], ws);
      R[b].mult2(ws);
      }

   if(scalar.is_negative())
      R[0].negate();

   //BOTAN_ASSERT(R[0].on_the_curve(), "Output is on the curve");

   return R[0];
   }
Beispiel #5
0
/*
* Division Operator
*/
BigInt operator/(const BigInt& x, const BigInt& y)
   {
   if(y.sig_words() == 1 && is_power_of_2(y.word_at(0)))
      return (x >> (y.bits() - 1));

   BigInt q, r;
   divide(x, y, q, r);
   return q;
   }
Beispiel #6
0
/*
* Generate a random integer within given range
*/
BigInt BigInt::random_integer(RandomNumberGenerator& rng,
                              const BigInt& min, const BigInt& max)
   {
   BigInt range = max - min;

   if(range <= 0)
      throw Invalid_Argument("random_integer: invalid min/max values");

   return (min + (BigInt(rng, range.bits() + 2) % range));
   }
Beispiel #7
0
/*
* Set the base
*/
void Fixed_Window_Exponentiator::set_base(const BigInt& base)
   {
   m_window_bits = Power_Mod::window_bits(m_exp.bits(), base.bits(), m_hints);

   m_g.resize(1U << m_window_bits);
   m_g[0] = 1;
   m_g[1] = base;

   for(size_t i = 2; i != m_g.size(); ++i)
      m_g[i] = m_reducer.multiply(m_g[i-1], m_g[1]);
   }
Beispiel #8
0
/*************************************************
* IF_Core Constructor                            *
*************************************************/
IF_Core::IF_Core(RandomNumberGenerator& rng,
                 const BigInt& e, const BigInt& n, const BigInt& d,
                 const BigInt& p, const BigInt& q,
                 const BigInt& d1, const BigInt& d2, const BigInt& c)
   {
   op = Engine_Core::if_op(e, n, d, p, q, d1, d2, c);

   if(BLINDING_BITS)
      {
      BigInt k(rng, std::min(n.bits()-1, BLINDING_BITS));
      blinder = Blinder(power_mod(k, e, n), inverse_mod(k, n), n);
      }
   }
Beispiel #9
0
/*
* Generate a random integer within given range
*/
BigInt BigInt::random_integer(RandomNumberGenerator& rng,
                              const BigInt& min, const BigInt& max)
   {
   BigInt r;

   const size_t bits = max.bits();

   do
      {
      r.randomize(rng, bits, false);
      }
   while(r < min || r >= max);

   return r;
   }
Beispiel #10
0
u64bit encrypt_number(u64bit cc_number, int length,
                         const std::string& key_str,
                         const std::string& tweak){
	BigInt n = 1;
	for(int j=0; j<length; ++j){
		n = n * 10;
	}	
	u64bit cc_ranked = cc_rank(cc_number);
	SymmetricKey key = sha1(key_str);
	BigInt c = FPE::fe1_encrypt(n, cc_ranked, key, sha1(tweak));
	if(c.bits() > 50)
	  throw std::runtime_error("FPE produced a number too large");
	u64bit enc_cc = 0;
	for(u32bit i = 0; i != 7; ++i)
	  enc_cc = (enc_cc << 8) | c.byte_at(6-i);
	return cc_derank(enc_cc);
}
Beispiel #11
0
BigInt Montgomery_Exponentation_State::exponentiation(const BigInt& k) const
   {
   const size_t exp_nibbles = (k.bits() + m_window_bits - 1) / m_window_bits;

   BigInt x = m_R_mod;

   const size_t z_size = 2*(m_p_words + 1);

   BigInt z(BigInt::Positive, z_size);
   secure_vector<word> workspace(z.size());
   secure_vector<word> e(m_p_words);

   for(size_t i = exp_nibbles; i > 0; --i)
      {
      for(size_t j = 0; j != m_window_bits; ++j)
         {
         bigint_monty_sqr(z, x, m_p.data(), m_p_words, m_mod_prime,
                          workspace.data());

         x = z;
         }

      const uint32_t nibble = k.get_substring(m_window_bits*(i-1), m_window_bits);

      BigInt::const_time_lookup(e, m_g, nibble);

      bigint_mul(z.mutable_data(), z.size(),
                 x.data(), x.size(), x.sig_words(),
                 e.data(), m_p_words, m_p_words,
                 workspace.data());

      bigint_monty_redc(z.mutable_data(),
                        m_p.data(), m_p_words, m_mod_prime,
                        workspace.data());

      x = z;
      }

   x.grow_to(2*m_p_words + 1);

   bigint_monty_redc(x.mutable_data(),
                     m_p.data(), m_p_words, m_mod_prime,
                     workspace.data());

   return x;
   }
Beispiel #12
0
Blinder::Blinder(const BigInt& modulus,
                 RandomNumberGenerator& rng,
                 std::function<BigInt (const BigInt&)> fwd,
                 std::function<BigInt (const BigInt&)> inv) :
      m_reducer(modulus),
      m_rng(rng),
      m_fwd_fn(fwd),
      m_inv_fn(inv),
      m_modulus_bits(modulus.bits()),
      m_e{},
      m_d{},
      m_counter{}
   {
   const BigInt k = blinding_nonce();
   m_e = m_fwd_fn(k);
   m_d = m_inv_fn(k);
   }
Beispiel #13
0
Blinder::Blinder(const BigInt& modulus,
                 std::function<BigInt (const BigInt&)> fwd_func,
                 std::function<BigInt (const BigInt&)> inv_func)
   {
   m_reducer = Modular_Reducer(modulus);

#if defined(BOTAN_HAS_SYSTEM_RNG)
   auto& rng = system_rng();
#else
   AutoSeeded_RNG rng;
#endif

   const BigInt k(rng, modulus.bits() - 1);

   m_e = fwd_func(k);
   m_d = inv_func(k);
   }
Beispiel #14
0
PointGFp operator*(const BigInt& scalar, const PointGFp& point)
   {
   //BOTAN_ASSERT(point.on_the_curve(), "Input is on the curve");

   const CurveGFp& curve = point.get_curve();

   const size_t scalar_bits = scalar.bits();

   std::vector<BigInt> ws(9);

   if(scalar_bits <= 2)
      {
      const byte abs_val = scalar.byte_at(0);

      if(abs_val == 0)
         return PointGFp::zero_of(curve);

      PointGFp result = point;

      if(abs_val == 2)
         result.mult2(ws);

      if(scalar.is_negative())
         result.negate();

      return result;
      }

   PointGFp R[2] = { PointGFp(curve), point };

   for(size_t i = scalar_bits; i > 0; i--)
      {
      const size_t b = scalar.get_bit(i - 1);
      R[b ^ 1].add(R[b], ws);
      R[b].mult2(ws);
      }

   if(scalar.is_negative())
      R[0].negate();

   //BOTAN_ASSERT(R[0].on_the_curve(), "Output is on the curve");

   return R[0];
   }
Beispiel #15
0
/*
* Set the base
*/
void Montgomery_Exponentiator::set_base(const BigInt& base)
   {
   m_window_bits = Power_Mod::window_bits(m_exp.bits(), base.bits(), m_hints);

   m_g.resize((1 << m_window_bits));

   BigInt z(BigInt::Positive, 2 * (m_mod_words + 1));
   secure_vector<word> workspace(z.size());

   m_g[0] = 1;

   bigint_monty_mul(z, m_g[0], m_R2_mod,
                    m_modulus.data(), m_mod_words, m_mod_prime,
                    workspace.data());
   m_g[0] = z;

   m_g[1] = (base >= m_modulus) ? (base % m_modulus) : base;

   bigint_monty_mul(z, m_g[1], m_R2_mod,
                    m_modulus.data(), m_mod_words, m_mod_prime,
                    workspace.data());

   m_g[1] = z;

   const BigInt& x = m_g[1];

   for(size_t i = 2; i != m_g.size(); ++i)
      {
      const BigInt& y = m_g[i-1];

      bigint_monty_mul(z, x, y, m_modulus.data(), m_mod_words, m_mod_prime,
                       workspace.data());

      m_g[i] = z;
      }
   }
Beispiel #16
0
PointGFp operator*(const BigInt& scalar, const PointGFp& point)
   {
   const CurveGFp& curve = point.get_curve();

   if(scalar.is_zero())
      return PointGFp(curve); // zero point

   std::vector<BigInt> ws(9);

   if(scalar.abs() <= 2) // special cases for small values
      {
      byte value = scalar.abs().byte_at(0);

      PointGFp result = point;

      if(value == 2)
         result.mult2(ws);

      if(scalar.is_negative())
         result.negate();

      return result;
      }

   const size_t scalar_bits = scalar.bits();

#if 0

   PointGFp x1 = PointGFp(curve);
   PointGFp x2 = point;

   size_t bits_left = scalar_bits;

   // Montgomery Ladder
   while(bits_left)
      {
      const bool bit_set = scalar.get_bit(bits_left - 1);

      if(bit_set)
         {
         x1.add(x2, ws);
         x2.mult2(ws);
         }
      else
         {
         x2.add(x1, ws);
         x1.mult2(ws);
         }

      --bits_left;
      }

   if(scalar.is_negative())
      x1.negate();

   return x1;

#else
   const size_t window_size = 4;

   std::vector<PointGFp> Ps(1 << window_size);
   Ps[0] = PointGFp(curve);
   Ps[1] = point;

   for(size_t i = 2; i != Ps.size(); ++i)
      {
      Ps[i] = Ps[i-1];
      Ps[i].add(point, ws);
      }

   PointGFp H(curve); // create as zero
   size_t bits_left = scalar_bits;

   while(bits_left >= window_size)
      {
      for(size_t i = 0; i != window_size; ++i)
         H.mult2(ws);

      const u32bit nibble = scalar.get_substring(bits_left - window_size,
                                                 window_size);

      H.add(Ps[nibble], ws);

      bits_left -= window_size;
      }

   while(bits_left)
      {
      H.mult2(ws);
      if(scalar.get_bit(bits_left-1))
         H.add(point, ws);

      --bits_left;
      }

   if(scalar.is_negative())
      H.negate();

   return H;
#endif
   }
Beispiel #17
0
BigInt monty_multi_exp(std::shared_ptr<const Montgomery_Params> params_p,
                       const BigInt& x_bn,
                       const BigInt& z1,
                       const BigInt& y_bn,
                       const BigInt& z2)
   {
   if(z1.is_negative() || z2.is_negative())
      throw Invalid_Argument("multi_exponentiate exponents must be positive");

   const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2);

   secure_vector<word> ws;

   const Montgomery_Int one(params_p, params_p->R1(), false);
   //const Montgomery_Int one(params_p, 1);

   const Montgomery_Int x1(params_p, x_bn);
   const Montgomery_Int x2 = x1.square(ws);
   const Montgomery_Int x3 = x2.mul(x1, ws);

   const Montgomery_Int y1(params_p, y_bn);
   const Montgomery_Int y2 = y1.square(ws);
   const Montgomery_Int y3 = y2.mul(y1, ws);

   const Montgomery_Int y1x1 = y1.mul(x1, ws);
   const Montgomery_Int y1x2 = y1.mul(x2, ws);
   const Montgomery_Int y1x3 = y1.mul(x3, ws);

   const Montgomery_Int y2x1 = y2.mul(x1, ws);
   const Montgomery_Int y2x2 = y2.mul(x2, ws);
   const Montgomery_Int y2x3 = y2.mul(x3, ws);

   const Montgomery_Int y3x1 = y3.mul(x1, ws);
   const Montgomery_Int y3x2 = y3.mul(x2, ws);
   const Montgomery_Int y3x3 = y3.mul(x3, ws);

   const Montgomery_Int* M[16] = {
      &one,
      &x1,                    // 0001
      &x2,                    // 0010
      &x3,                    // 0011
      &y1,                    // 0100
      &y1x1,
      &y1x2,
      &y1x3,
      &y2,                    // 1000
      &y2x1,
      &y2x2,
      &y2x3,
      &y3,                    // 1100
      &y3x1,
      &y3x2,
      &y3x3
   };

   Montgomery_Int H = one;

   for(size_t i = 0; i != z_bits; i += 2)
      {
      if(i > 0)
         {
         H.square_this(ws);
         H.square_this(ws);
         }

      const uint8_t z1_b = z1.get_substring(z_bits - i - 2, 2);
      const uint8_t z2_b = z2.get_substring(z_bits - i - 2, 2);

      const uint8_t z12 = (4*z2_b) + z1_b;

      H.mul_by(*M[z12], ws);
      }

   return H.value();
   }
Beispiel #18
0
PointGFp Blinded_Point_Multiply::blinded_multiply(const BigInt& scalar_in,
                                                  RandomNumberGenerator& rng)
   {
   if(scalar_in.is_negative())
      throw std::invalid_argument("Blinded_Point_Multiply scalar must be positive");

#if BOTAN_POINTGFP_SCALAR_BLINDING_BITS > 0
   // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure)
   const BigInt mask(rng, BOTAN_POINTGFP_SCALAR_BLINDING_BITS, false);
   const BigInt scalar = scalar_in + m_order * mask;
#else
   const BigInt& scalar = scalar_in;
#endif

   const size_t scalar_bits = scalar.bits();

   // Randomize each point representation (Coron's 3rd countermeasure)
   for(size_t i = 0; i != m_U.size(); ++i)
      m_U[i].randomize_repr(rng);

#if BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER
   PointGFp R = m_U.at(3*m_h + 2); // base point
   int32_t alpha = 0;

   R.randomize_repr(rng);

   /*
   Algorithm 7 from "Randomizing the Montgomery Powering Ladder"
   Duc-Phong Le, Chik How Tan and Michael Tunstall
   http://eprint.iacr.org/2015/657

   It takes a random walk through (a subset of) the set of addition
   chains that end in k.
   */
   for(size_t i = scalar_bits; i > 0; i--)
      {
      const int32_t ki = scalar.get_bit(i);

      // choose gamma from -h,...,h
      const int32_t gamma = static_cast<int32_t>((rng.next_byte() % (2*m_h))) - m_h;
      const int32_t l = gamma - 2*alpha + ki - (ki ^ 1);

      R.mult2(m_ws);
      R.add(m_U.at(3*m_h + 1 + l), m_ws);
      alpha = gamma;
      }

   const int32_t k0 = scalar.get_bit(0);
   R.add(m_U[3*m_h + 1 - alpha - (k0 ^ 1)], m_ws);

#else

   // N-bit windowing exponentiation:

   size_t windows = round_up(scalar_bits, m_h) / m_h;

   PointGFp R = m_U[0];

   if(windows > 0)
      {
      windows--;
      const u32bit nibble = scalar.get_substring(windows*m_h, m_h);
      R.add(m_U[nibble], m_ws);

      /*
      Randomize after adding the first nibble as before the addition R
      is zero, and we cannot effectively randomize the point
      representation of the zero point.
      */
      R.randomize_repr(rng);

      while(windows)
         {
         for(size_t i = 0; i != m_h; ++i)
            R.mult2(m_ws);

         const u32bit nibble = scalar.get_substring((windows-1)*m_h, m_h);
         R.add(m_U[nibble], m_ws);
         windows--;
         }
      }
#endif

   //BOTAN_ASSERT(R.on_the_curve(), "Output is on the curve");

   return R;
   }
Beispiel #19
0
/*
* Create a new Client Key Exchange message
*/
Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
                                         Handshake_State& state,
                                         const Policy& policy,
                                         Credentials_Manager& creds,
                                         const Public_Key* server_public_key,
                                         const std::string& hostname,
                                         RandomNumberGenerator& rng)
   {
   const std::string kex_algo = state.ciphersuite().kex_algo();

   if(kex_algo == "PSK")
      {
      std::string identity_hint = "";

      if(state.server_kex())
         {
         TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
         identity_hint = reader.get_string(2, 0, 65535);
         }

      const std::string psk_identity = creds.psk_identity("tls-client",
                                                          hostname,
                                                          identity_hint);

      append_tls_length_value(m_key_material, psk_identity, 2);

      SymmetricKey psk = creds.psk("tls-client", hostname, psk_identity);

      std::vector<byte> zeros(psk.length());

      append_tls_length_value(m_pre_master, zeros, 2);
      append_tls_length_value(m_pre_master, psk.bits_of(), 2);
      }
   else if(state.server_kex())
      {
      TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());

      SymmetricKey psk;

      if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
         {
         std::string identity_hint = reader.get_string(2, 0, 65535);

         const std::string psk_identity = creds.psk_identity("tls-client",
                                                             hostname,
                                                             identity_hint);

         append_tls_length_value(m_key_material, psk_identity, 2);

         psk = creds.psk("tls-client", hostname, psk_identity);
         }

      if(kex_algo == "DH" || kex_algo == "DHE_PSK")
         {
         BigInt p = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
         BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
         BigInt Y = BigInt::decode(reader.get_range<byte>(2, 1, 65535));

         if(reader.remaining_bytes())
            throw Decoding_Error("Bad params size for DH key exchange");

         if(p.bits() < policy.minimum_dh_group_size())
            throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
                                "Server sent DH group of " +
                                std::to_string(p.bits()) +
                                " bits, policy requires at least " +
                                std::to_string(policy.minimum_dh_group_size()));

         /*
         * A basic check for key validity. As we do not know q here we
         * cannot check that Y is in the right subgroup. However since
         * our key is ephemeral there does not seem to be any
         * advantage to bogus keys anyway.
         */
         if(Y <= 1 || Y >= p - 1)
            throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
                                "Server sent bad DH key for DHE exchange");

         DL_Group group(p, g);

         if(!group.verify_group(rng, false))
            throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
                                "DH group validation failed");

         DH_PublicKey counterparty_key(group, Y);

         DH_PrivateKey priv_key(rng, group);

         PK_Key_Agreement ka(priv_key, "Raw");

         secure_vector<byte> dh_secret = CT::strip_leading_zeros(
            ka.derive_key(0, counterparty_key.public_value()).bits_of());

         if(kex_algo == "DH")
            m_pre_master = dh_secret;
         else
            {
            append_tls_length_value(m_pre_master, dh_secret, 2);
            append_tls_length_value(m_pre_master, psk.bits_of(), 2);
            }

         append_tls_length_value(m_key_material, priv_key.public_value(), 2);
         }
      else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
         {
         const byte curve_type = reader.get_byte();

         if(curve_type != 3)
            throw Decoding_Error("Server sent non-named ECC curve");

         const u16bit curve_id = reader.get_u16bit();

         const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id);

         if(name == "")
            throw Decoding_Error("Server sent unknown named curve " + std::to_string(curve_id));

         EC_Group group(name);

         std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255);

         ECDH_PublicKey counterparty_key(group, OS2ECP(ecdh_key, group.get_curve()));

         ECDH_PrivateKey priv_key(rng, group);

         PK_Key_Agreement ka(priv_key, "Raw");

         secure_vector<byte> ecdh_secret =
            ka.derive_key(0, counterparty_key.public_value()).bits_of();

         if(kex_algo == "ECDH")
            m_pre_master = ecdh_secret;
         else
            {
            append_tls_length_value(m_pre_master, ecdh_secret, 2);
            append_tls_length_value(m_pre_master, psk.bits_of(), 2);
            }

         append_tls_length_value(m_key_material, priv_key.public_value(), 1);
         }
#if defined(BOTAN_HAS_SRP6)
      else if(kex_algo == "SRP_SHA")
         {
         const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
         const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
         std::vector<byte> salt = reader.get_range<byte>(1, 1, 255);
         const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535));

         const std::string srp_group = srp6_group_identifier(N, g);

         const std::string srp_identifier =
            creds.srp_identifier("tls-client", hostname);

         const std::string srp_password =
            creds.srp_password("tls-client", hostname, srp_identifier);

         std::pair<BigInt, SymmetricKey> srp_vals =
            srp6_client_agree(srp_identifier,
                              srp_password,
                              srp_group,
                              "SHA-1",
                              salt,
                              B,
                              rng);

         append_tls_length_value(m_key_material, BigInt::encode(srp_vals.first), 2);
         m_pre_master = srp_vals.second.bits_of();
         }
#endif
      else
         {
         throw Internal_Error("Client_Key_Exchange: Unknown kex " +
                              kex_algo);
         }

      reader.assert_done();
      }
   else
      {
      // No server key exchange msg better mean RSA kex + RSA key in cert

      if(kex_algo != "RSA")
         throw Unexpected_Message("No server kex but negotiated kex " + kex_algo);

      if(!server_public_key)
         throw Internal_Error("No server public key for RSA exchange");

      if(auto rsa_pub = dynamic_cast<const RSA_PublicKey*>(server_public_key))
         {
         const Protocol_Version offered_version = state.client_hello()->version();

         m_pre_master = rng.random_vec(48);
         m_pre_master[0] = offered_version.major_version();
         m_pre_master[1] = offered_version.minor_version();

         PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15");

         const std::vector<byte> encrypted_key = encryptor.encrypt(m_pre_master, rng);

         append_tls_length_value(m_key_material, encrypted_key, 2);
         }
      else
         throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
                             "Expected a RSA key in server cert but got " +
                             server_public_key->algo_name());
      }

   state.hash().update(io.send(*this));
   }
Beispiel #20
0
/*
* Set the exponent
*/
void Montgomery_Exponentiator::set_exponent(const BigInt& exp)
   {
   m_exp = exp;
   m_exp_bits = exp.bits();
   }
Beispiel #21
0
// Botan is released under the Simplified BSD License (see license.txt)

#include "catchy_tests.h"

#if defined(BOTAN_HAS_BIGINT)

#include <botan/bigint.h>

using namespace Botan;

TEST_CASE("Bigint basics", "[bigint]")
   {
   SECTION("in 0-bit border")
      {
      BigInt a(0u);
      CHECK_THAT(a.bits(),      Equals(0));
      CHECK_THAT(a.bytes(),     Equals(0));
      CHECK_THAT(a.to_u32bit(), Equals(0));
      }
   SECTION("above 0-bit border")
      {
      BigInt a(1u);
      CHECK_THAT(a.bits(),      Equals(1));
      CHECK_THAT(a.bytes(),     Equals(1));
      CHECK_THAT(a.to_u32bit(), Equals(1));
      }
   SECTION("in 8-bit border")
      {
      BigInt a(255u);
      CHECK_THAT(a.bits(),      Equals(8));
      CHECK_THAT(a.bytes(),     Equals(1));
Beispiel #22
0
void Montgomery_Exponentiator::set_base(const BigInt& base)
   {
   size_t window_bits = Power_Mod::window_bits(m_e.bits(), base.bits(), m_hints);
   m_monty = monty_precompute(m_monty_params, base, window_bits);
   }