// 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();
		}

	}
}
// Multiplies two big ints and returns a bigint
bigint bigint_mul(bigint a, bigint b){
	// Idea: Multiply the bigger number by a digit of the smaller number. Then shift by the digit's 10's place. Add this newly found
	// multiplication to the already calculated result. Keep adding until all the digits of the smaller number exhaust.

	bigint multiplicand_table[9];// [0] stores the multiplicand. [1] stores multiplicand*2. [2] stores multiplicand*3 and so on.
	int positive = 0;//Stores whether the multiplication is positive or negative. 0 means negative. 1 means positive.

	if((a.pos==0 && b.pos==0)||(a.pos==1 && b.pos==1))
		positive = 1;
	else
		positive = 0;

	a.pos = 1; b.pos = 1;//Make both the numbers positive for multiplication.

	int compare =  compare_bigint(a,b);
	bigint bigger_num, smaller_num;

	//If 'a' is greater than or equal to 'b' then do this.
	if(compare==1||compare==0){
		bigger_num = a; smaller_num = b;
	}
	//If 'b' is greater than 'a' then do this.
	else{
		bigger_num = b; smaller_num = a;
	}

	
	//Now fill the multiplicand table from 1 to 9.

	multiplicand_table[0] = bigger_num;// bigger_num*1
	multiplicand_table[1] = bigint_add(bigger_num,bigger_num);// bigger_num*2
	multiplicand_table[2] = bigint_add(multiplicand_table[1],multiplicand_table[0]);//bigger_num*3
	multiplicand_table[3] = bigint_add(multiplicand_table[2], multiplicand_table[0]);//bigger_num*4
	multiplicand_table[4] = bigint_add(multiplicand_table[3], multiplicand_table[0]);//bigger_num*5
	multiplicand_table[5] = bigint_add(multiplicand_table[4], multiplicand_table[0]);//bigger_num*6
	multiplicand_table[6] = bigint_add(multiplicand_table[5], multiplicand_table[0]);//bigger_num*7
	multiplicand_table[7] = bigint_add(multiplicand_table[6], multiplicand_table[0]);//bigger_num*8
	multiplicand_table[8] = bigint_add(multiplicand_table[7], multiplicand_table[0]);//bigger_num*9

	bigint result = init_bigint();


	int i = 0;//iterator
	for(i = smaller_num.length-1;i>=0;i--){

		if((smaller_num.value[i]-48)>=1){//Only if the digit is non zero will it add to the result.
			bigint tempNum = shift_by_power_of_10(multiplicand_table[smaller_num.value[i]-48-1],(smaller_num.length-1-i));
			result = bigint_add(result, tempNum);
		}

	}
	result.pos = positive;

	return result;
}
Beispiel #3
0
/** Multiply two big integers.
 *
 * The big integers @a a and @a b are multiplied and the result is stored in
 * @a dest.
 *
 * @param a		First factor.
 * @param b		Second factor.
 * @param dest		Destination bigint.
 */
void bigint_mul(bigint_t *a, bigint_t *b, bigint_t *dest)
{
	size_t idx;
	bigint_t dprod;
	bigint_t sum;
	bigint_t tmp;

#ifdef DEBUG_BIGINT_TRACE
	printf("Multiply bigints.\n");
#endif
	bigint_init(&sum, 0);
	for (idx = 0; idx < b->length; ++idx) {
		bigint_shift_mul_dig(a, b->digit[idx], idx, &dprod);
		bigint_add(&dprod, &sum, &tmp);
		bigint_destroy(&dprod);

		bigint_destroy(&sum);
		bigint_shallow_copy(&tmp, &sum);
	}

	if (b->negative)
		sum.negative = !sum.negative;

	bigint_shallow_copy(&sum, dest);
}
Beispiel #4
0
/**
 * Generate a truly random KUID within given `kuid'.
 */
void
kuid_random_fill(kuid_t *kuid)
{
	struct sha1 entropy;
	bigint_t bk, be;

	/*
	 * Entropy collection is slow but we generate our KUID only at startup
	 * and when none was present (nodes reuse their KUID from session to
	 * session to reuse as much of their previous routing table as possible).
	 *
	 * The aim is to obtain the most random KUID to ensure that among all
	 * the peers in the Kademlia network, KUIDs are unique and uniformly
	 * distributed in the KUID space.
	 */

	entropy_collect(&entropy);				/* slow */
	random_strong_bytes(kuid->v, KUID_RAW_SIZE);

	/*
	 * Combine the two random numbers by adding them.
	 *
	 * It's slightly better than XOR-ing the two since the propagation
	 * of the carry bit diffuses the randomness (entropy remains the same).
	 */

	STATIC_ASSERT(sizeof kuid->v == sizeof entropy.data);

	bigint_use(&bk, kuid->v, sizeof kuid->v);
	bigint_use(&be, entropy.data, sizeof entropy.data);

	(void) bigint_add(&bk, &be);
}
void bii_monproduct(bigint *dest, bigint abar, bigint bbar, bigint n, bigint nprime, uint32_t rpow){
	bigint t, m, u, tmp1, tmp2;
	bigint_init(&t);
	bigint_init(&m);
	bigint_init(&u);
	bigint_init(&tmp1);
	bigint_init(&tmp2);
	
	bigint_multiply(&t, abar, bbar);
	
	bigint_multiply(&tmp1, t, nprime);
	bigint_getsigbits(&m, tmp1, rpow);
	bigint_multiply(&tmp1, m,n);
	bigint_add(&u,t,tmp1);
	bigint_rightshift(&u,rpow);
	
	if(bigint_cmp(u,n)>=0) bigint_subtract(dest,u,n);
	else bigint_setval(dest, u);
	
	bigint_free(&t);
	bigint_free(&m);
	bigint_free(&u);
	bigint_free(&tmp1);
	bigint_free(&tmp2);
}
Beispiel #6
0
int bigint_multiply(bigint_s *dst, bigint_s *a, bigint_s *b) {
    if (!dst || !a || !b || !dst->bytes || !a->bytes || !b->bytes) return BIGINT_INVALID_ARGUMENT;
    if (a->bytes_alloced != b->bytes_alloced) return BIGINT_DIFFRENT_SIZE;  // TODO: allow different sizes (padding)

    uint32_t buffer_size = dst->bytes_alloced;
    
    /*
     * multiply two big numbers (in columns with carry)
     * assuming that:
     *       (b-number)     first row
     *     x (a-number)     second row
     *    -------------
     *           result
     */
    bool add = false;
    for (uint32_t i = 0; i < a->bytes_used; i++) {    // second row on paper
        bigint_s tmp;
        bigint_init(&tmp);
        
        uint32_t k = i;
        uint16_t rest = 0, carry = 0;
        for (uint32_t j = 0; j < b->bytes_used; j++) {
            uint16_t result = (uint16_t) a->bytes[i] * (uint16_t) b->bytes[j] + carry;
            
            carry = result/BIGINT_BASE;
            rest = result % BIGINT_BASE;
            
            if (k >= buffer_size) return BIGINT_OUT_OF_MEMORY;
            tmp.bytes[k++] = (uint8_t) rest;
        }
        if (k >= buffer_size) return BIGINT_OUT_OF_MEMORY;
        if (carry > 0) tmp.bytes[k++] = (uint8_t) carry;
        tmp.bytes_used = k;
        
        if (!add) {
            bigint_swap(dst, &tmp);
            add = true;
        } else {
            bigint_s r;
            bigint_init(&r);
            int rr = bigint_add(&r, dst, &tmp);
            if (rr != BIGINT_OK) return rr;
            bigint_swap(dst, &r);
            bigint_free(&r);
        }

        while (dst->bytes_used > 0 && dst->bytes[dst->bytes_used - 1] == 0) { dst->bytes_used--; }  // sometimes result is prefixed with zeros, cutting them off
        bigint_free(&tmp);
    }

    return BIGINT_OK;
}
Beispiel #7
0
/**
 * Add entropy from previous calls.
 */
static G_GNUC_COLD void
entropy_merge(sha1_t *digest)
{
	bigint_t older, newer;

	/*
	 * These big integers operate on the buffer space from ``digest'' and
	 * ``entropy_previous'' directly.
	 */

	bigint_use(&older, &entropy_previous, SHA1_RAW_SIZE);
	bigint_use(&newer, digest, SHA1_RAW_SIZE);
	bigint_add(&newer, &older);
	bigint_copy(&older, &newer);
}
Beispiel #8
0
int crypto_stream_salsa20_xor(
    unsigned char *c, 
    const unsigned char *m,crypto_uint16 mlen, 
    const unsigned char *n,const unsigned char *k
    )
{
  unsigned char z[16],x[64],u[8],i;

  for(i=0;i<8;i++) 
  {
    z[i] = n[i];
    z[i+8] = 0;
    u[i] = 0;
  }
  u[0] = 1;

  while (mlen >= 64) 
  {
    if(m)
    {
      crypto_core_salsa20(x,z,k,sigma);
      for(i=0;i<64;i++)
        c[i] = m[i] ^ x[i];
    }
    else
      crypto_core_salsa20(c,z,k,sigma);

    bigint_add(z+8,z+8,u,8);
    mlen -= 64;
    c += 64;
    if (m) m += 64;
  }
  if (mlen) 
  {
    crypto_core_salsa20(x,z,k,sigma);
    if(m)
      for(i=0;i<mlen;i++)
        c[i] = x[i] ^ m[i];
    else
      for(i=0;i<mlen;i++)
        c[i] = x[i];
  }
  return 0;
}
Beispiel #9
0
int crypto_stream_xor(
        unsigned char *c,
  const unsigned char *m,crypto_uint16 mlen,
  const unsigned char *n,
  const unsigned char *k
)
{
  unsigned char in[16];
  unsigned char block[64];
  unsigned char u[8];
  unsigned char i;

  if (!mlen) return 0;

  for (i = 0;i < 8;++i) { 
    in[i] = n[i]; 
	u[i] = 0; 
  }	
  for (i = 8;i < 16;++i) in[i] = 0;
  u[0]=1; 

  while (mlen >= 64) {
    crypto_core(block,in,k,sigma);
	bigint_xor(c,m,block,64);	
	bigint_add(&(in[8]),&(in[8]),&(u[0]),8);
    mlen -= 64;
    c += 64;
    m += 64;
  }

  if (mlen) {
    crypto_core(block,in,k,sigma);
	bigint_xor(c,m,block,(int)mlen);
  }
  return 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;
}
Beispiel #11
0
BigInt operator+(const BigInt& x, word y)
   {
   return bigint_add(x, &y, 1, BigInt::Positive);
   }
Beispiel #12
0
BigInt operator+(const BigInt& x, const BigInt& y)
   {
   return bigint_add(x, y.data(), y.sig_words(), y.sign());
   }
Beispiel #13
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);
}
void bii_modexpeven(bigint *dest, bigint a, bigint e, bigint n){
	/*
	 * Returns a**e mod n for the case when n is even. 
	 * This algorithm is from the paper:
	 * Montgomery reduction with even modulus
	 * Koc,C.K.
	 * IEE Proceedings - Computers and Digital Techniques(1994),141(5):314
	 * http://dx.doi.org/10.1049/ip-cdt:19941291
	 */
	 
	bigint q, j, A, E, x1, x2, y,  qinv, tmp1, tmp2;
	bigint_init(&q);
	bigint_init(&j);
	bigint_init(&A);
	bigint_init(&E);
	bigint_init(&x1);
	bigint_init(&x2);
	bigint_init(&y);
	bigint_init(&qinv);
	bigint_init(&tmp1);
	bigint_init(&tmp2);
	
	//n = q * (2**jpow)
	bigint_setval(&q,n);
	uint32_t jpow = 0;
	bigint_setval32(&j,1);
	while(bigint_parity(q)==0){
		bigint_rightshift(&q,1);
		bigint_leftshift(&j,1);
		jpow++;
	}
	
	bigint_divide(&tmp1,&A,a,q);
	
	bii_modexpodd(&x1, A, e, q);
	
	bigint_getsigbits(&A,a,jpow);
	bigint_getsigbits(&E, e, jpow-1);
	
	bii_binarymodpow_powerof2(&x2,A,E,jpow);
	
	bigint_setval32(&tmp1, 1);
	bigint_egcd(q,j,tmp1, &qinv,&tmp2);
	
	bigint_subtract(&tmp1,x2,x1);
	
	bigint_multiply(&tmp2,tmp1,qinv);
	
	bigint_divide(&tmp1,&y,tmp2,j);

	bigint_multiply(&tmp1,q,y);
	bigint_add(dest,x1,tmp1);
	
	bigint_free(&q);
	bigint_free(&j);
	bigint_free(&A);
	bigint_free(&E);
	bigint_free(&x1);
	bigint_free(&x2);
	bigint_free(&y);
	bigint_free(&qinv);
	bigint_free(&tmp1);
	bigint_free(&tmp2);

}