Example #1
0
/**
 * Compute the inverse of a mod m. Or, result = a^-1 mod m.
 */
void bignum_inverse(bignum* a, bignum* m, bignum* result) {
    bignum *remprev = bignum_init(), *rem = bignum_init();
    bignum *auxprev = bignum_init(), *aux = bignum_init();
    bignum *rcur = bignum_init(), *qcur = bignum_init(), *acur = bignum_init();
    
    bignum_copy(m, remprev);
    bignum_copy(a, rem);
    bignum_fromint(auxprev, 0);
    bignum_fromint(aux, 1);
    while(bignum_greater(rem, &NUMS[1])) {
        bignum_divide(qcur, rcur, remprev, rem);
        /* Observe we are finding the inverse in a finite field so we can use
         * a modified algorithm that avoids negative numbers here */
        bignum_subtract(acur, m, qcur);
        bignum_imultiply(acur, aux);
        bignum_iadd(acur, auxprev);
        bignum_imodulate(acur, m);
        
        bignum_copy(rem, remprev);
        bignum_copy(aux, auxprev);
        bignum_copy(rcur, rem);
        bignum_copy(acur, aux);
    }
    
    bignum_copy(acur, result);
    
    bignum_deinit(remprev);
    bignum_deinit(rem);
    bignum_deinit(auxprev);
    bignum_deinit(aux);
    bignum_deinit(rcur);
    bignum_deinit(qcur);
    bignum_deinit(acur);
}
Example #2
0
/**
 * Check whether a is a Euler witness for n. That is, if a^(n - 1)/2 != Ja(a, n) mod n
 */
int solovayPrime(int a, bignum* n) {
    bignum *ab = bignum_init(), *res = bignum_init(), *pow = bignum_init();
    bignum *modpow = bignum_init();
    int x, result;
    
    bignum_fromint(ab, a);
    x = bignum_jacobi(ab, n);
    if(x == -1) bignum_subtract(res, n, &NUMS[1]);
    else bignum_fromint(res, x);
    bignum_copy(n, pow);
    bignum_isubtract(pow, &NUMS[1]);
    bignum_idivide(pow, &NUMS[2]);
    bignum_modpow(ab, pow, n, modpow);
    
    result = !bignum_equal(res, &NUMS[0]) && bignum_equal(modpow, res);
    bignum_deinit(ab);
    bignum_deinit(res);
    bignum_deinit(pow);
    bignum_deinit(modpow);
    return result;
}
Example #3
0
int main(int argc, const char * argv[]) {
    
    char *p=(char*)malloc(BUF_SIZE*sizeof(char));
    printf("\n请输入选择的大素数p:\n");
    scanf("%s",p);
    bignum *p1 = bignum_init();
    bignum_fromstring(p1, p);
    free(p);
    if(probablePrime(p1, ACCURACY))
    {
        printf("p合理");
        bignum *yz = bignum_init();
        bignum_fromint(yz, 3);
        if (bignum_equal(yz,p1)) {
            printf("但p太小不适用!\n");
            return 1;
        }
    }else{
        printf("p不是素数!\n");
        return 1;
    }
    bignum *p2 = bignum_init();
    bignum *temp = bignum_init();
    bignum_fromint(temp, 1);
    bignum_subtract(p2, p1, temp);
    printf("\n请输入选择的本原元α:\n");
    char *a=(char*)malloc(BUF_SIZE*sizeof(char));
    scanf("%s",a);
    bignum *a1 = bignum_init();
    bignum_fromstring(a1, a);
    free(a);
    printf("\n请输入选择的随机整数d:(2<=d<=p-2)\n");
    char *d=(char*)malloc(BUF_SIZE*sizeof(char));
    scanf("%s",d);
    bignum *d1 = bignum_init();
    bignum_fromstring(d1, d);
    free(d);
    bignum *yz0 = bignum_init();
    bignum_fromint(yz0, 2);
    bignum *yz1 = bignum_init();
    bignum_subtract(yz1, p1, yz0);
    if( (bignum_greater(d1, yz0)||bignum_equal(d1, yz0))&&(bignum_greater(yz1,d1)||bignum_equal(yz1,d1)) )
    {
        printf("d合理");
    }else{
        printf("d不合要求!\n");
        return 1;
    }
    printf("\n请输入您的消息x:\n");
    char *x=(char*)malloc(BUF_SIZE*sizeof(char));
    scanf("%s",x);
    bignum *x1 = bignum_init();
    bignum_fromstring(x1, x);
    free(x);
    printf("\n请输入您选择的k:(2<=k<=p-2且k应与p-1互质)\n");
    char *k=(char*)malloc(BUF_SIZE*sizeof(char));
    scanf("%s",k);
    bignum *k1 = bignum_init();
    bignum_fromstring(k1, k);
    free(k);
    if( (bignum_greater(k1, yz0)||bignum_equal(k1, yz0))&&(bignum_greater(yz1,k1)||bignum_equal(yz1,k1)) )
    {
        bignum *yz2 = bignum_init();
        bignum_gcd(k1, p2, yz2);
        if (!bignum_equal(yz2,temp)) {
            printf("k不合要求!\n");
            return 1;
        }
        printf("k合理");
    }else{
        printf("k不合要求!\n");
        return 1;
    }
    
    
    
    bignum *b1 = bignum_init();
    bignum_modpow(a1,d1,p1,b1);
    printf("\n\n所以\n您生成的公钥(p,α,β)为:\t(");
    bignum_print(p1);
    printf(",");
    bignum_print(a1);
    printf(",");
    bignum_print(b1);
    printf(")\n");
    
    printf("您的私钥为:");
    bignum_print(d1);
    printf("\n");
    printf("您发出的消息(x(r,s))为:\t(");
    bignum_print(x1);
    printf(",(");
    bignum *r1 = bignum_init();
    bignum_modpow(a1,k1,p1,r1);
    bignum_print(r1);
    printf(",");
    bignum *s1=bignum_init();
    bignum_multiply(temp, d1, r1);
    
    bignum *temp2 = bignum_init();
    bignum *x2 = bignum_init();
    bignum_copy(x1, x2);
    while (bignum_less(x2, temp)) {
        bignum *add = bignum_init();
        bignum_copy(p2, add);
        bignum_iadd(x2, add) ;
    }
    bignum_subtract(temp2, x2, temp);
//    printf("\ntemp2:");
//    bignum_print(temp2);
//    printf("\t");
//    bignum_print(x2);
//    printf("\t");
//    bignum_print(temp);
//    printf("\n");
    bignum_inverse(k1, p2, temp);//计算a的逆元result = a^-1 mod m
    bignum_multiply(s1, temp, temp2);
    bignum_imodulate(s1, p2);//source = source % modulus
    bignum_print(s1);
    printf("))\n");
    
    bignum *t0 = bignum_init();
    bignum_modpow(a1,x1,p1,t0);
    bignum *t1 = bignum_init();
    bignum_modpow(b1,r1,p1,t1);
    bignum *t2 = bignum_init();
    bignum_modpow(r1,s1,p1,t2);
    bignum *t3 = bignum_init();
    bignum_multiply(t3, t1, t2);
    bignum_imodulate(t3, p1);
    printf("按t=(α^x)mod p,结果为:");
    bignum_print(t0);
    printf("\n按t=(β^r*r^s)mod p,结果为:");
    bignum_print(t3);
    printf("\n");
    if (bignum_equal(t0, t3)) {
        printf("此签名正确有效~\n\n");
    }else{
        printf("此签名错误无效!\n\n");
    }
}
Example #4
0
/**
 * Perform an in place subtract from the source bignum. That is, source -= sub
 */
void bignum_isubtract(bignum* source, bignum* sub) {
    bignum* temp = bignum_init();
    bignum_subtract(temp, source, sub);
    bignum_copy(temp, source);
    bignum_deinit(temp);
}
Example #5
0
/**
 * Main method to demostrate the system. Sets up primes p, q, and proceeds to encode and
 * decode the message given in "text.txt"
 */
int main(void) {
	int i, bytes, len;
	bignum *p = bignum_init(), *q = bignum_init(), *n = bignum_init();
	bignum *phi = bignum_init(), *e = bignum_init(), *d = bignum_init();
	bignum *bbytes = bignum_init(), *shift = bignum_init();
	bignum *temp1 = bignum_init(), *temp2 = bignum_init();
	
	bignum *encoded;
	int *decoded;
	char *buffer;
	FILE* f;
	
	srand(time(NULL));
	
	randPrime(FACTOR_DIGITS, p);
	printf("Got first prime factor, p = ");
	bignum_print(p);
	printf(" ... ");
	getchar();
	
	randPrime(FACTOR_DIGITS, q);
	printf("Got second prime factor, q = ");
	bignum_print(q);
	printf(" ... ");
	getchar();
	
	bignum_multiply(n, p, q);
	printf("Got modulus, n = pq = ");
	bignum_print(n);
	printf(" ... ");
	getchar();
	
	bignum_subtract(temp1, p, &NUMS[1]);
	bignum_subtract(temp2, q, &NUMS[1]);
	bignum_multiply(phi, temp1, temp2); /* phi = (p - 1) * (q - 1) */
	printf("Got totient, phi = ");
	bignum_print(phi);
	printf(" ... ");
	getchar();
	
	randExponent(phi, EXPONENT_MAX, e);
	printf("Chose public exponent, e = ");
	bignum_print(e);
	printf("\nPublic key is (");
	bignum_print(e);
	printf(", ");
	bignum_print(n);
	printf(") ... ");
	getchar();
	
	bignum_inverse(e, phi, d);
	printf("Calculated private exponent, d = ");
	bignum_print(d);
	printf("\nPrivate key is (");
	bignum_print(d);
	printf(", ");
	bignum_print(n);
	printf(") ... ");
	getchar();
	
	/* Compute maximum number of bytes that can be encoded in one encryption */
	bytes = -1;
	bignum_fromint(shift, 1 << 7); /* 7 bits per char */
	bignum_fromint(bbytes, 1);
	while(bignum_less(bbytes, n)) {
		bignum_imultiply(bbytes, shift); /* Shift by one byte, NB: we use bitmask representative so this can actually be a shift... */
		bytes++;
	}

	printf("Opening file \"text.txt\" for reading\n");
	f = fopen("text.txt", "r");
	if(f == NULL) {
		printf("Failed to open file \"text.txt\". Does it exist?\n");
		return EXIT_FAILURE;
	}
	len = readFile(f, &buffer, bytes); /* len will be a multiple of bytes, to send whole chunks */
	
	printf("File \"text.txt\" read successfully, %d bytes read. Encoding byte stream in chunks of %d bytes ... ", len, bytes);
	getchar();
	printf("\n");
	encoded = encodeMessage(len, bytes, buffer, e, n);
	printf("\n\nEncoding finished successfully ... ");
	getchar();
	
	printf("Decoding encoded message ... ");
	getchar();
	printf("\n");
	decoded = decodeMessage(len/bytes, bytes, encoded, d, n);
	printf("\n\nFinished RSA demonstration!");
	
	/* Eek! This is why we shouldn't of calloc'd those! */
	for(i = 0; i < len/bytes; i++) free(encoded[i].data);
	free(encoded);
	free(decoded);
	free(buffer);
	bignum_deinit(p);
	bignum_deinit(q);
	bignum_deinit(n);
	bignum_deinit(phi);
	bignum_deinit(e);
	bignum_deinit(d);
	bignum_deinit(bbytes);
	bignum_deinit(shift);
	bignum_deinit(temp1);
	bignum_deinit(temp2);
	fclose(f);
	
	return EXIT_SUCCESS;
}