⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsapgimpl.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
      }

      /* If the mpIntCtx did not have a GeneratePrime function, or if the
       * implementation did not do FIPS and FIPS was requested, then use
       * the regular toolkit technique.
       */
      if (status == VT_ERROR_FIPS)
      {
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VoltGeneratePrimeFips (
          subprimeSizeBits, random, SEED, seedLen, subprimeQ);
      }

      /* If status is not 0 at this point, give up.
       * Maybe the mpIntCtx GeneratePrime set status to something other
       * than 0 or ERROR_FIPS, or maybe the regular toolkit function set
       * it, it doesn't matter, it's an error now.
       */
      if (status != 0)
        break;

      /* Step 6: counter = 0, offset = 2
       */
      counter = 0;
      offset = 2;

      /* This is the beginning of the inner loop: find primeP based on
       * the given subprimeQ.
       */
      do
      {
        if (surrCtx != (VoltSurrenderCtx *)0)
        {
          surrCtx->surrenderInfo.callNumber++;
          VOLT_SET_FNCT_LINE (fnctLine)
          status = surrCtx->Surrender (
            surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
          if (status != 0)
            break;
        }

        /* Step 7: Build the primeP starting point by digesting SEED along
         * with the offset and a count as many times as necessary to
         * generate the appropriate number of bytes.
         */
        Z2Memcpy (seedCopy, SEED, *seedLen);
        totalLen = bufSize;
        kVal = 0;
        bufOffset = bufSize;

        AddValueToBuffer (seedCopy, *seedLen, offset - 1); 
        do
        {
          /* Compute SEED + offset + kVal.
           */
          AddValueToBuffer (seedCopy, *seedLen, 1); 
          kVal++;

          /* Digest this value.
           */
          VOLT_SET_FNCT_LINE (fnctLine)
          status = VtDigestInit (sha1);
          if (status != 0)
            break;

          VOLT_SET_FNCT_LINE (fnctLine)
          status = VtDigestFinal (
            sha1, seedCopy, *seedLen, digest, 20, &digestLen);
          if (status != 0)
            break;

          if (digestLen > totalLen)
            digestLen = totalLen;

          /* "Prepend" the current digest. This is the part of step 8
           * that builds W.
           */
          bufOffset -= digestLen;
          totalLen  -= digestLen;
          Z2Memcpy (buffer + bufOffset, digest + (20 - digestLen), digestLen);

        } while (totalLen > 0);
        if (status != 0)
          break;

        /* Finish step 8, compute X.
         */

        /* The FIPS technique actually specifies that W is a value of
         * length primeSizeBits - 1, so we need to clear the most
         * significant bit of the buffer to get the appropriate W. But
         * then we're going to add that bit in to get X, which is
         * W + (2 ^ (primeSizeBits - 1)). So at this point, just make
         * sure the most significant bit is set.
         */
        buffer[0] &= (unsigned char)bitMask;
        buffer[0] |= (unsigned char)bitSet;

        /* Step 9: c = X mod 2q, p = X - (c - 1)
         */
        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->OctetStringToMpInt (0, buffer, bufSize, primeP);
        if (status != 0)
          break;

        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->Add (subprimeQ, subprimeQ, expo);
        if (status != 0)
          break;

        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->ModReduce (primeP, expo, remainder);
        if (status != 0)
          break;

        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->Subtract (remainder, baseG, remainder);
        if (status != 0)
          break;

        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->Subtract (primeP, remainder, primeP);
        if (status != 0)
          break;

        /* Step 10: is primeP < 2 ^ (primeSizeBits - 1).
         * In other words, is the most significant bit still set?
         */
        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->GetBit (primeP, primeSizeBits - 1, &msbit);
        if (status == VT_ERROR_MP_INT_RANGE)
          status = 0;
        if (status != 0)
          break;

        /* Continuing Step 10, if the bit is set, move on to step 11.
         */
        if (msbit != 0)
        {
          /* Step 11: Is primeP actually prime?
           */
          VOLT_SET_FNCT_LINE (fnctLine)
          status = VoltRabinMillerTest (primeP, primeSizeBits, random, &isPrime);
          if (status != 0)
            break;

          /* Step 12: If the value is prime, move on to step 15.
           */
          if (isPrime != 0)
            break;
        }

        /* Step 13: The candidate "failed", either the msbit was not set
         * after the subtraction or it was not prime. Update counter and
         * offset.
         */
        counter++;
        offset += (nVal + 1);

        /* Step 14: If counter >= 4096, find a new subprimeQ.
         */
        if (counter >= 4096)
          break;

        /* Step 14: If counter < 4096, try another primeP.
         */

      } while (1);
      if (status != 0)
        break;

      /* At this point, we exited the inner loop because either we
       * found a prime or the counter hit 4096. If isPrime is not 0, we
       * found a prime.
       */
      if (isPrime != 0)
        break;

    } while (1);
    if (status != 0)
      break;

    /* If we reach this point, we have a subprimeQ and a primeP. The
     * SEED buffer contains the seed we used and counter is set to the
     * value we'll need to return at the address given by the count arg.
     */
    *count = counter;

    /* Now that we have p and q, compute g. It is
     *    g = h ^ ((p-1)/q)
     * where h is a random number.
     */

    /* Find (p-1) / q
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->MpIntToMpInt (primeP, expo);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->SetBit (expo, 0, 0);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Divide (expo, subprimeQ, expo, remainder);
    if (status != 0)
      break;

    /* Generate a random h < p.
     */
    do
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGenerateRandomBytes (random, buffer, bufSize);
      if (status != 0)
        break;
      buffer[0] = 2; 

      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->OctetStringToMpInt (0, buffer, /**/1/*/bufSize/*/, hVal); /* FIX */
      if (status != 0)
        break;

      /* compute g
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->ModExp (hVal, expo, primeP, baseG);
      if (status != 0)
        break;

      /* Make sure baseG is not a small number.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->MpIntToInt (baseG, 1, &msbit);
      /* If status is 0, the g computed fit into an unsigned int,
       * that's small, try again with new random material.
       */
      if (status == 0)
        continue;

      /* If status is VT_ERROR_MP_INT_RANGE, the number is big enough, we're
       * done. Make sure status is 0.
       * If status was some other error, pass it along.
       */
      if (status == VT_ERROR_MP_INT_RANGE)
        status = 0;

      break;
    } while (1);

  } while (0);

  if (callNumber != (unsigned int *)0)
    *callNumber = callNum;
  if (buffer != (unsigned char *)0)
    Z2Free (buffer);

  mpCtx->DestroyMpInt (&remainder);
  mpCtx->DestroyMpInt (&expo);
  VtDestroyAlgorithmObject (&sha1);

  VOLT_LOG_ERROR_COMPARE (
    status, (VtLibCtx)libCtx, status, errorType, fnctLine,
    "VoltGeneratePQG", (char *)0)

  return (status);
}

static void AddValueToBuffer (
   unsigned char *buffer,
   unsigned int bufferLen,
   UInt32 increment
   )
{
  unsigned int indexB, indexI;
  unsigned char carry, val;
  unsigned char vector[4];

  VOLT_SET_UINT32 (increment, vector)

  /* Add the four words of the increment to the low four words of the
   * buffer.
   */
  carry = 0;
  for (indexI = 4, indexB = bufferLen; indexI > 0; --indexI, --indexB)
  {
    val = carry + vector[indexI - 1];
    if (val >= carry)
      carry = 0;
    buffer[indexB - 1] += val;
    if (buffer[indexB - 1] < val)
      carry = 1;
  }

  /* If there's no carry, we're done.
   */
  if (carry == 0)
    return;

  /* Propagate the carry through the buffer (ignoring any carry beyond
   * the most significant byte.
   */
  for (; indexB > 0; --indexB)
  {
    buffer[indexB - 1] += 1;
    if (buffer[indexB - 1] != 0)
      break;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -