// ÀÌ»ê´ë¼ö¸¦ ÀÌ¿ëÇÏ´Â ¿µÁö½ÄÁõ¸í ¹æ¹ý // Áõ¸íÀÚ A´Â Å°½Ö (xa,ya)¸¦ °¡Áö°í ÀÖÀ½. ya=g^xa mod p // °ËÁõÀÚ B(¼­¹ö)´Â Áõ¸íÀÚ AÀÇ ½ÅºÐÀ» È®ÀÎÇÏ·Á°í ÇÔ // Áõ¸íÀÚ A(»ç¿ëÀÚ)´Â ÀÚ½ÅÀÇ °³ÀÎÅ° xa¸¦ ³ëÃâ½ÃÅ°Áö ¾ÊÀ¸¸é¼­ ÀÚ½ÅÀÇ ½ÅºÐÀ» Áõ¸íÇÏ°íÀÚ ÇÔ import java.math.BigInteger; import java.util.Scanner; import java.security.*; public class ZKPSchnorrNI { public static void main(String[] args) throws NoSuchAlgorithmException { Scanner s; s = new Scanner(System.in); // ------------------- ½Ã½ºÅÛ ÆĶó¸ÞÅÍ »ý¼º ---------------------- System.out.println("1. ½Ã½ºÅÛ ÆĶó¸ÞÅÍ »ý¼º "); System.out.print("qÀÇ ºñÆ®¼ö¸¦ ÀÔ·ÂÇϼ¼¿ä (160)>> "); int blq = s.nextInt(); System.out.print("pÀÇ ºñÆ®¼ö¸¦ ÀÔ·ÂÇϼ¼¿ä (1024)>> "); int blp = s.nextInt(); BigInteger one = new BigInteger("1"); BigInteger two = new BigInteger("2"); BigInteger q, qp, p, a, g, xa, ya; int certainty = 10; // ¼Ò¼öÀÏ È®·üÀ» Á¤ÇÑ´Ù. SecureRandom sr = new SecureRandom(); // ³­¼ö¸¦ »ý¼ºÇÑ´Ù. q = new BigInteger(blq, certainty, sr); // blq ºñÆ®ÀÇ ¼Ò¼ö System.out.println("q = "+q); // p = 2*q*qp+1 ÀÎ ¼Ò¼ö p¸¦ ¼±Åà int i=0; qp = new BigInteger(blp-blq, certainty, sr); // ºñÆ®¼ö°¡ blp-blqÀÎ ¼Ò¼ö¸¦ ³­¼ö·Î »ý¼º do { p = q.multiply(qp).multiply(two).add(one); // p = 2*q*qp+1 ¸¦ °è»ê if (p.isProbablePrime(certainty)) break; // ÀÌ·¸°Ô °è»êµÈ p°¡ ¼Ò¼öÀÌ¸é ¼±Åà qp = qp.nextProbablePrime(); // ¾Æ´Ï¸é ´Ù¸¥ ¼Ò¼ö¸¦ ½Ãµµ i++; } while (true); System.out.println("loop = "+i); System.out.println("p = "+p); System.out.println("pÀÇ bit¼ö = "+p.bitLength()); System.out.println(); // g^q mod p = 1 ¸¦ ¸¸Á·ÇÏ´Â »ý¼ºÀÚ g¸¦ ¼±Åà i=0; a = new BigInteger(blp-1, sr); // blp ºñÆ®ÀÇ ¼ö¸¦ ³­¼ö·Î »ý¼º do { g = a.modPow((p.subtract(one)).divide(q),p); // g = a^((p-1)/q) mod p = a^(2*qp) mod p ¸¦ °è»ê if(g.modPow(q, p).equals(one)) break; // g^q mod p = 1 À̸é g¸¦ »ý¼ºÀÚ·Î ¼±ÅÃÇÏ°í break a = a.add(one); // ¾Æ´Ï¸é ´Ù¸¥ ¼ö¸¦ ½Ãµµ i++; } while (true); System.out.println("loop = "+i); System.out.println("g = "+g); System.out.println("q|p-1 = "+(p.subtract(one)).mod(q)); // (p-1)Àº q·Î ³ª´©¾î ¶³¾îÁö´Â ¼öÀÎÁö È®ÀÎ System.out.println("g^q mod p = "+g.modPow(q, p)); // ÀÌ °ªÀº 1ÀÌ µÇ¾î¾ß ÇÔ System.out.println(); // ------------------- Áõ¸íÀÚÀÇ Å°½Ö »ý¼º ---------------------- System.out.println("2. Áõ¸íÀÚ AÀÇ Å°½Ö »ý¼º "); xa = new BigInteger(blq, sr); // °³ÀÎÅ°¸¦ ³­¼ö·Î ¼±Åà ya = g.modPow(xa, p); // °ø°³Å° °è»ê System.out.println("AÀÇ °³ÀÎÅ° : x = "+ xa); System.out.println("AÀÇ °ø°³Å° : y = g^x mod p = "+ ya); System.out.println(); // ------------------- ¿µÁö½Ä Áõ¸í ÇÁ·ÎÅäÄÝ ---------------------- System.out.println("3. Áõ¸íÀÚ AÀÇ ¿µÁö½Ä Áõ¸í "); BigInteger t = new BigInteger(blq, sr); // Commitment¸¦ À§ÇÑ ³­¼ö ¼±Åà BigInteger R = g.modPow(t, p); // Commitment°ª R °è»ê MessageDigest md = MessageDigest.getInstance("SHA1"); md.update(ya.byteValue()); md.update(R.byteValue()); byte[] digest = md.digest(); // H(ya,R) °è»ê BigInteger u = new BigInteger(1, digest); BigInteger w = t.subtract(u.multiply(xa).mod(q)).mod(q); System.out.println("R = "+ R); System.out.println("w = "+ w); System.out.println("A ---> B : (R,w)"); System.out.println(); System.out.println("4. °ËÁõÀÚ BÀÇ °ËÁõ ÀÛ¾÷ "); MessageDigest md1 = MessageDigest.getInstance("SHA1"); md1.update(ya.byteValue()); md1.update(R.byteValue()); byte[] digest1 = md1.digest(); // H(ya,R) °è»ê BigInteger u1 = new BigInteger(1, digest1); BigInteger R1 = g.modPow(w,p).multiply(ya.modPow(u,p)).mod(p); System.out.println("B computes R1 = g^w ya^u mod p = "+ R1); if(R1.equals(R)) System.out.println("Yes: R=R1À̹ǷΠÁõ¸íÀÚ AÀÇ ½ÅºÐÀÌ È®ÀεǾú½À´Ï´Ù."); else System.out.println("No: R!=R1À̹ǷΠÁõ¸íÀÚ AÀÇ ½ÅºÐÀ» È®ÀÎÇÒ ¼ö ¾ø½À´Ï´Ù."); } }