/*-
 * Copyright (c) 1998-2005 Joao Cabral
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      DHIS(c)  Dynamic Host Information System Release 5.3
 */


#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>

#ifdef QRC
#include<gmp.h>



/* qrc_random() - Generates a random integer of n digits
 *		  n may be up to 1024
 */
void qrc_random(mpz_t x,int n) {

	char buff[1024],temp[128];
	static int seed=0;

	if(!seed) { seed++; srandom(time(NULL)); }
	memset(buff,0,sizeof(buff));	
	memset(temp,0,sizeof(temp));	

	do {
		snprintf(temp,sizeof(temp),"%lu",(unsigned long int)random());
		strlcat(buff,temp,sizeof(buff));
		
	} while(strlen(buff) < n);
	buff[n]='\0';
	
	mpz_set_str(x,buff,10);
	return;
}
		



/* qrc_genkey() - Generates an integer of 100 digits being congruent 
 * 		  to 3 mod 4
 *
 */

void qrc_genkey(mpz_t k) {
	
	int flag=1;

	do {
	

	mpz_t a,b;

	/* Get a prime number */
	do qrc_random(k,100); while(!mpz_probab_prime_p(k,5));

	/* Now see if it is congruent to 3 mod 4 */
	mpz_init(a);mpz_init(b);
	mpz_set_ui(a,4);
	mpz_mod(b,k,a);
	mpz_set_ui(a,3);
	if(!mpz_cmp(a,b)) flag=0;
	mpz_clear(a);
	mpz_clear(b);

	} while(flag);

}



void show_key(mpz_t key,int n,char *s) {
	
	unsigned char buff[1024];
	unsigned char chunk[128];
	unsigned char *cp;
	int i;
	
	mpz_get_str(buff,10,key);
	
	cp=buff;
	for(i=0;i<n;i++) {
		memcpy(chunk,cp,50);
		chunk[50]='\0';
		printf("\t%s\t\t%s\n",s,chunk);
		cp+=50;
	}
}
#endif

int main() {

#ifdef QRC

	mpz_t p,q,n;
	
	mpz_init(p);
	mpz_init(q);
	mpz_init(n);

	qrc_genkey(p);
	show_key(p,2,"AuthP");
	qrc_genkey(q);
	show_key(q,2,"AuthQ");
	mpz_mul(n,p,q);
	show_key(n,4,"AuthN");
	mpz_clear(p);
	mpz_clear(q);
	mpz_clear(n);

#else
	printf("This program was not compiled with QRC support. Exiting ...\n");
#endif
	return(0);
}


syntax highlighted by Code2HTML, v. 0.9.1