Example #1
0
 /*******************************************************************************
  Function:
   
   void BIGINT_Multiply(BIGINT_DATA*result, BIGINT_DATA *arg1, BIGINT_DATA *arg2 )

  Summary:
   Big Integer multiplication routine.

  Description:
    This function performs the multiplication of A and B and saves it in C.
     result=arg1*arg2;     

  Precondition:
   result is initialized to all zeros.

  Parameters:
   Pointers to the operands and the result

  Returns:
   None.

  Example:
    <code>
    void BigIntMultiply(res,arg1,arg2); </code>

  Remarks:
  Only Little Endianness is supported.If the operands are not in the Little Endian format,
  They need to be changed to Little-Endianness format.
 *****************************************************************************/
BIGINT_RESULT BIGINT_Multiply(BIGINT_DATA *result, BIGINT_DATA *arg1, BIGINT_DATA *arg2)
{
    BIGINT_DATA_TYPE * a, *b;

    a = BigIntMSB(arg1);
    b = BigIntMSB(arg2);

    if ((result->bLength) < ((a - (uint16_t *)arg1->startAddress) + (b - (uint16_t *)arg2->startAddress) + 2))
        return BIGINT_RESULT_RESULT_BUFFER_LENGTH_INSUFFICIENT;

    BIGINT_Set(result,0x00);     // clear res before performing multiplication
    _mulBI(arg1, arg2, result);     // Perform the multiplication

    return BIGINT_RESULT_OK;
}
Example #2
0
void BigIntMultiply(BIGINT *a, BIGINT *b, BIGINT *res)
{
	// Clear out the result
	BigIntZero(res);

	// Load the start and stop pointers
	_iA = a->ptrLSB;
	_xA = BigIntMSB(a);
	_iB = b->ptrLSB;
	_xB = BigIntMSB(b);
	_iR = res->ptrLSB;

	// Perform the multiplication
	mulBI();

	// Invalidate the MSB ptr
	res->bMSBValid = 0;
}
Example #3
0
/*********************************************************************
 * Function:        CHAR BIGINT_Compare(BIGINTGINT *a, BIGINTGINT *b)
 *
 * PreCondition:    None
 *
 * Input:           *a: a pointer to the first number
 *                    *b: a pointer to the second number
 *
 * Output:          0 if a == b
 *                    1 if a > b
 *                    -1 if a < b
 *
 * Side Effects:    None
 *
 * Overview:        Determines if a > b, a < b, or a == b
 *
 * Note:            Supports at least 2048 bits.
 *                    
 ********************************************************************/
int BIGINT_Compare(BIGINT_DATA *a, BIGINT_DATA *b)
{
    uint32_t                magA, magB;
    BIGINT_DATA_TYPE         valA, valB;
    BIGINT_DATA_TYPE         *ptrA;
    BIGINT_DATA_TYPE         *ptrB;
    
    magA = BigIntMSB(a) - (BIGINT_DATA_TYPE *)a->startAddress;
    magB = BigIntMSB(b) - (BIGINT_DATA_TYPE *)b->startAddress;

    if(magA > magB)
    {
        
        return 1;
    }
    else if(magA < magB)
    {
        return -1;
    }

 // Loop through all words, looking for a non-equal word
    ptrA = BigIntMSB(a);
    ptrB = BigIntMSB(b);
    while(ptrA >= (BIGINT_DATA_TYPE *)a->startAddress)    // Magnitude is same, no need to check ptrB bounds
    {
        valA = *ptrA--;
        valB = *ptrB--;
        
        if(valA > valB)
        {
                    
            return 1;
        }
        else if(valA < valB)
        {
                    
            return -1;
        }    
    }

    // All words were exactly identical, return match
    return 0;
}
Example #4
0
void BigIntSubtract(BIGINT *a, BIGINT *b)
{
	_iA = a->ptrLSB;
	_xA = a->ptrMSBMax;
	_iB = b->ptrLSB;
	_xB = BigIntMSB(b);
	subBI();

	// Invalidate MSB pointer
	a->bMSBValid = 0;
}
Example #5
0
void BigIntAdd(BIGINT *a, BIGINT *b)
{
	_iA = a->ptrLSB;
	_xA = a->ptrMSBMax;
	_iB = b->ptrLSB;
	_xB = BigIntMSB(b);
	addBI();

	// Invalidate MSB pointer
	a->bMSBValid = 0;
}
Example #6
0
void BigIntSquare(BIGINT *a, BIGINT *res)
{
	BigIntZero(res);
	_iA = a->ptrLSB;
	_xA = BigIntMSB(a);
	_iR = res->ptrLSB;
	sqrBI();

	// Invalidate the MSB ptr
	res->bMSBValid = 0;
}
Example #7
0
uint32_t BigIntMagnitude(BIGINT_DATA *n)
{
    return BigIntMSB(n) - (BIGINT_DATA_TYPE *)n->startAddress;
}
Example #8
0
/*********************************************************************
 * Function:        void BIGINTMod(BIGINT_DATA *n, BIGINT_DATA *m)
 *
 * PreCondition:    None
 *
 * Input:           *n: a pointer to the number
 *                    *m: a pointer to the modulus
 *                    
 * Output:          *n contains the modded number
 *                     i.e: *n = *n % *m
 *
 * Side Effects:    None
 *
 * Overview:        Call BigIntMod() to calculate the modulus of two
 *                    really big numbers.
 *
 * Note:            Supports at least 2048 bits
 ********************************************************************/
BIGINT_RESULT BIGINT_Mod(BIGINT_DATA *result, BIGINT_DATA *a, BIGINT_DATA *b)
{
    BIGINT_DATA_TYPE    *_iB, *_xB, *_iR, _wC;
    BIGINT_DATA_TYPE    *ptrMSBa, MSBb;
    BIGINT_DATA_TYPE_2  qHatInt;
    BIGINT_DATA         temp1;
    uint32_t            tempLen;

    union
    {
        BIGINT_DATA_TYPE v[2];
        BIGINT_DATA_TYPE_2 Val;
    } topTwoWords;

    if (result == b)
    {
        // We can't store the result in m
        return BIGINT_RESULT_INVALID_PARAMETER;
    }
    else if (result != a)
    {
        // The result buffer is a separate buffer from n
        BIGINT_Copy (result, a);
    }


    // Set up assembly pointers for m
    // _iB and _xB are limiters in the _mas function
    _iB = b->startAddress;
    _xB = BigIntMSB(b);

    // Find the starting MSBs
    ptrMSBa = BigIntMSB(result);
    MSBb = *_xB;

    temp1.startAddress = result->startAddress;
    temp1.bLength = result->bLength;

    // Find out how many bytes we need to shift and move the LSB up
    _iR = result->startAddress + ((BigIntMagnitudeDifference(result, b) - 1) * BIGINT_DATA_SIZE);

    // This loops while the order of magnitude (in words) of n > m
    // Each iteration modulos off one word of magnitude from n
    while(_iR >= (BIGINT_DATA_TYPE *)result->startAddress)
    {
        // Find qHat = MSBn:MSBn-1/MSBb
        topTwoWords.Val = *((BIGINT_DATA_TYPE_2*)(ptrMSBa - 1));
        qHatInt = topTwoWords.Val / MSBb;
        if(qHatInt > BIGINT_DATA_MAX)  
            qHatInt = BIGINT_DATA_MAX;

        // Once qHat is determined, we multiply M by qHat, shift it up
        // as many bytes as possible, and subtract the result.
        // In essence, qHat is a rough estimation of the quotient, divided
        // by a power of 2^8 (PIC18) or 2^16 (PIC24/dsPIC)
        
        // This implementation multiplies and subtracts in the same step
        // using a _mas function which saves about 30% of clock cycles.

        // Save the old MSB and set up the ASM pointers
        _wC = (BIGINT_DATA_TYPE)qHatInt;

        // Do the multiply and subtract
        // Occassionally this results in underflow...this is solved below.
        _masBI(_xB, _iB, _wC, _iR);

        // qHat may have been 1 or 2 greater than possible.  If so,
        // the new MSB will be greater than the old one, so we *add*
        // M back to N in the shifted position until overflow occurs
        // and this case corrects itself.
        while(topTwoWords.v[1] < *ptrMSBa)
        {
            tempLen = result->bLength;
            result->bLength = (BigIntMSB(result) - _iR + 1) * BIGINT_DATA_SIZE;
            result->startAddress = _iR;

            _addBI(result,b);

            result->startAddress = temp1.startAddress;
            result->bLength = tempLen;
        }

        // We should have modulated off a word (or two if we were lucky),
        // so move our MSB and LSB pointers as applicable
        while(*ptrMSBa == 0x0u)
        {
            _iR--;
            result->bLength -= 2;
            ptrMSBa--;
        }
    }

    // Iteration of the _mas function can only handle full-byte orders
    // of magnitude.  The result may still be a little larger, so this
    // cleans up the last few multiples with simple subtraction.
    while(BIGINT_Compare(result, b) >= 0)
    {
//        _iA = result->startAddress;
//        _xA = result->startAddress + result->bLength - 1;

        _subBI(result,b);
    }

    result->startAddress = temp1.startAddress;
    result->bLength = temp1.bLength;

    return BIGINT_RESULT_OK;
}
Example #9
0
WORD BigIntMagnitude(BIGINT *n)
{
	return BigIntMSB(n) - n->ptrLSB;
}
Example #10
0
CHAR BigIntCompareROM(BIGINT *a, BIGINT_ROM *b)
{
	PTR_BASE				magA, magB;
	BIGINT_DATA_TYPE		valA, valB;
	BIGINT_DATA_TYPE		*ptrA;
	ROM BIGINT_DATA_TYPE	*ptrB;
	
	magA = BigIntMSB(a) - a->ptrLSB;
	magB = b->ptrMSB - b->ptrLSB;

	#if BIGINT_DEBUG_COMPARE
		putrsUART("\r\n    Compared Magnitudes |a|:");
		putulhexUART(w1);
		putrsUART(" |b|:");
		putulhexUART(w2);
		putrsUART(" diff:");
		putulhexUART(s);
	#endif

	if(magA > magB)
	{
		#if BIGINT_DEBUG_COMPARE
			putrsUART(" a > b");
		#endif
		
		return 1;
	}
	else if(magA < magB)
	{
		#if BIGINT_DEBUG_COMPARE
			putrsUART(" a < b");
		#endif
		
		return -1;
	}

	#if BIGINT_DEBUG_COMPARE
		putrsUART(" Checking further bytes...");
	#endif
	
	// Loop through all words, looking for a non-equal word
	ptrA = BigIntMSB(a);
	ptrB = b->ptrMSB;
	while(ptrA >= a->ptrLSB)	// Magnitude is same, no need to check ptrB bounds
	{
		valA = *ptrA--;
		valB = *ptrB--;
		
		if(valA > valB)
		{
			#if BIGINT_DEBUG_COMPARE
				putrsUART(" a > b");
			#endif
			
			return 1;
		}
		else if (valA < valB)
		{
			#if BIGINT_DEBUG_COMPARE
				putrsUART(" a < b");
			#endif
			
			return -1;
		}	
	}

	// All words were exactly identical, return match
	return 0;
}
Example #11
0
void BigIntModROM(BIGINT *n, BIGINT_ROM* m)
{
	BIGINT_DATA_TYPE *ptrMSBn, MSBm;
	BIGINT_DATA_TYPE_2 qHatInt, topTwoWords;

	// Find the starting MSBs
	ptrMSBn = BigIntMSB(n);
	MSBm = *m->ptrMSB;

	// Set up assembly pointers for m
	// _iBr and _xBr are limiters in the _masROM function
	_iBr = m->ptrLSB;
	_xBr = m->ptrMSB;

	// Find out how many bytes we need to shift and move the LSB up
	_iR = n->ptrLSB + (BigIntMagnitudeDifferenceROM(n, m) - 1);

	// This loops while the order of magnitude (in words) of n > m
	// Each iteration modulos off one word of magnitude from n
	while(_iR >= n->ptrLSB)
	{
		// Find qHat = MSBn:MSBn-1/MSBm
		topTwoWords = *((BIGINT_DATA_TYPE_2*)(ptrMSBn - 1));
		qHatInt = topTwoWords / MSBm;
		if(qHatInt > BIGINT_DATA_MAX)  
			qHatInt = BIGINT_DATA_MAX;

#if BIGINT_DEBUG
		putrsUART("\r\n\r\n    n = ");
		BigIntPrint(n);
		putrsUART("\r\n    m = ");
		BigIntPrintROM(m);
		putrsUART("\r\n    qHat (");
		putulhexUART(qHatInt);
		putrsUART(") = topTwo(");
		putulhexUART(topTwoWords);
		putrsUART(") / (");
		putulhexUART(MSBm);
		putrsUART(") ");
#endif

		// Once qHat is determined, we multiply M by qHat, shift it up
		// as many bytes as possible, and subtract the result.
		// In essence, qHat is a rough estimation of the quotient, divided
		// by a power of 2^8 (PIC18) or 2^16 (PIC24/dsPIC) or 2^32 (PIC32)
		
		// This implementation multiplies and subtracts in the same step
		// using a _mas function which saves about 30% of clock cycles.

		// Save the old MSB and set up the ASM pointers
		_wC = (BIGINT_DATA_TYPE)qHatInt;

		// Do the multiply and subtract
		// Occassionally this results in underflow...this is solved below.
		masBIROM();

		// qHat may have been 1 or 2 greater than possible.  If so,
		// the new MSB will be greater than the old one, so we *add*
		// M back to N in the shifted position until overflow occurs
		// and this case corrects itself.
		while(((BIGINT_DATA_TYPE*)&topTwoWords)[1] < *BigIntMSB(n))
		{
			_iA = _iR;
			_xA = BigIntMSB(n);
			addBIROM();
		}

		// We should have modulated off a word (or two if we were lucky),
		// so move our MSB and LSB pointers as applicable
		while(*ptrMSBn == 0x0u)
		{
			_iR--;
			n->ptrMSB--;
			ptrMSBn--;
		}
	}

	// Iteration of the _mas function can only handle full-byte orders
	// of magnitude.  The result may still be a little larger, so this
	// cleans up the last few multiples with simple subtraction.
	while(BigIntCompareROM(n, m) >= 0)
	{
		_iA = n->ptrLSB;
		_xA = n->ptrMSB;
		subBIROM();
	
		// Invalidate MSB pointer
		n->bMSBValid = 0;
	}
}