📄 x942prime.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, ¤tQ);
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 (¤tQ);
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 + -