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

📄 pgpbignum.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpBigNum.c,v 1.8 2002/08/06 20:10:57 dallen Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#include "pgpSDKPriv.h"

#include "pgpMem.h"
#include "pgpErrors.h"
#include "pgpContext.h"
#include "pgpBigNum.h"
#include "pgpMemoryMgr.h"
#include "pgpPFLPriv.h"
#include "bn.h"




#define IsBNError( i )			( (i) != 0 )
#define IsntBNError( i )		( (i) == 0 )


struct PGPBigNum
{
	BigNum			bn;
};

	static PGPBoolean
pgpBigNumIsValid( PGPBigNumRef bn )
{
	return( IsntNull( bn ) &&
		IsntPGPError( PGPValidateMemoryMgr( ( bn->bn.mgr ) ) ) );
}
#define pgpValidateBigNum( bn )	PGPValidateParam( pgpBigNumIsValid( bn ) )

	static PGPError
pgpNewBigNumInternal(
	PGPMemoryMgrRef memoryMgr,
	PGPBoolean		secure,
	PGPBigNumRef *	newBN )
{
	PGPError		err	= kPGPError_NoErr;
	PGPBigNumRef	ref;

	ref	= (PGPBigNumRef) PGPNewData( memoryMgr, sizeof( **newBN ),
					kPGPMemoryMgrFlags_Clear);
	if ( IsntNull( ref ) )
	{
		bnBegin( &ref->bn, memoryMgr, secure );
		*newBN	= ref;
	}
	else
	{
		err	= kPGPError_OutOfMemory;
	}
	
	return( err );
}

/* Creates a new bignum */
	PGPError
PGPNewBigNum(
	PGPContextRef 	context,
	PGPBoolean		secure,
	PGPBigNumRef *	newBN )
{
	PGPError		err	= kPGPError_NoErr;
	PGPMemoryMgrRef	mgr = PGPPeekContextMemoryMgr( context );
	
	PGPValidatePtr( newBN );
	*newBN	= kPGPInvalidBigNumRef;
	
	pgpEnterPGPErrorFunction();

	err = PGPValidateMemoryMgr( mgr );
	if( IsntPGPError( err ) )
	{
		err = pgpNewBigNumInternal( mgr, secure, newBN );
	}
	
	return( err );
}


/* destoys the bignum and all memory it uses */
	PGPError
PGPFreeBigNum( PGPBigNumRef	bn )
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( bn );

	pgpEnterPGPErrorFunction();

	bnEnd( &bn->bn );
	
	err	= PGPFreeData( bn );
	
	return( err );
}



/* Create a new big num with same value as src */
	PGPError
PGPCopyBigNum(
	PGPBigNumRef	src,
	PGPBigNumRef * 	dest )
{
	PGPError		err	= kPGPError_NoErr;
	PGPBigNumRef	temp	= NULL;
	
	PGPValidatePtr( dest );
	*dest	= NULL;
	pgpValidateBigNum( src );
	
	pgpEnterPGPErrorFunction();

	err	= pgpNewBigNumInternal( src->bn.mgr, src->bn.isSecure, &temp );
	if ( IsntPGPError( err ) )
	{
		err	= PGPAssignBigNum( src, temp );
		if ( IsPGPError( err ) )
		{
			PGPFreeBigNum( temp );
			temp	= NULL;
		}
	}
	
	*dest	= temp;
	
	return( err );
}


/* Make existing bignum dest have same value as source */
	PGPError
PGPAssignBigNum(
	PGPBigNumRef	src,
	PGPBigNumRef	dest )
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( src );
	pgpValidateBigNum( dest );
	
	pgpEnterPGPErrorFunction();

	if ( IsBNError( bnCopy( &dest->bn, &src->bn ) ) )
	{
		err	= kPGPError_OutOfMemory;
	}
	
	return( err );
}



/* Swap two BigNums.  Very fast. */
	PGPError
PGPSwapBigNum( PGPBigNumRef	a, PGPBigNumRef	b)
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( a );
	pgpValidateBigNum( b );
	
	pgpEnterPGPErrorFunction();

	bnSwap( &a->bn, &b->bn );
	
	return( err );
}




/*
 * Move bytes between the given buffer and the given BigNum encoded in
 * base 256.  I.e. after either of these, the buffer will be equal to
 * (bn / 256^lsbyte) % 256^len.  The difference is which is altered to
 * match the other!
 */
	PGPError
PGPBigNumExtractBigEndianBytes(
	PGPBigNumRef	bn,
	PGPByte *			dest,
	PGPUInt32			lsbyte,
	PGPUInt32			len )
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( bn );
	
	pgpEnterPGPErrorFunction();

	bnExtractBigBytes( &bn->bn, dest, lsbyte, len );
	
	return( err );
}

				
	PGPError
PGPBigNumInsertBigEndianBytes(
	PGPBigNumRef	bn,
	PGPByte const *	src,
	PGPUInt32		lsbyte,
	PGPUInt32		len )
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( bn );
	
	pgpEnterPGPErrorFunction();

	if ( IsBNError( bnInsertBigBytes( &bn->bn, src, lsbyte, len ) ) )
	{
		err	= kPGPError_OutOfMemory;
	}
	
	return( err );
}


/* The same, but the buffer is little-endian. */
	PGPError
PGPBigNumExtractLittleEndianBytes(
	PGPBigNumRef	bn,
	PGPByte *		dest,
	PGPUInt32		lsbyte,
	PGPUInt32		len )
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( bn );
	
	pgpEnterPGPErrorFunction();

	bnExtractLittleBytes( &bn->bn, dest, lsbyte, len );
	
	return( err );
}

				
	PGPError
PGPBigNumInsertLittleEndianBytes(
	PGPBigNumRef	bn,
	PGPByte const *	src,
	PGPUInt32		lsbyte,
	PGPUInt32		len )
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( bn );
	
	pgpEnterPGPErrorFunction();

	if ( IsBNError( bnInsertLittleBytes( &bn->bn, src, lsbyte, len ) ) )
	{
		err	= kPGPError_OutOfMemory;
	}
	
	return( err );
}


/* Return the least-significant bits (at least 16) of the BigNum */
	PGPUInt16
PGPBigNumGetLSWord( PGPBigNumRef	bn )
{
	PGPUInt16	lsWord	= 0;
	
	pgpEnterZeroFunction();

	if ( pgpBigNumIsValid( bn ) )
	{
		lsWord	= bnLSWord( &bn->bn );
	}
	
	return( lsWord );
}


/*
 * Return the number of significant bits in the BigNum.
 * 0 or 1+floor(log2(src))
 */
	PGPUInt32
PGPBigNumGetSignificantBits( PGPBigNumRef	bn )
{
	PGPUInt32	numBits;
	
	pgpEnterZeroFunction();

	pgpValidateBigNum( bn );
	
	numBits	= bnBits( &bn->bn );
	
	return( numBits );
}


/*
 * Adds two bignums into dest.  Faster if dest is same as lhs or rhs.
 */
	PGPError
PGPBigNumAdd(
	PGPBigNumRef	lhs,
	PGPBigNumRef	rhs,
	PGPBigNumRef	dest )
{
	PGPError	err	= kPGPError_NoErr;
	int			bnError;
	
	pgpValidateBigNum( lhs );
	pgpValidateBigNum( rhs );
	pgpValidateBigNum( dest );
	
	pgpEnterPGPErrorFunction();

	if ( lhs == dest )
	{
		bnError	= bnAdd( &dest->bn, &rhs->bn );
	}
	else if ( rhs == dest )
	{
		bnError	= bnAdd( &dest->bn, &lhs->bn );
	}
	else
	{
		bnError	= bnCopy( &dest->bn, &lhs->bn );
		if ( bnError == 0 )
		{
			bnError	= bnAdd( &dest->bn, &rhs->bn );
		}
	}
	
	if ( IsBNError( bnError ) )
	{
		err	= kPGPError_OutOfMemory;
	}
	
	return( err );
}


/*
 * lhs-rhs.  dest and src may be the same, but bnSetQ(dest, 0) is faster.
 * if dest < src, returns error and dest is undefined.
 */
	PGPError
PGPBigNumSubtract(
	PGPBigNumRef	lhs,
	PGPBigNumRef	rhs,
	PGPBigNumRef	dest,
	PGPBoolean *	underflowPtr )
{
	PGPError	err	= kPGPError_NoErr;
	int			bnError;
	PGPBoolean	underflow	= FALSE;
	
	if ( IsntNull( underflowPtr ) )
		*underflowPtr	= FALSE;
		
	pgpValidateBigNum( lhs );
	pgpValidateBigNum( rhs );
	pgpValidateBigNum( dest );
	
	pgpEnterPGPErrorFunction();

	if ( lhs == dest )
	{
		bnError	= bnSub( &dest->bn, &rhs->bn );
		underflow	= (bnError == 1);
		bnError		= 0;
	}
	else if ( rhs == dest )
	{
		BigNum	temp;
		PGPBoolean	secure;
		
		secure	= lhs->bn.isSecure || rhs->bn.isSecure ||
					dest->bn.isSecure;
		bnBegin( &temp, dest->bn.mgr, secure );
			bnError	= bnCopy( &temp, &lhs->bn );
			if ( bnError == 0 )
			{
				bnError	= bnSub( &temp, &rhs->bn );
				underflow	= (bnError == 1);
				bnError		= 0;
				
				bnError	= bnCopy( &dest->bn, &temp );
			}
		bnEnd( &temp );
	}
	else
	{
		bnError	= bnCopy( &dest->bn, &lhs->bn );
		if ( bnError == 0 )
		{
			bnError	= bnSub( &dest->bn, &rhs->bn );
			underflow	= (bnError == 1);
			bnError		= 0;
		}
	}
	
	if ( IsntNull( underflowPtr ) )
		*underflowPtr	= underflow;
		
	if ( bnError == -1 )
		err	= kPGPError_OutOfMemory;
	
	return( err );
}



/* Return sign (-1, 0, +1) of a-b.  a <=> b --> bnCmpQ(a, b) <=> 0 */
	PGPInt32
PGPBigNumCompareQ(
	PGPBigNumRef	bn,
	PGPUInt16		sm )
{
	PGPUInt32	result	= 0;
	
	pgpEnterZeroFunction();

	if ( pgpBigNumIsValid( bn ) )
	{
		result	= bnCmpQ( &bn->bn, sm );
	}
	
	return( result );
}


/* dest = src, where 0 <= src < 2^16. */
	PGPError
PGPBigNumSetQ(
	PGPBigNumRef	dest,
	PGPUInt16		sm)
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( dest );
	
	pgpEnterPGPErrorFunction();

	if ( IsBNError( bnSetQ( &dest->bn, sm ) ) )
	{
		err	= kPGPError_OutOfMemory;
	}
	
	return( err );
}


/* dest = bn + sm, where 0 <= sm < 2^16 */
	PGPError
PGPBigNumAddQ(
	PGPBigNumRef	bn,
	PGPUInt16		sm,
	PGPBigNumRef	dest)

⌨️ 快捷键说明

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