Ejemplo n.º 1
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;
   }
Ejemplo n.º 2
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;
   }