[์ปดํจํฐ ๋ณด์] ํ์๊ณก์ DSA ๋์งํธ ์๋ช ์ค๋ช ๋ฐ ๊ตฌํ์ฝ๋
ํ์๊ณก์ DSA ๋์งํธ ์๋ช
์๋ฃ์กฐ์ฌ
DSA๋?
๋์งํธ ์๋ช ์๊ณ ๋ฆฌ์ฆ(Digital Signature Algorithm, DSA)์ ๋์งํธ ์๋ช ์ ์ํ ํ์ค์ด๋ค. NIST๊ฐ 1991๋ 8์ DSS๋ผ๋ ๋ฏธ๊ตญ ์ ์์๋ช ํ์ค์์ ์ด์ฉํ๊ธฐ ์ํด ์ ๋ถ์ฉ ์ ์์๋ช ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ฐํํ์ผ๋ฉฐ, ํ์ฌ๋ DSA์ ํจ๊ป ECDSA, RSA๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค.
๋์งํธ ์๋ช ์ธ์ฆ ๋ฐฉ์
์ ์์๋ช (๋์งํธ ์๋ช )์ ๋ฌด๊ฒฐ์ฑ, ์ธ์ฆ, ๋ถ์ธ๋ฐฉ์ง๋ฅผ ๋ง์กฑํด์ผํ๋ค.
์ ์์๋ช ์๋ ๊ณต๊ฐํค ์ํธํ ์๊ณ ๋ฆฌ์ฆ์ด ์ฐ์ด๋ฉฐ ํฌ๊ฒ 3๊ฐ์ง ์ข ๋ฅ์ ์๊ณ ๋ฆฌ์ฆ์ด ์๋ค.
- ํฉ์ฑ์์ ์์ธ์๋ถํด๋ฌธ์ ๊ฐ ์ด๋ ต๋ค๋ ๋ฐ์ ๊ธฐ์ดํ RSAํ ์๊ณ ๋ฆฌ์ฆ
- ์ ํ์ฒด์ ์ด์ฐ๋์ ๋ฌธ์ ๊ฐ ์ด๋ ต๋ค๋ ๋ฐ์ ๊ธฐ์ดํ ElGamalํ ์๊ณ ๋ฆฌ์ฆ
- ํ์๊ณก์ ์ ์ด์ฉํ EC-DSA, EC-KCDSA
DSA๋ ์ด ์ค ElGamalํ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๊ธฐ๋ฐ์ฑ์ ๊ฐ์ง๊ณ ์์ง ์์ผ๋ฉฐ ์ ์์๋ช ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ์ด๋ฌํ ์๋ช ์๊ณ ๋ฆฌ์ฆ๋ค์ ์ฃผ๋ก 3๊ฐ์ง ํจ์๋ก ๋๋์ด ๋์ํ๋ฉฐ, ๊ฐ๊ฐ 'ํค ์์ฑ', '์๋ช ', '๊ฒ์ฆ' ์ญํ ์ ํ๋ ํจ์์ด๋ค.
์ด์ฐ๋์ ๋ฌธ์
์ด์ฐ ๋์ ๋ฌธ์ ๋ Y = g^x mod p
๋ผ๋ ๋ฌธ์ ์์ Y, g, p๋ฅผ ๊ณต๊ฐํ๋๋ผ๋ x๋ฅผ ๊ณ์ฐํ๊ธฐ ์ด๋ ค์ด ๋ฌธ์ ๋ฅผ ๋ปํ๋ค.
RSA์์ ๋น๊ต
๋์งํธ ์๋ช ๊ณผ ์ธ์ฆ ๋ฐฉ์์ ์๋ RSA ๊ณต๊ฐํค ์ํธํ์์คํ ์ ์ด์ฉํ๊ณ ์์๋ค. RSA์ DSA์ ์ฐจ์ด์ ์ ๋ค์ ๊ทธ๋ฆผ๊ณผ ๊ฐ๋ค.
RSA๋ ๊ฐ์ธํค๋ก ์ ์ ์๋ช ๊ฐ์ ๋ง๋ค์ง ์๊ณ , ์๋ณธ ๋ฉ์์ง๋ฅผ ์์ถ ํจ์๋ก ์์ถํ ํ ์์ถ ํด์๊ฐ์ ์ํธํํ์ฌ ์ ์์๋ช ๊ฐ์ ๋ง๋ ๋ค. ๋ฉ์์ง ์ธ์ฆ ์์๋ ๋ฉ์์ง๋ฅผ ๋ค์ ์์ถ ํด์๊ฐ์ผ๋ก ๋ง๋ค๊ณ , ๋ณตํธํ๋ ์ ์์๋ช ๊ฐ๊ณผ ๋น๊ตํ์ฌ ์ธ์ฆํ ์ ์๋ค.
DSA๋ ๋ฉ์์ง์ ์์ถ ๊ฐ์ ์ํธํํด์ ์ ์์๋ช ์ ๋ง๋๋ ๊ฒ์ ๊ฐ์ง๋ง ๋ฉ์์ง ์ธ์ฆ๊ณผ์ ์ด ๋ค๋ฅด๋ค. DSA ์๊ณ ๋ฆฌ์ฆ์ ์ ์์๋ช ๋ง์ ์ํ ์๊ณ ๋ฆฌ์ฆ์ด๋ฏ๋ก ๋น๊ต์์ด ๋ฐ๋ก ์ธ์ฆ์ด ๊ฐ๋ฅํ๋ค.
RSA๋ณด๋ค ํค ์์ฑ, ๋ณตํธํ(๊ฒ์ฆ) ๊ณผ์ ์ด ๋น ๋ฅด๋ฉฐ ์ํธํ(์๋ช ) ๊ณผ์ ์ ๋น๊ต์ ๋๋ฆฐ ํธ์ด๋ค.
ํน์ง
- RSA๋ณด๋ค ํค ์์ฑ์ด ๋น ๋ฅด๋ค.
- ๊ฒ์ฆ์๋๋ RSA๋ณด๋ค ๋๋ฆฌ๋ค.
- ์ด์ฐ ๋์ ๋ฌธ์ ์ ์ด๋ ค์์ ์ด์ฉํ ๋ฐฉ๋ฒ์ด๋ค.
- 320bit ์๋ช ์ ๋ง๋ค์ด ๋ธ๋ค.
- ํด์ ํจ์๋ก๋ SHA1์ ์ด์ฉํ๋ค.
๋ฌธ์ ์
Nonce reuse ๋ฌธ์ ๊ฐ ์๋ค. ์๋ช ์์ฑ ๊ณผ์ ์์ ์ฐ์ธ k ๊ฐ์ ๋ค์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. k๊ฐ์ด ๊ฐ์ ๋์ ๋ ์๋ช (r,s1), (r,s2)๊ฐ ์๋ค๊ณ ํ๋ฉด
s1 − s2 = k^(−1)(H(m1)+xr−H(m2)−xr) = k^(−1)(H(m1)−H(m2))(mod q)
์ด๋ฏ๋ก
k = (H(m1)−H(m2))/(s1−s2)(mod q)
๋ฅผ ํตํด k๋ฅผ ๋ณต๊ตฌํ ์ ์๋ค. k๊ฐ์ ๋ณต๊ตฌํ๋ฉด ์ด๋ฅผ ์ด์ฉํด s1, r, H(m1), k๋ฅผ ๊ตฌํด์ ๋น๋ฐํค x๋ฅผ ๋ณต๊ตฌํ ์ ์๋ค.
์๊ณ ๋ฆฌ์ฆ ๋ถ์
๊ณผ์
์ค๋น
-
ํค ๊ธธ์ด๋ฅผ ์ ํ๋ค.
L, N์ ์ ํด์ผํ๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก (1024, 160), (2048, 224), (2048, 256), (3072, 256) ์ค ํ๋์ด๋ค.
-
๋ฉ์ธ์ง ํด์ฑ ํจ์ H๋ฅผ ์ ์ํ๋ค.
H์ output ๊ธธ์ด๋ N ์ด์์ด์ด์ผํ๋ค.
-
์๋ช ์ ๋งค๊ฐ๋ณ์ (p,q,g)๋ฅผ ๊ณต์ ํ๋ค.
p๊ฐ์
2^(L-1) < p < 2^L
๋ฅผ ๋ง์กฑํ๋ฉฐ L bit ๊ธธ์ด์ธ ์์์ด๋ค.q๊ฐ์
2^(N-1) < q < 2^N
์ ๋ง์กฑํ๋ฉฐ N bit ์ฌ์ด์ ๊ธธ์ด๋ฅผ ๊ฐ์ง ์์ด๋ค.=> ์ฌ๊ธฐ์ p-1์ด q์ ๋ฐฐ์์ฌ์ผํ๋ค.
g๊ฐ์
g = h^((p-1)/q) mod p
๋ฅผ ๋ง์กฑํ๋ฉฐ1 < q < p
์ธ ์์ด๋ค.์ด ๋,
1 < h < p-1 && g > 1
์ด๊ณ ์ผ๋ฐ์ ์ผ๋ก h๋ 2๋ฅผ ๊ณ ๋ฅธ๋ค.
ํค ์์ฑ
-
๊ณต๊ฐํค y๋ฅผ ์์ฑํ๋ค.
0 < x < q
์ธ x(๊ฐ์ธํค)๋ฅผ ๊ผฝ์ ํ,y=g^x mod p
๋ก ๊ณต๊ฐํค์ธ y๋ฅผ ๊ณ์ฐํ๋ค.์ด์ฐ๋์ ๋ฌธ์ ๋ก y๊ฐ์ผ๋ก๋ถํฐ x๋ฅผ ์ฝ๊ฒ ๊ตฌํ ์ ์๋ค.
์๋ช ์์ฑ
-
๋๋คํ ์๋ฅผ ์์ฑํ๋ค.
0๋ณด๋ค ํฌ๊ณ q๋ณด๋ค ์์ ๋๋ค ์ k๋ฅผ ์์ฑํ๋ค.
-
์ ์ ์๋ช ์ ํ๋ค.
r = (g^k mod p) mod q s = (k^(-1)(H(M) +xr)) mod q
-
(r, s, M)์ ์ ์กํ๋ค.
์๋ช ๊ฒ์ฆ
-
(r, s, M)์ ๋ฐ๋๋ค.
-
๊ฐ์ ๊ณ์ฐํ๋ค.
w = s^-1 mod q u1 = (H(M)w) mod q u2 = rw mod q v = ((g^u1*y^u2) mod p ) mod q
-
v๊ฐ r์ด๋ผ๋ฉด ์ธ์ฆ ์๋ฃ์ด๋ค.
Correctness of the algorithm
์๊ณ ๋ฆฌ์ฆ์์ g = h^((p-1)/q) mod p
์ด์์ผ๋ฏ๋ก g^q = h^(p-1) = 1 mod p
์ด๋ค. ๋ฐ๋ผ์ a = b (mod q)
์ธ ์กฐ๊ฑด์์ g^a = g^b (mod p)
๊ฐ ์ฑ๋ฆฝํจ์ ์ ์ ์๋ค.
์์ ์๊ณ ๋ฆฌ์ฆ์์ s = (k^(-1)(H(M) +xr)) mod q
์ด๋ฏ๋ก ์์ ์ฑ์ง์ ์ด์ฉํ๋ฉด k = (s^(-1)(H(M) +xr)) mod q
๋ก ๋ํ๋ผ ์ ์๋ค. ๋ฐ๋ผ์
r = (g^k mod p) mod q = ((g^u1*y^u2) mod p) mod q = v
์ด๊ธฐ ๋๋ฌธ์ ์๊ณ ๋ฆฌ์ฆ์ด ์ฑ๋ฆฝํ๋ค.
ํ๋ก๊ทธ๋จ ๊ตฌํ
์ธ์ด๋ C++๋ก IDE๋ Visual Studio๋ฅผ ์ด์ฉํ์ฌ ๊ตฌํํ๊ธฐ๋ก ํ๋ค.
์ฃผ์ ์ฝ๋ ๊ตฌ์ฑ
์ฝ๋๋ ์ก์ ์์ธ Sender์ ์์ ์์ธ Receiver class๋ก ๋๋์ด ๊ตฌํํ์์ผ๋ฉฐ, ์ค๊ฐ์ ๋งค๊ฐํ๋ mainํจ์๋ ์๋น์ค ์ ๊ณต ์์คํ ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
Sender ํด๋์ค๋ 4๊ฐ์ง ํจ์๋ก ์ด๋ฃจ์ด์ ธ์์ผ๋ฉฐ, ๊ฐ ํจ์์์ ์ฐ์ด๋ ๋ณ์๋ค์ private์ผ๋ก ์ ์ธ๋์ด์๋ค.
๋จผ์ ์ก์ ์๋ initialize ํจ์๋ฅผ ์ด์ฉํ์ฌ ์ง์ ๋ ํด์ํจ์๋ฅผ ์ด์ฉํ ๋ฉ์ธ์ง์ ํด์๊ฐ, ๋ณ์ ๊ธธ์ด ๊ฒฐ์ ๋ณ์, ๋งค๊ฐ๋ณ์๋ค์ ์ธํ ํ๋ ์ญํ ์ ํ๋ค. ๊ทธ ํ generateKey ํจ์๋ฅผ ์ด์ฉํ์ฌ ํด๋น ๋งค๊ฐ๋ณ์๋ค๋ก ๋น๋ฐํค x์ ๊ณต๊ฐํค y๋ฅผ ๋ง๋ค์ด๋ธ๋ค. ํด๋น ํจ์์์ ํธ์ถ๋๋ generateSign์ผ๋ก ์๋ช ์ ๋ง๋ค์ด๋ด๊ณ , ์๋ช ์ด๋ผ๊ณ ์ผ์ปซ๋ r๊ณผ s๋ฅผ sendRS ํจ์๋ก Receiver์๊ฒ ๋ณด๋ธ๋ค.
Receiver ํด๋์ค๋ verifySign์ด๋ผ๋ ํ๋์ ํจ์๋ก ์ด๋ฃจ์ด์ ธ์๋ค. Sender์ ๋ง์ฐฌ๊ฐ์ง๋ก ํ์ํ ๋ณ์๋ค์ private์ผ๋ก ์ ์ธ๋์ด์๋ค.
์์ ์๋ ์ ๋ฌ๋ฐ์ r, s, M์ ๊ฐ์ง๊ณ ๊ฒ์ฆ์ ์์ํ๋ค. ๊ณ์ฐ ๊ฒฐ๊ณผ ๋์ถ๋ v ๋ณ์ ๊ฐ๊ณผ ์ก์ ์๋ก๋ถํฐ ๋ฐ์ r๊ฐ์ด ๊ฐ์ผ๋ฉด ์๋ช ์ด ์ผ์นํ๋ฏ๋ก ๊ฒ์ฆ์ด ์๋ฃ๋๊ณ ์ ๋ฌ๋ฐ์ ๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ๋ค. ๊ฐ์ง ์๋ค๋ฉด ๊ฒ์ฆ์ ์คํจํ๋ค.
๋์ ํจ์
์ ์ญ ๊ตฌ๊ฐ์ ์กด์ฌํ๋ ๋ ๊ฐ์ง ๋์ํจ์๊ฐ ์๋ค. bigModuler ํจ์๋ unsigned long์ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ๋ชจ๋๋ฌ ๊ณ์ฐ์ ์ํด ์ฌ๊ทํจ์์ ํํ๋ก ๋ถํ ์ ๋ณตํ๋ ํจ์์ด๋ค. isPrime ํจ์๋ ํด๋น ๋ณ์๊ฐ ์์์ธ์ง๋ฅผ ํ๋จํ๋ ๋์ํจ์๋ก ๋งค๊ฐ๋ณ์ p๊ฐ์ ๊ฒฐ์ ํ ๋ ์ฌ์ฉ๋๋ค.
ํค๋ํ์ผ
ํค๋ํ์ผ๋ก๋ Euclid.h์ SHA1.h๊ฐ ์๋ค. ์ฝ๋ ์์์ ์ฌ์ฉ๋๋ ํด์ ํจ์๋ ์ง์ ๊ตฌํํด๋ SHA1 ํจ์๋ฅผ ์ฌ์ฉํ์๋ค.
๋ํ ์๊ณ ๋ฆฌ์ฆ ์ค ๋ชจ๋๋ฌ ๊ณฑ์ ์ญ์์ ๊ตฌํ๋ ๋ถ๋ถ์ด ์๋๋ฐ, ์ด๋ฅผ ๊ตฌํํ๋ ค๋ฉด 2๊ฐ์ง ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.
-
์์ฐจ์ ์ผ๋ก ์ฆ๊ฐํ๋ฉด์ ์ญ์ ์ฐพ๊ธฐ
-
ํ์ฅ๋ ์ ํด๋ฆฌ๋ ํธ์ ๋ฒ ์ด์ฉํ๊ธฐ
๋ณธ์ธ์ ์ฒ์์ 1๋ฒ ๋ฐฉ๋ฒ์ ์ด์ฉํ์ฌ ์ฝ๋๋ฅผ ๊ตฌํํ์์ผ๋, ์ญ์์ ์ฐพ๋ ๋ฐ์ ์๊ฐ์ด ๋๋ฌด ์ค๋ ๊ฑธ๋ ค์ ์ ํด๋ฆฌ๋ ํธ์ ๋ฒ์ ๊ตฌํํ Euclid.h ํ์ผ์ ๋ง๋ค์๋ค.
๋ถ์กฑํ ์
์์ ์๊ณ ๋ฆฌ์ฆ ๋ถ์ ํํธ์์ ์ค๋ช ํ๋ฏ์ด L๊ณผ N์ ์ฃผ์ด์ง bit ์์ด ์กด์ฌํ๋ค. L์ ์ต์ 1024bit ๋ถํฐ ์์ํ๋ฏ๋ก ๊ณ์ฐ์ ๋ฒ์๊ฐ ๋๋ฌด ์ปค์ ธ ๋ค๋ฃจ๊ธฐ๊ฐ ์ด๋ ค์ ๋ค. ๋ฐ๋ผ์ ๋ณธ์ธ์ L๊ณผ N์ ๋ฎ์ ์๋ก ๊ณ ์ ํด๋ ์ผ๋ก์จ unsigned long์ ๋ฒ์๋ด์์ ๊ณ์ฐ ๊ฐ๋ฅํ ์ฝ๋๋ก ๊ตฌํํ๋ค.
์ฝ๋
<Euclid.h>
#include <iostream>
using namespace std;
typedef unsigned long ulong;
ulong Euclid_module(ulong, ulong);
ulong Inverse(ulong n1, ulong n2) {
int inv = 0;
if (n1 > n2)
inv = Euclid_module(n1, n2);
else
inv = Euclid_module(n2, n1);
return inv;
}
ulong Euclid_module(ulong r1, ulong r2) {
int r, q, s, s1 = 1, s2 = 0, t, t1 = 0, t2 = 1, tmp = r1;
while (r2)
{
q = r1 / r2;
r = r1 % r2;
s = s1 - q * s2;
t = t1 - q * t2;
r1 = r2;
r2 = r;
s1 = s2;
s2 = s;
t1 = t2;
t2 = t;
}
if (r1 == 1) // ์ญ์ ์กด์ฌ
{
if (t1 < 0)
t1 += tmp;
return t1;
}
return 0;
}
<SHA1.h>
#include <cmath>
#include <vector>
#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>
using namespace std;
std::string m;
uint64_t ml;
uint32_t weight[80];
uint32_t k_sha[80];
int exe = 0;
unsigned int h_sha[5] = {
0x67452301,
0xEFCDAB89,
0x98BADCFE,
0x10325476,
0xC3D2E1F0
};
unsigned int rotl32(unsigned int value, unsigned int count) {
return ((value << count) & 0xFFFFFFFF) | ((value & 0xFFFFFFFF) >> (32 - count));
}
void padding() {
// m์ padding์ ์ถ๊ฐํ๊ธฐ ์ length (bit size)
ml = m.size() * CHAR_BIT; // m.size() => 64bit (8byte)
// 0x80 = 2^7 = 10000000
// ์๋ ๋ฉ์ธ์ง์ bit '1' ์ถ๊ฐ
// ์ด์ฐจํผ ๋ค์ ๋จ๊ณ์์ 0์ ์ฑ์ฐ๊ธฐ ๋๋ฌธ์ ๋ฏธ๋ฆฌ 7๊ฐ ์ถ๊ฐ
m += (char)0x80;
// 64byte(512bit)๋ก ๋๋์ด๋จ์ด์ง๋๋ก 0 ์ฑ์์ฃผ๊ธฐ
// m.size()๊ฐ 64(byte)๊ฐ ๋ ๋๊น์ง
while (m.size() % 64 != 64 - sizeof(ml)) {
m += (char)0x00;
}
// ๋งจ ๋ค์๋ ๋ฉ์ธ์ง size ๋ฃ๊ธฐ
// 8bit ์ฉ
for (int i = 7; i >= 0; i--) {
char byte = (ml >> 8 * i) & 0xff;
m += byte;
}
// ์ด์ m์ 64bytes(512bit)๋ก ๋๋์ด ๋จ์ด์ง๋ค.
}
void wSetting() {
// m์ w ์ฒ์์ ์ฑ์ฐ๊ธฐ
// m (64byte(512bit)) => 16๊ฐ์ w => ํ๋์ w๋น 4byte(4๊ธ์ = 4*char)์ m์ด ํ ๋น๋จ
for (int i = 0; i < 16; i++) {
weight[i] = (m[4 * i + 3] & 0xff)
| (m[4 * i + 2] & 0xff) << 8
| (m[4 * i + 1] & 0xff) << 16
| (m[4 * i + 0] & 0xff) << 24;
}
// weight ๊ฐ๊ณตํด์ ๋๋จธ์ง weight ์ฑ์ฐ๊ธฐ
for (int i = 16; i < 80; i++) {
weight[i] = rotl32(weight[i - 16] ^ weight[i - 14] ^ weight[i - 8] ^ weight[i - 3], 1);
}
}
void kSetting() {
for (int i = 0; i < 20; i++)
k_sha[i] = 0x5A827999;
for (int i = 20; i < 40; i++)
k_sha[i] = 0x6ED9EBA1;
for (int i = 40; i < 60; i++)
k_sha[i] = 0x8F1BBCDC;
for (int i = 60; i < 80; i++)
k_sha[i] = 0xCA62C1D6;
}
uint32_t F(unsigned int b, unsigned int c, unsigned int d) {
if (exe < 20) {
return (b&c) | ((~b)&d);
}
else if (exe < 40) {
return (b^c^d);
}
else if (exe < 60) {
return ((b&c) | (b&d) | (c&d));
}
else if (exe < 80) {
return (b^c^d);
}
}
void SHA() {
uint32_t a = h_sha[0]; uint32_t b = h_sha[1]; uint32_t c = h_sha[2]; uint32_t d = h_sha[3]; uint32_t e = h_sha[4];
// 80๋ฒ loop
uint32_t temp;
while (exe != 80) {
temp = rotl32(a, 5) + F(b, c, d) + e + weight[exe] + k_sha[exe];
e = d;
d = c;
c = rotl32(b, 30);
b = a;
a = temp;
exe++;
}
h_sha[0] = h_sha[0] + a;
h_sha[1] = h_sha[1] + b;
h_sha[2] = h_sha[2] + c;
h_sha[3] = h_sha[3] + d;
h_sha[4] = h_sha[4] + e;
}
unsigned int SHA1(string message) {
m = message;
padding(); // 1. ๋ฉ์ธ์ง padding ์ฒ๋ฆฌ
wSetting(); // 2. w ์ธํ
kSetting(); // 3. k ์ธํ
SHA(); // 4. SHA
unsigned int result=0;
for (int i = 0; i < 5; i++) {
result += h_sha[i];
}
return result;
}
<DSA.cpp>
#include <iostream>
#include <random>
#include <math.h>
#include <Windows.h>
#include <vector>
#include "SHA1.h"
#include "Euclid.h"
using namespace std;
typedef unsigned long ulong;
random_device rd;
mt19937 gen(rd());
ulong p, q, g;
ulong y;
ulong Hm;
string M;
ulong bigModuler(ulong n, ulong e, ulong m) { // ํฐ ์์ ๋ชจ๋๋ฌ ๊ณ์ฐ์ ์ํ ํจ์
if (e <= 3) {
return ((int)pow(n, e)) % m;
}
if (e % 2 == 0) { // ์ง์์ด๋ฉด
ulong tmp = bigModuler(n, e / 2, m);
return (tmp*tmp) % m;
}
else {
ulong tmp = bigModuler(n, (int)e / 2, m);
ulong tmp2 = bigModuler(n, e-(int)e / 2, m);
return (tmp*tmp2) % m;
}
}
bool isPrime(ulong num) { // ์์๋ฅผ ํ๋ณํ๊ธฐ ์ํ ํจ์
for (int i = 2; i <= (int)sqrt(num); i++) {
if (num%i == 0)
return false;
}
return true;
}
class Receiver {
private:
ulong w, u1, u2, v;
public:
void verifySign(ulong r, ulong s) { // ์ ์์๋ช
์ธ์ฆ ๊ณผ์
cout << "verifying..." << endl;
ulong inv_s = Inverse(s, q);
w = inv_s % q;
u1 = (Hm*w) % q;
u2 = (r*w) % q;
v = ((bigModuler(g,u1,p)*bigModuler(y,u2,p)) % p) % q;
if (v == r) { // ์๋ช
์ด ์ผ์นํ๋ฉด ํต๊ณผ => ๋ฉ์ธ์ง ์ถ๋ ฅ
cout << "authentication success :>" << endl;
cout << "message : " << M << endl;
}
else {
cout << "authentication denied :<" << endl;
}
}
};
class Sender {
private:
ulong L, N;
ulong h = 2;
ulong k, r, s;
public :
vector<ulong> sendRS() {
cout << "sending..." << endl;
vector<ulong> rs;
rs.push_back(r);
rs.push_back(s);
cout << "send complete!" << endl << endl; // r,s,M ์ ์ก
return rs;
}
void generateSign(ulong x) {
uniform_int_distribution<> dis4(1, q - 1);
k = dis4(gen); // ๋๋ค ์ k ์์ฑ
ulong inv_k = Inverse(k, q);
r = bigModuler(g, k, p) % q;
s = (inv_k*(Hm + x * r)) % q;
if (s == 0) { // s๊ฐ 0์ด๋ฉด ๋ค์ ํ๊ธฐ
generateKey();
}
}
void generateKey() {
uniform_int_distribution<> dis3(1, q - 1);
ulong x = dis3(gen); // ๋๋ค ์ x ์์ฑ
y = bigModuler(g, x, p);
generateSign(x); // ์ ์์๋ช
์์ฑ
}
void initialize() {
L = 5; N = 2; // length ์ค์
Hm = SHA1(M); // ํด์ ํจ์ ์ด์ฉ => ๋ฉ์ธ์ง ํด์๊ฐ ์์ฑ
uniform_int_distribution<> dis((ulong)pow(2, L - 1) + 1, (ulong)pow(2, L) - 1);
do {
p = dis(gen);
} while (!isPrime(p)); // ์ฃผ์ด์ง ๋ฒ์ ๋ด์ ์์ p ์ฐพ๊ธฐ
int flag = 0;
for (ulong i = (ulong)pow(2, N - 1) + 1; i >= (ulong)pow(2, N) - 1; i--) {
if ((p - 1) % i == 0) {
q = i;
flag = 1;
}
}
if (!flag) {
initialize();
}
g = bigModuler(h, (ulong)((p - 1) / q), p);
}
};
int main() {
cout << "๋ฌธ์์ด์ ์
๋ ฅํด์ฃผ์ธ์." << endl;
cin >> M;
cout << endl;
Sender* s = new Sender(); // ์์ ์ ์์ฑ
Receiver* r = new Receiver(); // ์ก์ ์ ์์ฑ
s->initialize(); // ์ด๊ธฐํ
s->generateKey(); // ํค ์์ฑ
cout << "๊ณต๊ฐํค : " << y << endl; // ๊ณต๊ฐํค ๊ณต๊ฐ
vector<ulong> tmp = s->sendRS(); // r,s,M ์ ์ก
r->verifySign(tmp[0],tmp[1]); // ์ ์์๋ช
์ธ์ฆ
cin >> M;
}
์คํํ๋ฉด
์์คํ ์ ์์ํ๊ณ ๋ฌธ์์ด์ ์ ๋ ฅํ๋ฉด ๊ณต๊ฐํค๊ฐ ์ถ๋ ฅ๋๋ค. Sender๊ฐ Receiver์๊ฒ ๋ณด๋ด๋ ๊ณผ์ ์ด ์ง๋ ํ, Receiver๊ฐ ๊ฒ์ฆํ ๋, ์ฃผ์ด์ง ๊ณต๊ฐํค์ ์ ๋ฌ๋ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง๊ณ ๊ฒ์ฆ์ ์ฐจ๋ฅผ ๊ฑฐ์น๋ค. ๊ฒ์ฆ์ ์ฑ๊ณตํ๋ฉด ์ฑ๊ณตํ์์ ํจ๊ป Sender๊ฐ ๋ณด๋ธ ๋ฉ์ธ์ง๊ฐ ์ถ๋ ฅ๋๋ค.
์ฐธ๊ณ ๋ฌธํ
https://www.nist.gov/publications/digital-signature-standard-dss-0?pub_id=902984
http://blog.naver.com/PostView.nhn?blogId=turbo0815&logNo=60049190798
http://www.parkjonghyuk.net/lecture/modernCrypto/lecturenote/chap09-1.pdf
http://www.secmem.org/blog/2019/07/21/Digital-Signature-and-Nonce-Ruse/
https://eunplay.tistory.com/122
http://www.secmem.org/blog/2019/07/21/Digital-Signature-and-Nonce-Ruse/
https://blog.naver.com/techshare/220921626310
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf