예제 #1
0
// Subtracts two bigints and returns the result which is a bigint
// Returns a-b
bigint bigint_sub(bigint a, bigint b){

	if(a.pos==0&&b.pos==1){
		b.pos = 0;
		return bigint_add(a,b);
	}
	else if(a.pos==1&&b.pos==0){
		b.pos = 1;
		return bigint_add(a,b);
	}

	//At this point, both the numbers are of the same sign. So, a normal subtraction will work.
	else{
		int max_num = compare_bigint(a,b);

		//Case: a>b and both are negative. Example: a = -20 ; b = -30
		//a-b = (-x) - (-y) = y-x. 'y' and 'x' are positive. And 'y' is greater than 'x'.
		if(a.pos==0 && max_num==1){
			b.pos = 1;
			a.pos = 1;
			return bigint_sub(b,a);//Returns (y-x). 'y' and 'x' are positive.
		}

		//Case: b>a and both are negative
		//a-b = (-x) - (-y) = y-x. 'y' and 'x' are positive. 'x' is greater than 'y'.
		//So, do x-y and then change the sign to negative. Then return.
		else if(a.pos==0 && max_num==-1){
			
			a.pos = 1;
			b.pos = 1;
			bigint tempNo = bigint_sub(a,b);
			tempNo.pos = 0;
			return tempNo;
		}


		// Case: b>a and both are positive
		// a-b = x-y. 'x' and 'y' are positive
		// Do y-x and change the sign, then return.
		else if(a.pos==1 && max_num==-1){
			bigint tempNo = bigint_sub(b,a);
			tempNo.pos = 0;
			return tempNo;
		}

		//Case: a>b and both are positive
		else if(a.pos==1 && max_num==1){
			return borrow_subtraction(a,b);
		}

		//Case: Both are equal. Return 0.
		else{
			return init_bigint();
		}

	}
}
예제 #2
0
파일: bigint.c 프로젝트: jvesely/helenos
/** Get value of big integer.
 *
 * Allows to obtain the value of big integer, provided that it fits
 * into a small integer.
 *
 * @param bigint	Bigint to obtain value from.
 * @param dval		Place to store value.
 * @return		EOK on success, ELIMIT if bigint is too big to fit
 *			to @a dval.
 */
int bigint_get_value_int(bigint_t *bigint, int *dval)
{
	bigint_t vval, diff;
	size_t idx;
	int val;
	bool_t zf;

#ifdef DEBUG_BIGINT_TRACE
	printf("Get int value of bigint.\n");
#endif
	val = 0;
	for (idx = 0; idx < bigint->length; ++idx) {
		val = val * BIGINT_BASE + bigint->digit[idx];
	}

	if (bigint->negative)
		val = - val;

	/* If the value did not fit @c val now contains garbage. Verify. */
	bigint_init(&vval, val);

	bigint_sub(bigint, &vval, &diff);
	zf = bigint_is_zero(&diff);

	bigint_destroy(&vval);
	bigint_destroy(&diff);

	/* If the difference is not zero, the verification failed. */
	if (zf != b_true)
		return EINVAL;

	*dval = val;
	return EOK;
}
예제 #3
0
//Uses subtraction repeatedly to find the remainder and the quotient.
//Stores the remainder in a new bigint and uses 'pos' to store the quotient.
//returns this new bigint
bigint get_remainder_quotient(bigint dividend, bigint divisor){

	int quotient = 0;

	while(compare_bigint(dividend, divisor)>=0){
		dividend = bigint_sub(dividend,divisor);
		quotient+=1;
	}

	dividend.pos = quotient;//Will be 1 anyway, but to ensure it. Not very crucial.
	return dividend;
}
예제 #4
0
int main( int argc, char* argv[] )
{
    char cmd[ BUF_SIZE ];
    // NOTE: Uncomment this once you've implemented this function
       bigint result = init_bigint();
      //bigint result;
    // At the end of every arithmetic operation update the result.

    // In an infinite loop, get input from user
    while( 1 )
    {
        char* op = NULL; // Store the operation
        // Get a line of input from the user
        fgets( cmd, BUF_SIZE, stdin );

        // Parse the line using strtok
        // Note: Given a string like "a b c d", strtok returns "a" the first
        // time it's called, and "b", "c", "d" and NULL subsequently, if the
        // first argument is NULL. Read the manpage for more details
        op = strtok( cmd, " " );
        // If the last line is a new line, make it a null character
        int len = strlen( op );
        if( op[ len-1 ] == '\n' )
          op[ len-1 ] = 0;
        
        // Match the operation, and do appropriate action
        if( strcmp( op, "quit" ) == 0 || op[0] == EOF )
        {
          // Quit when you see this
          break;
        }
        else if( strcmp( op, "set" ) == 0 )
        {
          // set <data>
          // Sets a big int value to data
         
          int data;
          if( read_args1( &data ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
           // printf( "Setting value as %d\n", data );
            // NOTE: Uncomment this once you've implemented this function
             result = int_to_bigint(data);
          }
        }
        
        else if( strcmp( op, "add" ) == 0 )
        {
          // add <num1> <num2> 
          // Adds two bigints and then prints the result
          
          char num1[512];
          char num2[512];
          if( read_args2( num1, num2 ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
            //printf( "Add %s and %s\n", num1, num2 );
            // NOTE: Uncomment this once you've implemented this function
             bigint a = make_bigint(num1);
             bigint b = make_bigint(num2);
             result = bigint_add( a, b);
             print_bigint(result);
          }
        }
        
        else if( strcmp( op, "sub" ) == 0 )
        {
          // sub <num1> <num2> 
          // Subtracts two bigints and then prints the result
          
          char num1[512];
          char num2[512];
          if( read_args2( num1, num2 ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
            //printf( "Subtract %s and %s\n", num1, num2 );
            // NOTE: Uncomment this once you've implemented this function
             bigint a = make_bigint(num1);
             bigint b = make_bigint(num2);
             result = bigint_sub( a, b);
             print_bigint(result);
	     printf("\n");
          }
        }
        
        else if( strcmp( op, "mul" ) == 0 )
        {
          // mul <num1> <num2> 
          // Multiplies two bigints and then prints the result
          
          char num1[512];
          char num2[512];
          if( read_args2( num1, num2 ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
            //printf( "Multiply %s and %s\n", num1, num2 );
            // NOTE: Uncomment this once you've implemented this function
             bigint a = make_bigint(num1);
             bigint b = make_bigint(num2);
             result = bigint_mul( a, b);
             print_bigint(result);
          }
        }
        else if( strcmp( op, "div" ) == 0 )
        {
          // add <num1> <num2> 
          // Adds two bigints and then prints the result
          
          char num1[512];
          char num2[512];
          if( read_args2( num1, num2 ) )
          {
            // NOTE: This printf line has been added to help debug. Should be
            // removed before submitting
            //printf( "Divide %s and %s\n", num1, num2 );
            // NOTE: Uncomment this once you've implemented this function
             bigint a = make_bigint(num1);
             bigint b = make_bigint(num2);
             result = bigint_div( a, b);
             print_bigint(result);
          }
        }
        else
        {
          printf( "Invalid command\n" );
        }

    }

    return 0;
}
예제 #5
0
// Adds two bigints and returns the result which is a bigint
bigint bigint_add(bigint a, bigint b){

	//If they are of the opposite signs, then send them for subtraction
	if(a.pos==0&&b.pos==1||a.pos==1&&b.pos==0){

		if(a.pos==0){
			a.pos = 1;//Make it positive and send it for subtraction.
			return bigint_sub(b,a);//Returns (b-a)
		}

		else{
			b.pos = 1;//Make it positive and send it for subtraction.
			return bigint_sub(a,b);//Returns (a-b)
		}
	}
	//If of the same sign, then add.
	else{
		bigint bigger_num, smaller_num;// Here the bigger number is in terms of the absolute quantity.

		if(!a.pos){
			if(compare_bigint(a,b)==1){
				bigger_num = b; smaller_num = a;
			}
			else if(compare_bigint(a,b)==-1){
				bigger_num = a; smaller_num = b;
			}
			else{
				//Both are equal. Assign any number to any variable.
				bigger_num = a; smaller_num = b;
			}
		}
		else{
			if(compare_bigint(a,b)==1){
				bigger_num = a; smaller_num = b;
			}
			else if(compare_bigint(a,b)==-1){
				bigger_num = b; smaller_num = a;
			}
			else{
				//Both are equal. Assign any number to any variable.
				bigger_num = b; smaller_num = a;
			}
		}

		//At this point, bigger_num has the larger number in absolute terms. The 'smaller_num' contains the other.
		//Now, create a new character array which can hold the sum of the two terms and pass that array to make_bigint
		//For the new character array, assign memory 1 greater than the length of the bigger_num.
		//In case the left hand most field doesn't get filled up, then assign 0 to it. make_bigint takes care of that.

		int new_length = bigger_num.length+1;//This length excludes the negative sign.
		char* new_value;
		if(bigger_num.pos==0){
		 	new_value = (char*)malloc((new_length+1+1)*sizeof(char));//+1 for the negative sign and +1 for terminating it with NULL
			new_value[0] = '-';
			new_value[new_length+1] = '\0';//Terminating with a null character
		}
		else{
		 	new_value = (char*)malloc((new_length+1)*sizeof(char));//+1 for terminating it with null.
			new_value[new_length] = '\0';//Terminating with a null character
		}

		addValues(bigger_num, smaller_num, new_value, new_length);//Does string addition and stores the result in new_value
 		return make_bigint(new_value);
	}//Else ends
}
예제 #6
0
BigInt operator-(const BigInt& x, word y)
   {
   return bigint_sub(x, &y, 1, BigInt::Positive);
   }
예제 #7
0
BigInt operator-(const BigInt& x, const BigInt& y)
   {
   return bigint_sub(x, y.data(), y.sig_words(), y.sign());
   }
예제 #8
0
/*
 * RSA Sign using Garners algorithm and Chinese Remainder theorem.
 * See the derivation on page 613 in handbook of applied cryptography
 * use factors dp and dq of secret exponent d and p and q of public
 * exponent n, and qinv
 */
void
CSL_ComputeRsaSigFast(u8 *result, u32 *message, u32 *certpublickey, u32 *certp, u32 *certq, u32 *dmp, u32 *dmq, u32 *qinv, int num_bits)
{
    u32 pDigits, qDigits, cDigits, nDigits;
    bigint_digit bigp[MAX_BIGINT_DIGITS];
    bigint_digit bigq[MAX_BIGINT_DIGITS];
    bigint_digit bigc[MAX_BIGINT_DIGITS];
    bigint_digit bigdmp[MAX_BIGINT_DIGITS];
    bigint_digit bigdmq[MAX_BIGINT_DIGITS];
    bigint_digit bigqinv[MAX_BIGINT_DIGITS];
    bigint_digit bign[MAX_BIGINT_DIGITS];
    bigint_digit cP[MAX_BIGINT_DIGITS];
    bigint_digit cQ[MAX_BIGINT_DIGITS];
    bigint_digit mP[MAX_BIGINT_DIGITS];
    bigint_digit mQ[MAX_BIGINT_DIGITS];
    bigint_digit temp[MAX_BIGINT_DIGITS];

    int outlen;
    int i;
    int num_words = num_bits/BIGINT_DIGIT_BITS;

    bigint_zero(bigp, MAX_BIGINT_DIGITS);
    bigint_zero(bigq, MAX_BIGINT_DIGITS);
    bigint_zero(bigdmp, MAX_BIGINT_DIGITS);
    bigint_zero(bigdmq, MAX_BIGINT_DIGITS);
    bigint_zero(bigqinv, MAX_BIGINT_DIGITS);
    bigint_zero(bigc, MAX_BIGINT_DIGITS);

    for (i = 0; i < num_words/2; i++) {
        bigp[num_words/2 - 1 - i] = certp[i];
        bigq[num_words/2 - 1 - i] = certq[i];
        bigdmp[num_words/2 - 1 - i] = dmp[i];
        bigdmq[num_words/2 - 1 - i] = dmq[i];
        bigqinv[num_words/2 - 1 - i] = qinv[i];
    }
    for (i = 0; i < num_words; i++) {
        bigc[num_words - 1 - i] = message[i];
        bign[num_words - 1 - i] = certpublickey[i];
    }
    cDigits = bigint_digits(bigc, MAX_BIGINT_DIGITS);
    pDigits = bigint_digits(bigp, MAX_BIGINT_DIGITS);
    qDigits = bigint_digits(bigq, MAX_BIGINT_DIGITS);
    nDigits = bigint_digits(bign, MAX_BIGINT_DIGITS);

    /*
     * compute cP and cQ
     */
    bigint_mod(cP, bigc, cDigits, bigp, pDigits);
    bigint_mod(cQ, bigc, cDigits, bigq, qDigits);

    /*
     * Compute mP = cP^dP mod p  and  mQ = cQ^dQ mod q.
     */
    bigint_mod_exp(mP, cP, bigdmp, pDigits, bigp, pDigits);
    bigint_zero(mQ, nDigits);
    bigint_mod_exp(mQ, cQ, bigdmq, pDigits, bigq, pDigits);

    /*
     * do CRT
     * m = ((((mP - mQ) mod p)*qinv) mod p) *q + mQ
     */
    if (bigint_cmp(mP, mQ, pDigits) >= 0) {
        bigint_sub(temp, mP, mQ, pDigits);
    } else {
        bigint_sub(temp, mQ, mP, pDigits);
        bigint_sub(temp, bigp, temp, pDigits);
    }

    bigint_mod_mult(temp, temp, bigqinv, bigp, pDigits);
    bigint_mult(temp, temp, bigq, pDigits);
    bigint_add(temp, temp, mQ, nDigits);

    outlen = (num_bits + 7)/8;
    I2OSP(result, outlen, temp, nDigits);
}