📄 gmpwrap.c
字号:
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Check the arguments.
* If NULL, can't log, no libCtx.
*/
if (theInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
VOLT_SET_FNCT_LINE (fnctLine)
if (bitLen != (unsigned int *)0)
{
/* How big is the integer?
*/
*bitLen = (unsigned int)mpz_sizeinbase ((mpz_ptr)(theInt->mpInt), 2);
return (0);
}
VOLT_LOG_ERROR (
theInt->mpCtx->voltObject.libraryCtx, VT_ERROR_NULL_ARG,
VT_ERROR_TYPE_PRIMARY, fnctLine, "GMPWrapGetBitLength", (char *)0)
return (VT_ERROR_NULL_ARG);
}
int GMPWrapSetBit (
VoltMpInt *theInt,
unsigned int bitIndex,
unsigned int value
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
*/
if (theInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
if (value != 0)
{
mpz_setbit ((mpz_ptr)(theInt->mpInt), bitIndex);
return (0);
}
mpz_clrbit ((mpz_ptr)(theInt->mpInt), bitIndex);
return (0);
}
int GMPWrapGetBit (
VoltMpInt *theInt,
unsigned int bitIndex,
unsigned int *value
)
{
int status;
unsigned int bitLen;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Check the arguments.
* If NULL, can't log, no libCtx.
*/
if (theInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
do
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if (value == (unsigned int *)0)
break;
status = 0;
/* How big is the integer?
*/
bitLen = (unsigned int)mpz_sizeinbase ((mpz_ptr)(theInt->mpInt), 2);
/* If the index requested is beyond the end, set the value to 0.
* We could return VT_ERROR_MP_INT_RANGE, but it is true that the
* bit is 0. (Think of the decimal number 3,142, it is 03,142).
*/
*value = 0;
if (bitIndex >= bitLen)
break;
*value = (unsigned int)mpz_tstbit ((mpz_ptr)(theInt->mpInt), bitIndex);
} while (0);
VOLT_LOG_ERROR_COMPARE (
status, theInt->mpCtx->voltObject.libraryCtx, status,
VT_ERROR_TYPE_PRIMARY, fnctLine, "GMPWrapGetBit", (char *)0)
return (status);
}
int GMPWrapShiftLeftBits (
VoltMpInt *theInt,
unsigned int shiftCount
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
*/
if (theInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
mpz_mul_2exp (
(mpz_ptr)(theInt->mpInt), (mpz_ptr)(theInt->mpInt), shiftCount);
return (0);
}
int GMPWrapShiftRightBits (
VoltMpInt *theInt,
unsigned int shiftCount
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
*/
if (theInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
mpz_tdiv_q_2exp (
(mpz_ptr)(theInt->mpInt), (mpz_ptr)(theInt->mpInt), shiftCount);
return (0);
}
int GMPWrapSubtract (
VoltMpInt *minuend,
VoltMpInt *subtrahend,
VoltMpInt *difference
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (minuend == (VoltMpInt *)0) ||
(subtrahend == (VoltMpInt *)0) ||
(difference == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
mpz_sub (
(mpz_ptr)(difference->mpInt), (mpz_ptr)(minuend->mpInt),
(mpz_ptr)(subtrahend->mpInt));
return (0);
}
int GMPWrapAdd (
VoltMpInt *addend1,
VoltMpInt *addend2,
VoltMpInt *sum
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (addend1 == (VoltMpInt *)0) ||
(addend2 == (VoltMpInt *)0) ||
(sum == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
mpz_add (
(mpz_ptr)(sum->mpInt), (mpz_ptr)(addend1->mpInt),
(mpz_ptr)(addend2->mpInt));
return (0);
}
int GMPWrapMultiply (
VoltMpInt *multiplicand,
VoltMpInt *multiplier,
VoltMpInt *product
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (multiplicand == (VoltMpInt *)0) ||
(multiplier == (VoltMpInt *)0) ||
(product == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
mpz_mul (
(mpz_ptr)(product->mpInt), (mpz_ptr)(multiplicand->mpInt),
(mpz_ptr)(multiplier->mpInt));
return (0);
}
int GMPWrapSquare (
VoltMpInt *operand,
VoltMpInt *product
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (operand == (VoltMpInt *)0) ||
(product == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
mpz_mul (
(mpz_ptr)(product->mpInt), (mpz_ptr)(operand->mpInt),
(mpz_ptr)(operand->mpInt));
return (0);
}
int GMPWrapDivide (
VoltMpInt *dividend,
VoltMpInt *divisor,
VoltMpInt *quotient,
VoltMpInt *remainder
)
{
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (dividend == (VoltMpInt *)0) ||
(divisor == (VoltMpInt *)0) ||
(quotient == (VoltMpInt *)0) ||
(remainder == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
/* Can't divide by zero. So check to see that the divisor is not 0.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (mpz_sgn ((mpz_ptr)(divisor->mpInt)) != 0)
{
mpz_tdiv_qr (
(mpz_ptr)(quotient->mpInt), (mpz_ptr)(remainder->mpInt),
(mpz_ptr)(dividend->mpInt), (mpz_ptr)(divisor->mpInt));
return (0);
}
VOLT_LOG_ERROR (
divisor->mpCtx->voltObject.libraryCtx, VT_ERROR_DIVIDE_BY_ZERO,
VT_ERROR_TYPE_PRIMARY, fnctLine, "GMPWrapDivide", (char *)0)
return (VT_ERROR_DIVIDE_BY_ZERO);
}
int GMPWrapGCD (
VoltMpInt *operand1,
VoltMpInt *operand2,
VoltMpInt *result
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (operand1 == (VoltMpInt *)0) ||
(operand2 == (VoltMpInt *)0) ||
(result == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
mpz_gcd (
(mpz_ptr)(result->mpInt), (mpz_ptr)(operand1->mpInt),
(mpz_ptr)(operand2->mpInt));
return (0);
}
int GMPWrapModReduce (
VoltMpInt *operand,
VoltMpInt *modulus,
VoltMpInt *result
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (operand == (VoltMpInt *)0) ||
(modulus == (VoltMpInt *)0) ||
(result == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
mpz_mod (
(mpz_ptr)(result->mpInt), (mpz_ptr)(operand->mpInt),
(mpz_ptr)(modulus->mpInt));
return (0);
}
int GMPWrapModInvert (
VoltMpInt *operand,
VoltMpInt *modulus,
VoltMpInt *result
)
{
int gmpRes;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (operand == (VoltMpInt *)0) ||
(modulus == (VoltMpInt *)0) ||
(result == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
VOLT_SET_FNCT_LINE (fnctLine)
gmpRes = mpz_invert (
(mpz_ptr)(result->mpInt), (mpz_ptr)(operand->mpInt),
(mpz_ptr)(modulus->mpInt));
/* The GMP mod invert returns non-zero for success.
*/
if (gmpRes != 0)
return (0);
/* There is no inverse for the operand.
*/
VOLT_LOG_ERROR (
operand->mpCtx->voltObject.libraryCtx, VT_ERROR_NO_INVERSE,
VT_ERROR_TYPE_PRIMARY, fnctLine, "GMPWrapModInvert", (char *)0)
return (VT_ERROR_NO_INVERSE);
}
int GMPWrapModExp (
VoltMpInt *base,
VoltMpInt *exponent,
VoltMpInt *modulus,
VoltMpInt *result
)
{
/* Check the arguments.
* If NULL, can't log, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (base == (VoltMpInt *)0) ||
(exponent == (VoltMpInt *)0) ||
(modulus == (VoltMpInt *)0) ||
(result == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
mpz_powm (
(mpz_ptr)(result->mpInt), (mpz_ptr)(base->mpInt),
(mpz_ptr)(exponent->mpInt), (mpz_ptr)(modulus->mpInt));
return (0);
}
#ifdef _WINCE
#pragma optimize( "g", off )
#endif
int GMPWrapGeneratePrime (
unsigned int primeSizeBits,
VtRandomObject random,
unsigned char *SEED,
unsigned int bufferSize,
unsigned int *seedLen,
VoltMpInt *prime
)
{
int status;
unsigned int bitMask, bitSet;
unsigned char *buffer = (unsigned char *)0;
VoltMpIntCtx *mpCtx;
VoltLibCtx *libCtx;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Check the arguments.
* Can't log an error if NULL, no libCtx.
*/
if (prime == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
do
{
/* If a SEED buffer is given, the caller wants a FIPS-certified
* prime, this implementation does not do that, return the error.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_FIPS;
if (SEED != (unsigned char *)0)
break;
mpCtx = (VoltMpIntCtx *)(prime->mpCtx);
libCtx = (VoltLibCtx *)(mpCtx->voltObject.libraryCtx);
/* Create a buffer of the appropriate size. We'll fill it with
* random bytes and use that as a starting point.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
bufferSize = (primeSizeBits + 7) / 8;
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);
/* Generate random bytes of the appropriate bit length.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGenerateRandomBytes (random, buffer, bufferSize);
if (status != 0)
break;
/* Make sure the msbyte is set properly.
*/
buffer[0] &= (unsigned char)bitMask;
buffer[0] |= (unsigned char)bitSet;
/* Set the lsbit to guarantee it is odd.
*/
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;
/* The nextprime function will find the next prime after the
* starting point.
*/
mpz_nextprime ((mpz_ptr)(prime->mpInt), (mpz_ptr)(prime->mpInt));
} while (0);
if (buffer != (unsigned char *)0)
Z2Free (buffer);
VOLT_LOG_ERROR_COMPARE (
status, prime->mpCtx->voltObject.libraryCtx, status, errorType,
fnctLine, "GMPWrapGeneratePrime", (char *)0)
return (status);
}
#ifdef _WINCE
#pragma optimize( "g", on )
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -