📄 pgpbignum.c
字号:
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( bn );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnAddQ( &dest->bn, sm ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/* dest = bn + sm, where 0 <= sm < 2^16 */
PGPError
PGPBigNumSubtractQ(
PGPBigNumRef bn,
PGPUInt16 sm,
PGPBigNumRef dest,
PGPBoolean * underflowPtr )
{
PGPError err = kPGPError_NoErr;
int bnError = 0;
PGPBoolean underflow = FALSE;
if ( IsntNull( underflowPtr ) )
*underflowPtr = FALSE;
pgpValidateBigNum( bn );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( bn != dest )
{
bnError = bnCopy( &dest->bn, &bn->bn );
if ( IsBNError( bnError ) )
err = kPGPError_OutOfMemory;
}
if ( IsntBNError( bnError ) )
{
bnError = bnSubQ( &dest->bn, sm );
if ( IsBNError( bnError ) )
{
underflow = TRUE;
}
}
if ( IsntNull( underflowPtr ) )
*underflowPtr = underflow;
return( err );
}
/* Return sign (-1, 0, +1) of a-b. a <=> b --> bnCmp(a, b) <=> 0 */
PGPInt32
PGPBigNumCompare(
PGPBigNumRef lhs,
PGPBigNumRef rhs )
{
pgpEnterZeroFunction();
if ( pgpBigNumIsValid( lhs ) && pgpBigNumIsValid( rhs ) )
{
return( bnCmp( &lhs->bn, &rhs->bn ) );
}
return( 0 );
}
/* dest = src * src. dest may be the same as src, but it costs time. */
PGPError
PGPBigNumSquare(
PGPBigNumRef src,
PGPBigNumRef dest)
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( src );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnSquare( &dest->bn, &src->bn ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/* dest = a * b. dest may be the same as a or b, but it costs time. */
PGPError
PGPBigNumMultiply(
PGPBigNumRef lhs,
PGPBigNumRef rhs,
PGPBigNumRef dest)
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( lhs );
pgpValidateBigNum( rhs );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnMul( &dest->bn, &lhs->bn, &rhs->bn ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/* dest = a * b, where 0 <= b < 2^16. dest and a may be the same. */
PGPError
PGPBigNumMultiplyQ(
PGPBigNumRef lhs,
PGPUInt16 sm,
PGPBigNumRef dest)
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( lhs );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnMulQ( &dest->bn, &lhs->bn, sm ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/*
* q = n/d, r = n%d. r may be the same as n, but not d,
* and q may not be the same as n or d.
* re-entrancy issue: this temporarily modifies d, but restores
* it for return.
*/
PGPError
PGPBigNumDivide(
PGPBigNumRef numerator,
PGPBigNumRef denominator,
PGPBigNumRef quotient,
PGPBigNumRef remainder)
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( numerator );
pgpValidateBigNum( denominator );
pgpValidateBigNum( quotient );
pgpValidateBigNum( remainder );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnDivMod( "ient->bn,
&remainder->bn, &numerator->bn, &denominator->bn) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/*
* dest = n % d. dest and src may be the same, but not dest and d.
* re-entrancy issue: this temporarily modifies d, but restores
* it for return.
*/
PGPError
PGPBigNumMod(
PGPBigNumRef numerator,
PGPBigNumRef denominator,
PGPBigNumRef dest )
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( numerator );
pgpValidateBigNum( denominator );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnMod( &dest->bn, &numerator->bn, &denominator->bn) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/* return src % d, where 0 <= d < 2^16. */
PGPUInt16
PGPBigNumModQ(
PGPBigNumRef numerator,
PGPUInt16 denominator )
{
PGPUInt16 result = 0;
pgpEnterZeroFunction();
if ( pgpBigNumIsValid( numerator ) && denominator != 0 )
{
result = bnModQ( &numerator->bn, denominator);
}
return( result );
}
/* n = n^exp, modulo "mod" "mod" *must* be odd */
PGPError
PGPBigNumExpMod(
PGPBigNumRef n,
PGPBigNumRef exponent,
PGPBigNumRef mod,
PGPBigNumRef dest )
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( n );
pgpValidateBigNum( exponent );
pgpValidateBigNum( mod );
pgpValidateBigNum( dest );
PGPValidateParam( dest != n && dest != exponent && dest != mod );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnExpMod( &dest->bn,
&n->bn, &exponent->bn, &mod->bn ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/*
* dest = n1^e1 * n2^e2, modulo "mod". "mod" *must* be odd.
* dest may be the same as n1 or n2.
*/
PGPError
PGPBigNumDoubleExpMod(
PGPBigNumRef n1,
PGPBigNumRef exponent1,
PGPBigNumRef n2,
PGPBigNumRef exponent2,
PGPBigNumRef mod,
PGPBigNumRef dest )
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( n1 );
pgpValidateBigNum( exponent1 );
pgpValidateBigNum( n2 );
pgpValidateBigNum( exponent2 );
pgpValidateBigNum( mod );
pgpValidateBigNum( dest );
PGPValidateParam( dest != n1 && dest != exponent1 &&
dest != n2 && dest != exponent2 && dest != mod );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnDoubleExpMod( &dest->bn,
&n1->bn, &exponent1->bn,
&n2->bn, &exponent2->bn,
&mod->bn ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/* dest = 2^exp, modulo "mod" "mod" *must* be odd */
PGPError
PGPBigNumTwoExpMod(
PGPBigNumRef exponent,
PGPBigNumRef mod,
PGPBigNumRef dest )
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( exponent );
pgpValidateBigNum( mod );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnTwoExpMod( &dest->bn, &exponent->bn, &mod->bn ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/* dest = gcd(a, b). The inputs may overlap arbitrarily. */
PGPError
PGPBigNumGCD(
PGPBigNumRef a,
PGPBigNumRef b,
PGPBigNumRef dest )
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( a );
pgpValidateBigNum( b );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnGcd( &dest->bn, &a->bn, &b->bn ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/* dest = src^-1, modulo "mod". dest may be the same as src. */
PGPError
PGPBigNumInv(
PGPBigNumRef src,
PGPBigNumRef mod,
PGPBigNumRef dest )
{
PGPError err = kPGPError_NoErr;
int bnError = 0;
pgpValidateBigNum( src );
pgpValidateBigNum( mod );
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
bnError = bnInv( &dest->bn, &src->bn, &mod->bn );
if ( IsBNError( bnError ) )
{
if ( bnError == 1 )
err = kPGPError_BigNumNoInverse;
else
err = kPGPError_OutOfMemory;
}
return( err );
}
/* Shift dest left "amt" places */
PGPError
PGPBigNumLeftShift(
PGPBigNumRef dest,
PGPUInt32 numBits )
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
if ( IsBNError( bnLShift( &dest->bn, numBits ) ) )
{
err = kPGPError_OutOfMemory;
}
return( err );
}
/* Shift dest right "amt" places, discarding low-order bits */
PGPError
PGPBigNumRightShift(
PGPBigNumRef dest,
PGPUInt32 numBits )
{
PGPError err = kPGPError_NoErr;
pgpValidateBigNum( dest );
pgpEnterPGPErrorFunction();
bnRShift( &dest->bn, numBits );
return( err );
}
/* right shift all low order 0-bits, return number of bits shifted */
PGPUInt16
PGPBigNumMakeOdd( PGPBigNumRef dest )
{
PGPUInt16 numBits = 0;
pgpEnterZeroFunction();
if ( pgpBigNumIsValid( dest ) )
{
numBits = bnMakeOdd( &dest->bn );
}
return( numBits );
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -