Exemple #1
0
//we don't have to bother with making sure that gcd(R,M) == 1 since M is odd.
uberzahl modexp_mm(mm_t & mm, uberzahl base, uberzahl exp, uberzahl M){
	if(!mm.initialized){
		mm.R = next_power(M);
		mm.Rbits = mm.R.bitLength();
		mm.Mprime = (mm.R-M.inverse(mm.R));
		uberzahl z("1");
		uberzahl t("2");
		mm.Rsq = modexp(mm.R,t,M);
		//mm.z_init = mm.R % M;
		mm.z_init = montgomery_reduction(mm.Rsq, M, mm.Mprime, mm.Rbits, mm.R);
		mm.initialized = true;
	}

	//convert into Montgomery space
	uberzahl z = mm.z_init;

	//According to Piazza post we don't even need to calculate the residues with mod
	if(base * mm.Rsq < mm.R*M)
		base = montgomery_reduction(base * mm.Rsq, M, mm.Mprime, mm.Rbits, mm.R);
	else
		base = base * mm.R % M;

	mediumType i = exp.bitLength() - 1;

	while(i >= 0) {
		z = montgomery_reduction(z * z, M, mm.Mprime, mm.Rbits, mm.R);
		if(exp.bit(i) == 1){
			z = montgomery_reduction(z * base , M, mm.Mprime, mm.Rbits, mm.R);
		}
		if(i == 0)
			break;
		i -= 1;
	}
	return montgomery_reduction(z, M, mm.Mprime, mm.Rbits, mm.R);
}
Exemple #2
0
uberzahl originalModExp(uberzahl c, uberzahl a, uberzahl p, uberzahl q){
	//a^c mod pq
	auto start = chrono::steady_clock::now();

	uberzahl z = 1;
	uberzahl n = p*q;

	unsigned int numBits = c.bitLength();
	unsigned int currentBit = 1;

	for (unsigned int i = 0; i < numBits; i++){
		z = (z*z) % n;

		currentBit = c.bit(numBits-i-1);
        if (currentBit == 1)
            z = (z*a) % n;
	}

	if(q > 1){
		auto current = chrono::steady_clock::now();
		auto elapsed = chrono::duration_cast<chrono::duration<double>>(current-start);
		double chrono_time = elapsed.count();
		cerr << "\tSqMultOrig time: " << chrono_time << "\n"; 
	}

	return z;
}
Exemple #3
0
uberzahl modexp_mm_crt(mm_t & mm1, mm_t & mm2, crt_t & crt, uberzahl base, uberzahl exp, uberzahl p, uberzahl q){
	if(!crt.initialized){
		crt.p_inverse = p.inverse(q);
    	crt.q_inverse = q.inverse(p);
    	crt.initialized = true;
	}
	return ( crt_helper(MONTGOMERY,mm1,base,exp,p,q, crt.q_inverse) + crt_helper(MONTGOMERY, mm2, base, exp, q, p, crt.p_inverse) ) % (p * q);
}
Exemple #4
0
uberzahl modexp_crt(crt_t & crt, uberzahl base,  uberzahl exp, uberzahl p, uberzahl q){
    mm_t mm;
    if(!crt.initialized){
    	crt.p_inverse = p.inverse(q);
    	crt.q_inverse = q.inverse(p);
    	crt.initialized = true;
    }
	return ( crt_helper(CLASSIC,mm, base,exp,p,q,crt.q_inverse) + crt_helper(CLASSIC, mm, base, exp, q, p, crt.p_inverse) ) % (p * q);
}
Exemple #5
0
	inline void ReduceZ(){
		// m = (z*NPrime) % R;
		m = (z*NPrime) & (( (uberzahl)1 << (R.bitLength()-1) )-(uberzahl)1);
		t = (z + m*N) >> (R.bitLength()-1);
		if(t >= N) 
			z = (t-N);
		else 
			z = (t);
	}
Exemple #6
0
 void encrypt(const uberzahl &m, uberzahl &r, uberzahl &s)
 {
     //Encrypts m,
     //Modifies r, s to the outputs of the encryption
     uberzahl low = 2;
     uberzahl high = prime - 2;
     uberzahl k = random(low, high);
     r = generator.expm(k, prime);
     s = m * y.expm(k,prime) % prime;
 }
Exemple #7
0
uberzahl modexp(uberzahl base, uberzahl exp, uberzahl n){
	mediumType i = exp.bitLength() - 1;

	uberzahl z((largeType)1);

	while(i >= 0){
		z = (z * z ) % n;
		if(exp.bit(i) == 1)
			z = (z * base) % n;
		if(i == 0)
			break;
		i -= 1;
	}
	return z;
}
Exemple #8
0
uberzahl increment (uberzahl x) {
    // Extract and "increment" least significant 32 bits from x
    uberzahl leastSigBits = betterExtract(x, 0, 31) + 1;
    uberzahl modulo = 4294967296;
    leastSigBits = leastSigBits % modulo;
    // Set least significant bits in x
    for (int i = 0; i < 32; ++i) {
        if(leastSigBits.bit(i) == 0) {
            x.clearBit(i);
        }
        else {
            x.setBit(i);
        }
    }
    return x;
}
Exemple #9
0
    uberzahl decrypt(const uberzahl &r, const uberzahl &s, uberzahl &m)
    {
        //Takes in r, s and decrypts them
        //modifies m to the decrypted ciphertext value
        uberzahl rx = r.expm(x, prime);
        m = s * rx.inverse(prime) % prime;

        return m;
    }
Exemple #10
0
uberzahl chineseModExp2(uberzahl c, uberzahl a, uberzahl p, uberzahl q){ 
	//a^c mod pq
	auto start = chrono::steady_clock::now();
	
	uberzahl dp = c % (p-1);
	uberzahl dq = c % (q-1);

	uberzahl T = q.inverse(p);
	uberzahl S = p.inverse(q);

	uberzahl m1 = originalModExp(dp,a,p,1);
	uberzahl m2 = originalModExp(dq,a,q,1);
    
	uberzahl m = (m1*q*T + m2*p*S) % (p*q);

	auto current = chrono::steady_clock::now();
	auto elapsed = chrono::duration_cast<chrono::duration<double>>(current-start);
	double chrono_time = elapsed.count();
	cerr << "\tSqMult_CRT time: " << chrono_time << "\n"; 
    
	return m;
}
Exemple #11
0
vector<uberzahl> Speck::generateKeys(){
	vector<uberzahl> keySeed;
	
	uberzahl lowerBound = two.exp(n - 1) - one;
	uberzahl upperBound = two.exp(n + 1) - one;
	
	for(int i = 0; i < m; i++){
		keySeed.push_back(random(lowerBound, upperBound) & modulus);
	}
	
	keyExpansion(keySeed);
	
	return keySeed;
}
uberzahl multiply (uberzahl x, uberzahl y) {
    uberzahl z, v = y, r = "299076299051606071403356588563077529600";
    for (int i = 127; i >= 0; --i) {
        // Set z block
        if (x.bit(i) == 0) {
            z = z;
        }
        else {
            z = z ^ v;
        }
        // Set v block
        if (v.bit(0) == 0) {
            v = v >> 1;
        }
        else {
Exemple #13
0
 elGamal()
 {
     //Initializes all of the required values using a 128-bit prime
     srand(time(NULL));
     uberzahl temp = 2;
     minPrime = temp.exp(126);
     temp = 2;
     maxPrime = temp.exp(127);
     prime = getPrime(minPrime, maxPrime);
     uberzahl low = 2;
     uberzahl high = prime - 2;
     x = random(low, high);
     generator = gen(prime);
     y = generator.expm(x, prime);
 }
Exemple #14
0
int main(int argc, char **argv){
     srand(time(0));
    //uberzahl new_key = generate();
    vector<uberzahl> k;
    vector<uberzahl> plaintext_vector;
    vector<uberzahl> ciphertext_vector;
    uberzahl ciphertext;
    uberzahl plaintext;
    uberzahl zero = "0";
    if(strcmp(argv[1],"encrypt") == 0)
    {
        key = argv[2];
        if(key.bitLength() > 256)
        {
            cout << "key bit length is more than 256 bit, please see README file." << endl;
            return 0;
        }
        plaintext = argv[3];
        //For test the result
        // k.push_back(0x1f1e1d1c1b1a1918);
        // k.push_back(0x1716151413121110);
        // k.push_back(0x0f0e0d0c0b0a0908);
        // k.push_back(0x0706050403020100);
        // key = (k[0] << (3*n)) | (k[1] << (2*n)) | (k[2] << (n)) | k[3];
        // plaintext = 0x74206e69206d6f6f;
        // plaintext = (plaintext << n) | 0x6d69732061207369;
        int num_block = 0;
        uberzahl result;
        uberzahl temp;
        while(plaintext != zero)
        {
            temp = plaintext & take_128_bit;
            plaintext = plaintext >> (2*n);
            result = encrypt(temp, key);
            ciphertext = ciphertext | (result << num_block*(2*n));
            num_block++;
        }
        cout << "The ciphertext is: " << endl;
        cout << ciphertext << endl;
    }
Exemple #15
0
//x is a random number 0 < x < q - private key
void pqgGen(uberzahl & p, uberzahl & q, uberzahl & g) {
	//find a L-bit long p prime
  /*  uberzahl rand;
    p = 2;
   	rand.random(L);
   	string p_string = rand.convert_to_string();
   	mpz_class p_mpz(p_string, 10);
   	while(p.bitLength() != L) {
   		mpz_nextprime(p_mpz.get_mpz_t(), p_mpz.get_mpz_t());
   		p_string = p_mpz.get_str(10);
   		p = p_string.c_str();
   	}
   	cout<<p<<endl;
   	*/


   	//find an N bit q such that p-1 divides q
//method 1
/*	rand.random(N); 	
	string q_string = rand.convert_to_string();
   	mpz_class q_mpz(q_string, 10);
   	while(q.bitLength() != N || (((p-1)%q) != zero)) {
   		mpz_nextprime(q_mpz.get_mpz_t(), q_mpz.get_mpz_t());
   		q_string = q_mpz.get_str(10);
   		q = q_string.c_str();
   		cout<<1<<endl;
   	}
   	cout<<q<<endl;
*/
//method2
/*   	uberzahl two = 2;
   	uberzahl lower_bound = two.exp(N-1);
   	q = lower_bound;
   	mpz_class q_mpz(q.convert_to_string(), 10);
   	string q_string;
   	while(((p-1) % q) != zero) {
   		mpz_nextprime(q_mpz.get_mpz_t(), q_mpz.get_mpz_t());
   		q_string = q_mpz.get_str(10);
   		q = q_string.c_str();
   		if (q.bitLength() != N) {
   			cout<<"no such q exists"<<endl;
   			exit(1);
   		}
   		cout<<1<<endl;
   	}
   	cout<<q<<endl;
   	cout<<2<<endl;
*/



   	string p_string, q_string;
   	mpz_class p_mpz;
   	uberzahl rand;
   	bool none = 0;
   	while(1) {
   		//find random N bit prime q
   		do {
	   		rand.random(N);
	   		q = nextprime(rand, 10);
	   		q_string = q.convert_to_string();
	   		q = q_string.c_str();
	   	}
   		while (q.bitLength() != N);

   		mpz_class q_mpz(q_string, 10);


   		mpz_class mult_mpz = 3;
   		while (1) {
   			mpz_class product_mpz = mult_mpz * q_mpz;

   			//if product is odd -> no way product+1 is prime
   			if ((product_mpz % 2) == one) {
   				mult_mpz = mult_mpz + 1;
   				continue;
   			}
   			//this number should be p-1
   			mpz_class product_1_mpz = product_mpz + 1;
   			//check if p is a prime
   			uberzahl product = (product_mpz.get_str(10)).c_str();
   			uberzahl product_1 = (product_1_mpz.get_str(10)).c_str();



   			//missing 1 bit
   			if (product.bitLength() == L-1) {
   				mult_mpz = mult_mpz * 2;
   			}
   			//increment mult if mult not big enough
   			if (product.bitLength() < L) {
   				double diff = L - product.bitLength();
   				mult_mpz = mult_mpz * diff;
   			}

   			//increment multi if mult is not big enough
   			//mult too high? find other q
   			if (product.bitLength() > L) {
   				none = 1;
   				break;
   			}

   			//if it is of bitlength N --> check product if it is a prime
   			if (mpz_probab_prime_p(product_1_mpz.get_mpz_t(), 10) > 0) {
   				//found a right p
   				p_string = product_1_mpz.get_str(10);
   				p = p_string.c_str();
   				break;
   			}
   			else {
	   				mult_mpz = mult_mpz + 1;
	   		}
   		}	


   		if (none) {
   			none = 0;
   			continue;
   		}
   		else 
   			break;

   	}



//    while (q.bitLength() != N || ((p-1) % q) != zero ) {
//    	rand.random(N);
//    	uberzahl rand = random(lower_bound, upper_bound);
//     	q = nextprime(rand, 20); // this is gonna EVEN slower
//	} 



	//find g with multiplicative order modulo p = q
	uberzahl h = 20;
	g = 1;
	while (g == 1) {
		uberzahl c = ((p-1)/q);
		g = h.expm(c, p);
		h = h + 1;
		if (h == (p-1)) {
			cout<<"no such generator g"<<endl;
			exit(1);
		}
	}

}