import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*; 


public class CryptoAsym
{

public static void main(String args[])
{
	Bob b=new Bob();
	//2*4493+11=8997
	BigInteger publicAlice=new BigInteger("8997");
	BigInteger publicbob=b.setPublicAlice(publicAlice);
	System.out.println();
	System.out.println("Alice calcule msg of Bob whit clef private 4493 and 11 ;");
	System.out.println("msg de bob = "+publicbob.mod(new BigInteger("4493")).mod(new BigInteger("11"))+";");
	
	Eve e=new Eve(publicAlice,publicbob);
	e.attackForceBrute();

}


}

class Eve{
	BigInteger publicAlice,publicBob;
	Eve(BigInteger v,BigInteger v2)	{
		this.publicAlice=v;
		this.publicBob=v2;
	}
	
	public void attackForceBrute()
	{
		System.out.println("primeNumber ;publicAlice.mod(primeNumber) ; publicBob.mod(primeNumber) ; publicBob.mod(primNumber).mod(publicAlice.mod(primeNumber));");
		BigInteger nb,nb2;
		Vector v=initNbPremier(publicAlice);
		for(int i=0;i<v.size();i++)
		{
			nb=(BigInteger)v.get(i);
			nb2=publicAlice.mod(nb);
			if(nb2.compareTo(BigInteger.ZERO)!=0){
				System.out.println(nb+" ;"+nb2+" ;"+publicBob.mod(nb)+" ;"+(publicBob.mod(nb)).mod(nb2)+" ;");
			}else{
				System.out.println(nb+" ;"+nb2+" ;"+publicBob.mod(nb)+" ;-1;");
			}
		}
		
		
	}

/*
this function initializes a vector with all prime numbers <n
*/
private Vector initNbPremier(BigInteger v){
	Vector lst=new Vector();
	BigInteger un	=BigInteger.ONE;
	BigInteger p=un.nextProbablePrime();
	while(p.compareTo(v)==-1)
	{	lst.add(p);
		p=p.nextProbablePrime();
	}
	return lst;
}
		
	
}



class Bob{
Vector listNombrePremier;
Vector listValeurUnitaire;

public BigInteger setPublicAlice(BigInteger v)
{
	System.out.println("publicAlice="+v+";");
	System.out.println("start init ;");
	listNombrePremier=initNbPremier(v);
	listValeurUnitaire =initValUnitaire(listNombrePremier);
	System.out.println("end init ;");
	
	Random r = new Random();
	int num1=r.nextInt(listValeurUnitaire.size()); 
	int num2=r.nextInt(listValeurUnitaire.size()); 
	
	v=v.add(new BigInteger("5"));
	v=v.pow(3);
	v=v.subtract(new BigInteger("125"));//125=5^3
	v=v.add(new BigInteger("7"));//msg of bob
	v=v.add((BigInteger)listValeurUnitaire.elementAt(num1));
	v=v.add((BigInteger)listValeurUnitaire.elementAt(num2));// I know but we can image several solutions I am in the study of the system
	
	//System.out.println("publicBob="+v+";"); //comment line to make the xls file readable
	return v;
}
/*
this function initializes a vector with all prime numbers <n
*/
private Vector initNbPremier(BigInteger v){
	Vector lst=new Vector();
	BigInteger un	=BigInteger.ONE;
	BigInteger p=un.nextProbablePrime();
	while(p.compareTo(v)==-1)
	{
		lst.add(p);
		p=p.nextProbablePrime();
	}
	return lst;
}

/*
this function initializes a vector with the values which allows to modify only one element of the decomposition 
*/
private Vector initValUnitaire(Vector v){
	BigInteger primoriel=BigInteger.ONE;
	BigInteger val,test,nbP,poid;
	Vector v2=new Vector();
	for(int i=0;i<v.size();i++)	{primoriel=primoriel.multiply((BigInteger)v.get(i));}
	
	for(int i=0;i<v.size();i++)
	{
		nbP=(BigInteger)v.get(i);
		val=primoriel.divide(nbP);
		test=val.mod(nbP);
		poid=BigInteger.ONE;
		
		while(test.compareTo(BigInteger.ONE)!=0)
		{
			poid=poid.add(BigInteger.ONE);
			test=val.multiply(poid).mod(nbP);//
		}
		v2.add((primoriel.divide(nbP)).multiply(poid));
		//System.out.println(poid+"    "+nbP+"   "+((primoriel.divide(nbP)).multiply(poid)).mod(nbP)+" "+v2.size());
	}
	return v2;
	
}

}