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

📄 x942prime.c

📁 IBE是一种非对称密码技术
💻 C
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */

#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "mpint.h"
#include "prime.h"
#include "errorctx.h"

int VoltGeneratePrimeX942 (
   unsigned int primeSizeBits,
   VtRandomObject random,
   unsigned char *SEED,
   unsigned int *seedLen,
   VoltMpInt *prime
   )
{
  int status, count;
  unsigned int sLen, digestLen, index, mLimit, isPrime;
  VoltMpIntCtx *mpCtx = (VoltMpIntCtx *)(prime->mpCtx);
  VoltMpInt *temp = (VoltMpInt *)0;
  VoltMpInt *currentQ = (VoltMpInt *)0;
  VoltLibCtx *libCtx = (VoltLibCtx *)(mpCtx->voltObject.libraryCtx);
  VtAlgorithmObject sha1 = (VtAlgorithmObject)0;
  unsigned char *buffer = (unsigned char *)0;
  unsigned char digest[40];
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* How many bytes do we generate.
   */
  sLen = (primeSizeBits + 7) / 8;
  *seedLen = sLen;

  do
  {
    /* Currently, the toolkit is supporting only 160 bit primes to be
     * generated using the FIPS technique
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_PARAM_LENGTH;
    if (primeSizeBits != 160)
      break;

    /* Build a buffer to hold the starting point.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    buffer = (unsigned char *)Z2Malloc (sLen, VOLT_MEMORY_SENSITIVE);
    if (buffer == (unsigned char *)0)
      break;

    /* Build the SHA-1 digest object to be used in step 6 below.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtCreateAlgorithmObject (
      (VtLibCtx)libCtx, VtAlgorithmImplSHA1, (Pointer)0, &sha1);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->CreateMpInt ((Pointer)mpCtx, &temp);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->CreateMpInt ((Pointer)mpCtx, &currentQ);
    if (status != 0)
      break;

    count = 0;
    isPrime = 1;
    /* Step 1: this will tell us how many digest blocks we need to
     * produce.
     */
    mLimit = (primeSizeBits + 159) / 160;

    /* Steps 2 and 3 deal with generating a prime for which (p-1) is a
     * multiple of a subprime. This subroutine deals with generating
     * random primes. So skip steps 2 and 3 in this routine.
     */

    do
    {
      /* Step 4: "Select a seed ... "
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGenerateRandomBytes (random, SEED, sLen); 
      if (status != 0)
        break;

      /* Step 5: Set q to 0.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->IntToMpInt (0, 0, currentQ);
      if (status != 0)
        break;

      /* Step 6: For i = 0 to mLimit, generate blocks.
       */
      for (index = 0; index < mLimit; ++index)
      {
        /* Add i to seed.
         */
        Z2Memcpy (buffer, SEED, sLen);
        VoltAddValueToBuffer (buffer, sLen, (UInt32)index);

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

        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtDigestFinal (
          sha1, buffer, sLen, digest, 20, &digestLen);
        if (status != 0)
          break;

        /* Now compute seed + mLimit + i and digest that.
         */
        VoltAddValueToBuffer (buffer, sLen, (UInt32)mLimit);

        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtDigestInit (sha1);
        if (status != 0)
          break;

        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtDigestFinal (
          sha1, buffer, sLen, digest + 20, 20, &digestLen);
        if (status != 0)
          break;

        /* XOR the two digests.
         */
        for (digestLen = 0; digestLen < 20; ++digestLen)
          buffer[digestLen] = digest[digestLen] ^ digest[digestLen + 20];

        /* Add this to the current value we're building.
         */
        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->OctetStringToMpInt (0, buffer, sLen, temp);
        if (status != 0)
          break;

        /* We actually add 2^(160i).
         */
        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->ShiftLeftBits (temp, index * 160);
        if (status != 0)
          break;

        VOLT_SET_FNCT_LINE (fnctLine)
        status = mpCtx->Add (temp, currentQ, currentQ);
        if (status != 0)
          break;
      }
      if (status != 0)
        break;

      /* Step 7: q = q mod 2 ^ m, then make sure ms and ls bits are set.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->IntToMpInt (0, 1, temp);
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->ShiftLeftBits (temp, primeSizeBits);
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->ModReduce (currentQ, temp, prime);
      if (status != 0)
        break;

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

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

      /* Step 8: Run Rabin-Miller on this value. Run 50 iterations. We
       * can either run 50 iterations of Rabin-Miller, or 8 iterations
       * of Rabin-Miller with Lucas.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltRabinMillerTest (
        prime, primeSizeBits, 50, random, &isPrime);
      if (status != 0)
        break;

      /* If this came back prime, we're done.
       */
      if (isPrime != 0)
        break;

      /* Step 5: The Rabin-Miller test indicates that the number is not
       * prime, get a new random starting point. But first, don't run
       * this test forever.  Try up to 1000000 times.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_NO_PRIME_FOUND;
      count++;
      if (count > 1000000)
        break;

    } while (1);

  } while (0);

  mpCtx->DestroyMpInt (&temp);
  mpCtx->DestroyMpInt (&currentQ);
  VtDestroyAlgorithmObject (&sha1);
  Z2Memset (digest, 0, sizeof (digest));
  if (buffer != (unsigned char *)0)
    Z2Free (buffer);

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

  return (status);
}

⌨️ 快捷键说明

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