10.07.2015 Views

An implementation of RSA and ElGamal PKCs using Java ...

An implementation of RSA and ElGamal PKCs using Java ...

An implementation of RSA and ElGamal PKCs using Java ...

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

- "Sociálne náklady"- "Kultúra/mentalita"- "nenachádzam žiadne zodpovedajúcepracovné sily "O nahradení pracovníkov z vlasti inýmipracovníkmi z nových členských štátov EÚby ste uvažovali v prípade …Spolupracujete so subdodavateľmi znových členských štátov EÚ?Myslíte si, že rozšírenie EÚ v roku 2004prinieslo Vášmu podniku nové možnostialebo ohrozenia?Zamestnávate pracovníkov z novýchčlenských štátov EÚ?Vývoj počtu zamestnancov…'- zo Slovenska (N=437)- z Česka (n=437)- z Maďarska (n=437)- z iných „nových“ štátov EÚ (N=437)- z krajín bývalej Juhoslávie resp. zTurecka (N=437)- z iných štátov (N=437)FAMO II - Podnikový dotazník - Rakúska/Viedeň (N=1501)hovorí pre 16%hovorí proti 6%ani/ani 71%Neviem / žiadna odpoved 7%hovorí pre 10%hovorí proti 18%ani/ani 65%Neviem / žiadna odpoved 7%hovorí pre 18%hovorí proti 8%ani/ani 67%Neviem / žiadna odpoved 7%učni 1%pomocné sily / zaučení a nevyučení pracovníci 3%kvalifikovaní/é pracovníci/čky 6%zamestnanci bez maturity 2%zamestnanci s maturitou 2%zamestnaní absolventi/tky vysokej školy 1%nenahradia sa 88%Áno 19%Nie 79%Neviem / žiadna odpoved 2%nové možnosti 41%ohrozenia 15%ani/ani 42%neviem 3%Áno 29%Nie 70%Neviem / žiadna odpoved 1%Počet sa zvýšil 5%Počet zostal rovnaký 38%Počet sa znížil 4%nezamestnávam žiadnych 51%neviem 3%Počet sa zvýšil 3%Počet zostal rovnaký 32%Počet sa znížil 3%nezamestnávam žiadnych 59%neviem 4%Počet sa zvýšil 2%Počet zostal rovnaký 41%Počet sa znížil 4%nezamestnávam žiadnych 50%neviem 4%Počet sa zvýšil 6%Počet zostal rovnaký 53%Počet sa znížil 4%nezamestnávam žiadnych 35%neviem 3%Počet sa zvýšil 6%Počet zostal rovnaký 50%Počet sa znížil 6%nezamestnávam žiadnych 34%neviem 4%Počet sa zvýšil 4%Počet zostal rovnaký 47%Počet sa znížil 4%nezamestnávam žiadnych 42%neviem 4%9


}for (int i=0; i < nBlks; i++)for (int j=0; j < blkSz; j++)ba[i][j] = msg[i*blkSz + j];return ba;//put a series <strong>of</strong> encoded blocks back into a single array <strong>of</strong> byytes.//The BigInt might be smaller than the block size, so fill the array//from the rear <strong>of</strong> each block.protected static byte[] unblock(byte[][] ba, int blkSz) {byte[] ub = new byte [ba.length * blkSz];for (int i=0; i= 0) {ub[i*blkSz+j] = ba[i][k];k--; j--;}}return ub;}public static void display(byte[] b) {String digits = "0123456789abcdef";for (int i=0; i>> 4));System.out.print(digits.charAt(b[i] & 0x0f));}System.out.println(" - "+ b.length + " bytes");}//Strip <strong>of</strong>f the extra byte containing the sign bit (always 0 here)//returned by toByteArray() (ref D Bishop p123)protected static byte[] getBytes(BigInteger bg) {byte[] bts = bg.toByteArray();if (bg.bitLength()%8 != 0)return bts;else {byte[] sbts = new byte[bg.bitLength()/8];System.arraycopy(bts, 1, sbts, 0, sbts.length);return sbts;}}public abstract byte[] transform(byte[] msg);} //end class MyTransformer---------------------------------------------------------import java.math.BigInteger;public class My<strong>RSA</strong>Encrypter extends MyTransformer {private BigInteger e, n;public My<strong>RSA</strong>Encrypter(BigInteger e, BigInteger n) {this.e = e; this.n = n;System.out.println("Encryption key:");System.out.println("n = " + n.toString(16));System.out.println("e = " + e.toString(16));}11


public byte[] transform(byte[] msg) {long startTm = System.currentTimeMillis();int blkSz = (n.bitLength() - 1)/8;byte[][] ba = block(pad(msg, blkSz), blkSz);BigInteger msgBlkInt;System.err.println("" + ba.length + " blocks");for (int i=0; i


*/import java.math.BigInteger;import java.security.SecureR<strong>and</strong>om;import java.util.*;public class GeneratorFactory {private int minBits, crtty;private SecureR<strong>and</strong>om srng;private BigInteger p, g;private static final BigIntegerZERO = BigInteger.ZERO, ONE = BigInteger.ONE,TWO = ONE.add(ONE), THREE = TWO.add(ONE);//Constructorspublic GeneratorFactory (int bits) { this(bits, 300); }public GeneratorFactory (int bits, int crtty) {this(bits, crtty, new SecureR<strong>and</strong>om());}public GeneratorFactory (int bits, int crtty, SecureR<strong>and</strong>om sr) {if (bits < 512)System.err.println("WARNING: Safe primes should be >= 512 bits long");this.minBits = bits;this.crtty = crtty;this.srng = sr;}System.out.printf("Making a safe prime <strong>of</strong> at least %d bits...\n", bits);long startTm = System.currentTimeMillis(), endTm;makeSafePrime<strong>An</strong>dGenerator();endTm = System.currentTimeMillis();System.err.printf("Generating p, g took %d ms\n", endTm - startTm);System.out.printf("p = %x (%d bits)\n", p, p.bitLength());System.out.printf("g = %x (%d bits)\n", g, g.bitLength());/* Method to make a safe prime (stored in this.p)* <strong>and</strong> a generator (this.g) mod p. Uses method suggested by D Bishop:* (1) Find a safe prime p = 2rt + 1 where r is smallish (~10^9), t prime;* (2) Obtain the prime factorization <strong>of</strong> p-1 (quickish in view <strong>of</strong> (1));* (3) Repeatedly make a r<strong>and</strong>om g, 1 < g < p until* for each prime factor f <strong>of</strong> p-1, g^((p-1)/f) is incogruent to 1 mod p.*/public void makeSafePrime<strong>An</strong>dGenerator() {BigInteger r = BigInteger.valueOf(0x7fffffff),t = new BigInteger(minBits, crtty, srng);//(1) make prime pdo {r = r.add(ONE);p = TWO.multiply(r).multiply(t).add(ONE);} while (!p.isProbablePrime(crtty));//(2) obtain prime factorization <strong>of</strong> p-1 = 2rtHashSet factors = new HashSet();factors.add(t); factors.add(TWO);if (r.isProbablePrime(crtty))factors.add(r);elsefactors.addAll(primeFact(r));//We have set <strong>of</strong> prime factors <strong>of</strong> p-1.//Now (3) look for a generator mod p. Repeatedly make13


a r<strong>and</strong>om g, 1 < g < p, until for each prime factor f <strong>of</strong> p-1,// g^((p-1)/f) is incogruent to 1 mod p.BigInteger pMinusOne = p.subtract(ONE), z, lnr;boolean isGen;do {isGen = true;g = new BigInteger(p.bitLength()-1, srng); //r<strong>and</strong>om, < pfor (BigInteger f: factors) { //check cond on g for each fz = pMinusOne.divide(f);lnr = g.modPow(z, p);if (lnr.equals(ONE)) {isGen = false;break;}}} while (!isGen);// Now g is a generator mod p} // end <strong>of</strong> makeSafePrime<strong>An</strong>dGenerator() methodpublic static HashSet primeFact(BigInteger n) {BigInteger nn = new BigInteger(n.toByteArray()); //clone nHashSet factors = new HashSet();BigInteger dvsr = TWO,dvsrSq = dvsr.multiply(dvsr);while (dvsrSq.compareTo(nn)


}//Warning: a large prime factor will take a long time to find!HashSet factors = primeFact(pMinusOne);boolean isGen = true;for (BigInteger f: factors) { //check cond on g for each fz = pMinusOne.divide(f);if (g.modPow(z, p).equals(ONE)) {isGen = false;System.err.println("g is not a generator mod p.");break;}}return isGen;}//Test driverpublic static void main(String[] args) {int bitLen = 512;if (args.length > 0) {try {bitLen = Integer.parseInt(args[0]);} catch(NumberFormatException ex) {bitLen = 512;}}GeneratorFactory fact = new GeneratorFactory(bitLen);BigInteger p = fact.getP(), g = fact.getG();System.out.println("p probable prime: "+ (p.isProbablePrime(300)?"yes":"no"));if (g.compareTo(p) < 0)System.out.println("g < p");elseSystem.out.println("p divides g: " + (g.mod(p).equals(ZERO)?"yes":"no"));}/* Note on generator test:* If p is prime <strong>and</strong> not a factor <strong>of</strong> g then |g|_p is in general a divisor <strong>of</strong>* p-1 (see eg Bishop prop 37 or Apostol thm 10.1). So if g is NOT* a generator mod p then |g|_p is a PROPER divisor <strong>of</strong> p-1.* In that case, if F is the set <strong>of</strong> all prime factors <strong>of</strong> p-1 then some* (p-1)/f, f in F, will be a multiple <strong>of</strong> |g|_p <strong>and</strong> hence fail the test (3).*/---------------------------------------------------------import java.math.BigInteger;public class GenTest {public static void main(String[] args) {boolean isGen = GeneratorFactory.isGenerator(new BigInteger(args[0], 16), new BigInteger(args[1], 16), 300);System.err.println(args[1] + (isGen?" is ":" is not ")+ "a generator mod "+ args[0]);}}---------------------------------------------------------import java.math.BigInteger;import java.security.SecureR<strong>and</strong>om;import java.io.*;public class My<strong>ElGamal</strong> {private BigInteger p, g, a, r, pMinus2;15


private SecureR<strong>and</strong>om srng;private static final int CRTTY = 300;private static final String configPath = "My<strong>ElGamal</strong>Config.txt";private static final BigIntegerZERO = BigInteger.ZERO, ONE = BigInteger.ONE,TWO = ONE.add(ONE), THREE = TWO.add(ONE);//Two constructors -//Option 1: generate a r<strong>and</strong>om system <strong>using</strong> specified key size; save config:public My<strong>ElGamal</strong>(int kSz) { //R<strong>and</strong>om system with at least (kSz) bits in psrng = new SecureR<strong>and</strong>om();GeneratorFactory fact = new GeneratorFactory(kSz, CRTTY, srng);p = fact.getP(); pMinus2 = p.subtract(TWO);g = fact.getG();//a should be a r<strong>and</strong>om integer in range 1 < a < p-1BigInteger pmt = p.subtract(THREE);a = (new BigInteger(p.bitLength(), srng)).mod(pmt).add(TWO);r = g.modPow(a, p);saveConfig();}//Option 2 (default) -- construct a system from saved values:public My<strong>ElGamal</strong>() {srng = new SecureR<strong>and</strong>om();try {BufferedReader in = new BufferedReader(new FileReader(configPath));p = new BigInteger(in.readLine(), 16);g = new BigInteger(in.readLine(), 16);a = new BigInteger(in.readLine(), 16);in.close();} catch (NumberFormatException ex) {System.err.println("Invalid data in config file - " + ex);System.exit(1);} catch (EOFException ex) {System.err.println("Unexpected end <strong>of</strong> config file");System.exit(1);} catch (IOException ex) {System.err.println("Trouble reading config file");System.exit(1);} catch (NullPointerException ex) {System.err.println("Trouble reading string from config file - " +ex);System.exit(1);}if (!p.isProbablePrime(CRTTY)) {System.err.println(p.toString(16) + " is not prime. Terminating.");System.exit(1);}if (g.mod(p).equals(ZERO)) {System.err.println(p.toString(16) + " divides " + g.toString(16) +". Terminating.");System.exit(1);}//That g is truely a generator mod p will take inordinately long to//check if p-1 has a large prime factor.//Notwithstading this, we have a system if we have go to here.pMinus2 = p.subtract(TWO);r = g.modPow(a, p);}public String toString() {String dspStg = "p = " + p.toString(16);16


}String nl = dspStg.length() > 80? "\n\n": "\n";dspStg += nl + "g = " + g.toString(16);dspStg += nl + "a = " + a.toString(16);dspStg += nl + "r = " + r.toString(16);return dspStg;public void saveConfig() {try {PrintWriter out = new PrintWriter(new FileWriter(configPath));out.println(p.toString(16)); out.println(g.toString(16));out.println(a.toString(16));out.close();} catch (IOException ex) {System.err.println("Could not save the config");}}public BigInteger getP() { return p; }public BigInteger getG() { return g; }public BigInteger getR() { return r; }//A message block is considered a BigInteger.//Returns pair <strong>of</strong> BigIntegers comprising the <strong>ElGamal</strong> cipher-"text"public BigInteger[] encrypt(BigInteger m) {BigInteger k = new BigInteger(p.bitLength(), srng);k = k.mod(pMinus2).add(ONE);BigInteger[] cipher = new BigInteger[2];cipher[0] = g.modPow(k, p);cipher[1] = r.modPow(k, p).multiply(m).mod(p);return cipher;}public BigInteger decrypt(BigInteger c0, BigInteger c1) {BigInteger c = c0.modPow(a, p).modInverse(p); //c0^-a mod preturn c.multiply(c1).mod(p);}public My<strong>ElGamal</strong>Encrypter getEncrypter() {return new My<strong>ElGamal</strong>Encrypter(p, g, r);}public My<strong>ElGamal</strong>Decrypter getDecrypter() {return new My<strong>ElGamal</strong>Decrypter(p, a);}/* Test bed* Run with single integer argument, kSz, to generate a system <strong>and</strong> save it.* Run with no arguments to initialise a system from a saved config,* generate a r<strong>and</strong>om BigInteger < p, encrypt it <strong>and</strong> decrypt it again.*/public static void main(String[] args) {if (args.length > 0) {new My<strong>ElGamal</strong>(Integer.parseInt(args[0]));System.err.println("Config saved in " + configPath);} else {My<strong>ElGamal</strong> sys = new My<strong>ElGamal</strong>();SecureR<strong>and</strong>om sr = new SecureR<strong>and</strong>om();BigInteger p = sys.getP(),msg = (new BigInteger(p.bitLength(), sr)).mod(p);System.out.println("Message = " + msg.toString(16));17


BigInteger[] c = sys.encrypt(msg);System.out.println("Cipher: c0 = " + c[0].toString(16));System.out.println("Cipher: c1 = " + c[1].toString(16));BigInteger d = sys.decrypt(c[0], c[1]);System.out.println("Decrypted = " + d.toString(16));}}} // end My<strong>ElGamal</strong> class---------------------------------------------------------import java.math.BigInteger;import java.io.*;public class My<strong>ElGamal</strong>Tst {public static void main(String[] args) throws IOException {if (args.length < 2) {System.out.println("Usage: java My<strong>ElGamal</strong>Tst [e|d] ");return;}My<strong>ElGamal</strong> pkc = new My<strong>ElGamal</strong>();MyTransformer trfmr;if (args[0].charAt(0) == 'e')trfmr = pkc.getEncrypter();else if (args[0].charAt(0) == 'd')trfmr = pkc.getDecrypter();else {System.out.println(pkc);System.out.println("No encrypt/decrypt option specified");return;}File inFile = new File(args[1]);int inputLength = (int)(inFile.length()/100 + 1)*100;BufferedInputStream inStrm = new BufferedInputStream(new FileInputStream(inFile));BufferedOutputStream outStrm = new BufferedOutputStream(new FileOutputStream(args[1]+".out"));System.err.println("Buffer size = " + inputLength);byte[] buf = new byte[inputLength];int nBytes = inStrm.read(buf);System.out.println("\n" + nBytes + " bytes read");byte[] msg = new byte[nBytes];System.arraycopy(buf, 0, msg, 0, nBytes);byte[] tmsg = trfmr.transform(msg);System.out.println("" + tmsg.length + " bytes produced");outStrm.write(tmsg);inStrm.close();outStrm.close();}}---------------------------------------------------------public class MyTransformersame as <strong>RSA</strong>’s---------------------------------------------------------18


import java.math.BigInteger;import java.security.SecureR<strong>and</strong>om;public class My<strong>ElGamal</strong>Encrypter extends MyTransformer {private BigInteger p, g, r, pMinus2;private SecureR<strong>and</strong>om srng;private static final BigInteger ONE = BigInteger.ONE, TWO = ONE.add(ONE);//Assume p is prime, g is a gen mod p, r = g^a mod p (a = pvt key)public My<strong>ElGamal</strong>Encrypter(BigInteger p, BigInteger g, BigInteger r) {srng = new SecureR<strong>and</strong>om();this.p = p; this.g = g; this.r = r;pMinus2 = p.subtract(TWO);System.out.println("Encryption key:");System.out.println("p = " + p.toString(16));System.out.println("g = " + g.toString(16));System.out.println("r = " + r.toString(16));}public byte[] transform(byte[] msg) {long startTm = System.currentTimeMillis();int blkSz = (p.bitLength() - 1)/8;byte[][] ba = block(pad(msg, blkSz), blkSz);byte[][] ba2 = new byte[2*ba.length][];BigInteger m, c0, c1, k;System.err.println("" + ba.length + " blocks");for (int i=0; i


long startTm = System.currentTimeMillis();int blkSz = (p.bitLength()-1)/8 + 1;byte[][] ba2 = block(msg, blkSz);byte[][] ba = new byte[ba2.length/2][];BigInteger m, c0, c1, c;System.err.println("" + ba.length + " blocks");for (int i=0; i

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!