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

📄 fipsprime.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
字号:
/* Copyright 2003-2004, Voltage Security, all rights reserved.
 */

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

int VoltGeneratePrimeFips (
   unsigned int primeSizeBits,
   VtRandomObject random,
   unsigned char *SEED,
   unsigned int *seedLen,
   VoltMpInt *prime
   )
{
  int status, count;
  unsigned int bufferSize, digestLen, index, limit;
  unsigned int bitMask, bitSet, isPrime;
  VoltMpIntCtx *mpCtx = (VoltMpIntCtx *)(prime->mpCtx);
  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.
   */
  bufferSize = (primeSizeBits + 7) / 8;
  *seedLen = bufferSize;

  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_FIPS;
    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 (bufferSize, VOLT_MEMORY_SENSITIVE);
    if (buffer == (unsigned char *)0)
      break;

    /* Create a mask for the first byte. Depending on the bit length,
     * we may want to trim some bits off the top.
     */
    bitSet = primeSizeBits % 8;
    if (bitSet == 0)
      bitSet = 8;
    bitMask = 0xff >> (8 - bitSet);
    /* Make sure the msbit is set. Create a value to OR with the first
     * byte that will set the msbit.
     */
    bitSet = 1 << (bitSet - 1);

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

    count = 0;
    isPrime = 1;
    do
    {
      /* Step 1: "Choose an arbitrary sequence ... call it SEED."
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGenerateRandomBytes (random, SEED, bufferSize); 
      if (status != 0)
        break;

      /* Step 2: Compute U.
       */
      Z2Memcpy (buffer, SEED, bufferSize);

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

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

      /* Add 1 to SEED (don't carry beyond the most significant byte).
       */
      for (index = bufferSize; index > 0; --index)
      {
        buffer[index - 1] += 1;
        if (buffer[index - 1] != 0)
          break;
      }

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

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtDigestFinal (
        sha1, buffer, bufferSize, digest + digestLen,
        sizeof (digest) - digestLen, &digestLen);
      if (status != 0)
        break;

      /* XOR the two digests.
       */
      limit = digestLen;
      if (digestLen > bufferSize)
        limit = bufferSize;
      for (index = 0; index < limit; ++index)
        buffer[index] = digest[index] ^ digest[index + digestLen];

      /* Step 3: Form q.
       */
      buffer[0] &= (unsigned char)bitMask;
      buffer[0] |= (unsigned char)bitSet;
      buffer[bufferSize - 1] |= 1;

      /* Set the MpInt to this value.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->OctetStringToMpInt (0, buffer, bufferSize, prime);
      if (status != 0)
        break;

      /* Step 4: Run Rabin-Miller on this value.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltRabinMillerTest (prime, primeSizeBits, 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);

  VtDestroyAlgorithmObject (&sha1);
  Z2Memset (digest, 0, sizeof (digest));
  if (buffer != (unsigned char *)0)
    Z2Free (buffer);

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

  return (status);
}

⌨️ 快捷键说明

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