// ºñ¹Ð¼­¸í ±â¹ý (Secret Signature Scheme) // Byoungcheon Lee, Kim-Kwang Raymond Choo, Jeongmo Yang, and Seungjae Yoo, Secret Signatures: How to Achieve Business Privacy Efficiently?, WISA 2007, LNCS 4867, pp. 30-47, 2007. // http://cris.joongbu.ac.kr/publication/SS-WISA2007.pdf // ÀÏ¹Ý ÀüÀÚ¼­¸íÀº ¼­¸íÀÚÀÇ °ø°³Å°¸¦ ¾Ë°í ÀÖÀ¸¸é ´©±¸³ª °ËÁõ °¡´ÉÇÔ. ºñ¹Ð¼­¸íÀº ¼­¸íÀÚ A°¡ ƯÁ¤ ¼ö½ÅÀÚ B¸¸ °ËÁõÇÒ ¼ö ÀÖµµ·Ï Ưº°ÇÏ°Ô Á¦°øÇÏ´Â ÀüÀÚ¼­¸íÀÓ. import java.math.BigInteger; import java.util.Scanner; import java.security.*; public class SecretSig { public static void main(String[] args) throws NoSuchAlgorithmException { Scanner s; s = new Scanner(System.in); System.out.println("ºñ¹Ð¼­¸í ±â¹ý (Secret Signature Scheme) "); System.out.println("Byoungcheon Lee, Kim-Kwang Raymond Choo, Jeongmo Yang, and Seungjae Yoo, Secret Signatures: How to Achieve Business Privacy Efficiently?, WISA 2007, LNCS 4867, pp. 30-47, 2007."); System.out.println("http://cris.joongbu.ac.kr/publication/SS-WISA2007.pdf"); System.out.println("ÀÏ¹Ý ÀüÀÚ¼­¸íÀº ¼­¸íÀÚÀÇ °ø°³Å°¸¦ ¾Ë°í ÀÖÀ¸¸é ´©±¸³ª °ËÁõ °¡´ÉÇÔ. ºñ¹Ð¼­¸íÀº ¼­¸íÀÚ A°¡ ƯÁ¤ ¼ö½ÅÀÚ B¸¸ °ËÁõÇÒ ¼ö ÀÖµµ·Ï Ưº°ÇÏ°Ô Á¦°øÇÏ´Â ÀüÀÚ¼­¸íÀÓ. "); System.out.println(); // ------------------- Å°»ý¼º ---------------------- System.out.println("1. Å°»ý¼º (Key Generation) "); 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; BigInteger xa, ya; // ¼­¸íÀÚ(¼Û½ÅÀÚ)ÀÇ Å°½Ö BigInteger xb, yb; // °ËÁõÀÚ(¼ö½ÅÀÚ)ÀÇ Å°½Ö 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(); xa = new BigInteger(blq, sr); // °³ÀÎÅ°¸¦ ³­¼ö·Î ¼±Åà ya = g.modPow(xa, p); // °ø°³Å° °è»ê xb = new BigInteger(blq, sr); // °³ÀÎÅ°¸¦ ³­¼ö·Î ¼±Åà yb = g.modPow(xb, p); // °ø°³Å° °è»ê System.out.println("¼­¸íÀÚ(¼Û½ÅÀÚ) AÀÇ °³ÀÎÅ°: xa = "+ xa); System.out.println("¼­¸íÀÚ(¼Û½ÅÀÚ) AÀÇ °ø°³Å°: ya = "+ ya); System.out.println("°ËÁõÀÚ(¼ö½ÅÀÚ) BÀÇ °³ÀÎÅ°: xb = "+ xb); System.out.println("°ËÁõÀÚ(¼ö½ÅÀÚ) BÀÇ °ø°³Å°: yb = "+ yb); System.out.println(); // ------------------- ¼­¸í »ý¼º ---------------------- System.out.println("2. ºñ¹Ð¼­¸í »ý¼º (Secret Signing) "); String plaintext = "This is a simple message for Secret signature."; // ¼­¸íÇÒ Æò¹® BigInteger k, U, W, V, H; k = new BigInteger(blq, sr); // k¸¦ ³­¼ö·Î ¼±Åà U = g.modPow(k,p); // U = g^k mod p W = yb.modPow(k,p); // W = yb^k mod p MessageDigest md = MessageDigest.getInstance("SHA1"); // SHA1 Çؽ¬ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© md.update(plaintext.getBytes()); md.update(U.toString().getBytes()); md.update(W.toString().getBytes()); byte[] digest = md.digest(); // H(m,U,W)¸¦ °è»ê H = new BigInteger(1, digest); // digest °ªÀ» BigInteger·Î º¯È¯ V = (k.add(xa.multiply(H))).mod(q); // V = (k + xa * H) mod q System.out.println("m = "+plaintext); System.out.println("U = "+U); System.out.println("V = "+V); System.out.println("A-->B Àü¼ÛÇÏ´Â ¼­¸í°ª = (m,U,V)"); System.out.println(); // ------------------- ¼­¸í °ËÁõ ---------------------- System.out.println("3. ºñ¹Ð¼­¸í °ËÁõ (Secret Signature Verification) "); BigInteger left = g.modPow(V,p); // ¿ÞÂÊ°ª = g^V mod p °è»ê BigInteger WW = U.modPow(xb,p); // WW = U^xb mod p = yb^k mod p = W // °¨Ãß¾îÁø WW¸¦ °è»êÇؾ߸¸ ¼­¸íÀ» °ËÁõÇÒ ¼ö ÀÖÀ½. ÀÌ°ÍÀº xb¸¦ ¾Ë°í ÀÖ´Â ¼ö½ÅÀÚ B¸¸ÀÌ °è»êÇÒ ¼ö ÀÖÀ½. MessageDigest md1 = MessageDigest.getInstance("SHA1"); md1.update(plaintext.getBytes()); md1.update(U.toString().getBytes()); md1.update(WW.toString().getBytes()); byte[] digest1 = md1.digest(); // H(m,U,W)¸¦ °è»ê BigInteger HH = new BigInteger(1, digest1); // digest °ªÀ» BigInteger·Î º¯È¯ BigInteger right = (ya.modPow(HH,p).multiply(U)).mod(p); // ¿À¸¥ÂÊ°ª = ya^HH * U mod p °è»ê System.out.println("Left = "+left); System.out.println("Right = "+right); if(left.equals(right)) // ¿ÞÂÊ, ¿À¸¥ÂÊ °ªÀÌ °°À¸¸é ¼­¸íÀÌ À¯È¿ System.out.println("Secret signature is valid"); else System.out.println("Secret signature is not valid"); } }