Skip to Content
독학사독학사 3단계정보보호02. 암호학을 위한 최소 수학·논리 기초

이번 문서의 목표: 모듈러 연산·모듈러 지수·이산로그·XOR을 실제 숫자로 손으로 계산할 수 있게 되어, 05~08편의 대칭키·공개키·해시·PKI 계산을 수학 걱정 없이 따라갈 수 있게 한다. 아울러 키 공간과 브루트포스 확률, 보안 정책 서술에 쓰이는 논리식·진리표를 다룬다.

왜 이 수학이 필요한가

쉽게 말하면: 암호는 결국 “나눗셈의 나머지”와 “매우 큰 수의 거듭제곱”으로 만들어진다.

05편부터 등장하는 대칭키·공개키 암호, 06편의 디피-헬만 키교환, 07편의 해시 함수는 모두 내부적으로 나머지 연산(모듈러 연산)과 거듭제곱(지수)을 사용한다. RSA 공개키 암호의 암호화·복호화 식도, 디피-헬만 키교환의 공유 비밀 계산도 형태는 다르지만 전부 “어떤 수를 거듭제곱한 뒤 특정 수로 나눈 나머지를 구한다”는 동일한 연산에 기반한다. 이 편에서 그 연산을 실제 작은 숫자로 완전히 계산해 두면, 뒤 편에서는 “이 계산은 03편에서 했던 것과 같은 구조다”라고 바로 알아볼 수 있다.

모듈러 연산(modular arithmetic)

정의와 기본 계산

쉽게 말하면: 나눗셈을 하고 몫은 버리고 나머지만 남기는 연산이다.

모듈러 연산(합동식, congruence)은 어떤 정수를 특정 양의 정수(법, modulus)로 나눈 나머지만을 취하는 연산이다. amodna \bmod n은 “aann으로 나눈 나머지”를 뜻하며, 시계가 12를 넘으면 다시 1로 돌아가는 것과 같은 원리다(시계는 12를 법으로 하는 모듈러 연산의 생활 속 예시다).

17mod5=217 \bmod 5 = 2
  • 17mod517 \bmod 5: 17을 5로 나누면 몫이 3이고 나머지가 2이므로(5×3=155 \times 3 = 15, 1715=217 - 15 = 2), 결과는 2다.

두 수가 같은 법에 대해 나머지가 같으면 “합동(congruent)“이라 하고 ab(modn)a \equiv b \pmod n으로 쓴다. 예를 들어 172(mod5)17 \equiv 2 \pmod 5다.

모듈러 덧셈과 곱셈

모듈러 연산은 덧셈·곱셈에 대해 다음 성질을 만족한다. 이 성질 덕분에 큰 수를 직접 계산하지 않고도 중간에 나머지를 취해가며 계산할 수 있다.

(a+b)modn=((amodn)+(bmodn))modn(a + b) \bmod n = ((a \bmod n) + (b \bmod n)) \bmod n
  • 예시: (14+9)mod6(14 + 9) \bmod 6을 직접 계산하면 23mod6=523 \bmod 6 = 5다. 성질을 이용하면 (14mod6)+(9mod6)=2+3=5(14 \bmod 6) + (9 \bmod 6) = 2 + 3 = 5, 다시 5mod6=55 \bmod 6 = 5로 같은 결과가 나온다.
(a×b)modn=((amodn)×(bmodn))modn(a \times b) \bmod n = ((a \bmod n) \times (b \bmod n)) \bmod n
  • 예시: (14×9)mod6(14 \times 9) \bmod 6을 직접 계산하면 126mod6=0126 \bmod 6 = 0이다. 성질을 이용하면 (2×3)mod6=6mod6=0(2 \times 3) \bmod 6 = 6 \bmod 6 = 0으로 같다.

이 곱셈 성질이 바로 다음 절의 모듈러 지수 연산을 큰 수 그대로 계산하지 않고도 빠르게 처리할 수 있게 해주는 근거다.

모듈러 지수(modular exponentiation): 빠른 거듭제곱

쉽게 말하면: 지수를 절반씩 쪼개면서 매번 나머지를 취하면, 아무리 큰 지수라도 몇 단계 안에 계산할 수 있다.

공개키 암호와 디피-헬만 키교환은 모두 gamodpg^a \bmod p 형태의 계산(밑 gg를 지수 aa만큼 거듭제곱한 뒤 pp로 나눈 나머지)을 반복한다. 지수가 매우 커도 제곱-곱 알고리즘(square-and-multiply)을 쓰면 곱셈 횟수를 크게 줄일 수 있다. 37mod113^7 \bmod 11을 예로 들어 단계별로 계산해 본다.

  1. 지수 7을 이진수로 쓴다: 7=11127 = 111_2 (4 + 2 + 1)
  2. 밑을 반복 제곱하며 표를 만든다: 31mod11=33^1 \bmod 11 = 3, 32mod11=93^2 \bmod 11 = 9, 34mod11=92mod11=81mod11=43^4 \bmod 11 = 9^2 \bmod 11 = 81 \bmod 11 = 4
  3. 이진수에서 1인 자리에 해당하는 값만 곱한다: 7=4+2+17 = 4 + 2 + 1이므로 34×32×31mod113^4 \times 3^2 \times 3^1 \bmod 11
  4. 차례로 곱하며 매번 나머지를 취한다: 34×32=4×9=363^4 \times 3^2 = 4 \times 9 = 36, 36mod11=336 \bmod 11 = 3. 여기에 31=33^1 = 3을 곱하면 3×3=93 \times 3 = 9, 9mod11=99 \bmod 11 = 9
37mod11=93^7 \bmod 11 = 9
  • 33: 밑(base). 반복해서 곱해지는 수.
  • 77: 지수(exponent). 밑을 몇 번 곱할지 나타내는 수.
  • 1111: 법(modulus). 나머지를 취하는 기준 수.

직접 37=21873^7 = 2187을 계산해 1111로 나눠도 2187mod11=92187 \bmod 11 = 9로 같은 값이 나오는 것을 확인할 수 있다. 차이는 제곱-곱 알고리즘이 중간중간 나머지를 취해 다뤄야 하는 숫자의 크기를 계속 작게 유지한다는 점이다. RSA에서 실제로 쓰이는 지수와 법은 수백 자리 숫자이므로, 이 방식이 아니면 계산 자체가 불가능할 정도로 느려진다. 06편의 디피-헬만 키교환과 08편의 RSA 계산은 모두 이 절차를 그대로 사용한다.

모듈러 역원(modular inverse): 나눗셈을 되돌리는 열쇠

쉽게 말하면: 모듈러 세계에는 나눗셈이 따로 없어서, “곱하면 1이 되는 짝꿍 수”를 찾아 나눗셈 대신 쓴다.

일반 산수에서 aa로 나누는 것은 1a\frac{1}{a}을 곱하는 것과 같다. 모듈러 연산에는 분수가 없으므로, “aa와 곱했을 때 결과가 11이 되는 수” a1a^{-1}을 찾아 나눗셈을 대신한다. 이를 모듈러 역원이라 하며 다음을 만족하는 xx다.

a×x1(modn)a \times x \equiv 1 \pmod n
  • aa: 역원을 구하려는 수.
  • xx: aa의 모듈러 역원(찾으려는 값).
  • nn: 법.

예를 들어 3mod113 \bmod 11의 역원을 구해 보자. xx11부터 차례로 대입하며 3xmod113x \bmod 1111이 되는 값을 찾으면, 3×4=123 \times 4 = 12, 12mod11=112 \bmod 11 = 1이므로 x=4x = 4다.

31mod11=43^{-1} \bmod 11 = 4

작은 수는 이렇게 대입으로 찾을 수 있지만, RSA처럼 법이 수백 자리인 경우에는 확장 유클리드 호제법(extended Euclidean algorithm, 두 수의 최대공약수를 구하는 과정에서 동시에 모듈러 역원까지 구해내는 절차)을 쓴다. 이 알고리즘 자체의 세부 절차는 08편에서 RSA 키쌍 생성을 다룰 때 실제 계산으로 다시 등장하므로, 여기서는 “역원이 나눗셈의 대체 역할을 한다”는 개념만 확실히 잡아 둔다.

이산로그(discrete logarithm)와 디피-헬만의 직관

쉽게 말하면: 거듭제곱은 계산하기 쉽지만, 결과에서 거꾸로 몇 제곱인지 알아내는 것은 훨씬 어렵다.

일반 로그는 ga=yg^a = y일 때 a=loggya = \log_g y로 쉽게 구할 수 있다. 그런데 모듈러 세계에서 gamodp=yg^a \bmod p = y가 주어졌을 때 aa를 구하는 문제(이산로그 문제)는 pp가 커지면 사실상 계산이 불가능할 정도로 어려워진다. 이 “계산의 비대칭성”(거듭제곱은 쉽고, 역으로 지수를 구하는 것은 어려움)이 06편에서 다룰 디피-헬만 키교환과 여러 공개키 암호 방식의 안전성 근거가 된다.

작은 수로 이 비대칭성을 체감해 보자. p=11p = 11, g=2g = 2일 때 2amod112^a \bmod 11의 값을 a=1a = 1부터 나열하면 다음과 같다.

aa2a2^a2amod112^a \bmod 11
122
244
388
4165
53210

정방향(a를 알 때 결과 구하기)은 앞 절의 모듈러 지수 계산으로 즉시 구해진다. 하지만 “2amod11=102^a \bmod 11 = 10일 때 aa는 얼마인가”라는 역방향 질문에 답하려면, 이 작은 예제에서는 표를 훑어 a=5a = 5임을 찾을 수 있지만, pp가 수백 자리 소수가 되면 이런 무작정 대입(brute-force, 브루트포스)은 우주의 나이보다 긴 시간이 걸린다. 06편의 디피-헬만 키교환은 바로 이 계산 비대칭성을 이용해, 통신 당사자만 알 수 있는 공유 비밀을 도청자는 알아낼 수 없게 만든다.

XOR(배타적 논리합) 연산

진리표와 계산

쉽게 말하면: 두 비트가 서로 다르면 1, 같으면 0이 나오는 연산이다.

XOR(exclusive OR, 배타적 논리합)은 두 비트를 비교해 서로 다를 때만 1을 출력하는 논리 연산이며 기호로 \oplus를 쓴다. 스트림 암호(05편)의 핵심 연산이자, 여러 해시·블록암호 내부 연산에도 등장한다.

AABBABA \oplus B
000
011
101
110

비트열(여러 비트를 나열한 것) 단위로 계산할 때는 같은 자리끼리 XOR한다.

10100110=11001010 \oplus 0110 = 1100
  • 첫째 자리: 10=11 \oplus 0 = 1
  • 둘째 자리: 01=10 \oplus 1 = 1
  • 셋째 자리: 11=01 \oplus 1 = 0
  • 넷째 자리: 00=00 \oplus 0 = 0

XOR의 되돌리기(복호화) 성질

XOR의 가장 중요한 암호학적 성질은 같은 값을 두 번 XOR하면 원래 값으로 되돌아온다는 것이다. 이는 스트림 암호가 평문을 키와 XOR해 암호문을 만들고, 같은 키를 다시 XOR해 평문을 복원하는 원리의 근거다.

(AB)B=A(A \oplus B) \oplus B = A

앞의 예시로 확인하면, 10100110=11001010 \oplus 0110 = 1100이었다. 여기에 다시 01100110을 XOR하면 다음과 같다.

11000110=10101100 \oplus 0110 = 1010
  • 첫째 자리: 10=11 \oplus 0 = 1
  • 둘째 자리: 11=01 \oplus 1 = 0
  • 셋째 자리: 01=10 \oplus 1 = 1
  • 넷째 자리: 00=00 \oplus 0 = 0

결과 10101010은 처음 평문과 정확히 일치한다. 이 구조에서 "10101010"을 평문, "01100110"을 키, "11001100"을 암호문이라고 이름 붙이면, 암호화는 평문과 키를 XOR하는 것이고 복호화는 암호문과 같은 키를 다시 XOR하는 것이 된다. 05편의 스트림 암호는 이 원리를 그대로 사용하되, 매번 같은 키를 반복하지 않고 키로부터 생성한 긴 난수열(키스트림)을 사용해 안전성을 높인다.

같은 키를 두 번 이상 재사용해 서로 다른 평문을 암호화하면, 두 암호문을 XOR한 결과가 두 평문의 XOR과 같아져서(C1C2=P1P2C_1 \oplus C_2 = P_1 \oplus P_2) 평문 정보가 새어 나갈 수 있다. 이것이 스트림 암호에서 “키 재사용 금지”가 강조되는 수학적 이유이며, 05편에서 이 문제를 다시 다룬다.

키 공간과 브루트포스 확률

키 공간(key space)

쉽게 말하면: 키가 몇 비트냐에 따라 가능한 키의 개수가 기하급수적으로 늘어난다.

키 공간은 암호에서 사용 가능한 키의 전체 경우의 수를 뜻한다. 키가 nn비트로 이루어져 있다면, 각 비트가 0 또는 1 두 가지 값을 가질 수 있으므로 키 공간의 크기는 2n2^n이다.

키 공간 크기=2n\text{키 공간 크기} = 2^n
  • nn: 키의 비트 길이.
  • 2n2^n: 가능한 키의 총 개수.

몇 가지 비트 길이에 대한 실제 값을 계산해 보면 크기 증가를 체감할 수 있다.

키 길이 nn키 공간 크기 2n2^n
4비트24=162^4 = 16
8비트28=2562^8 = 256
16비트216=65,5362^{16} = 65,536
40비트240=1,099,511,627,7762^{40} = 1,099,511,627,776(약 1조)

키 길이가 1비트 늘어날 때마다 키 공간은 정확히 두 배로 늘어난다. 이것이 128비트, 256비트 같은 현대 암호 키 길이가 왜 “충분히 안전하다”고 여겨지는지의 근거다.

브루트포스(brute-force) 성공 확률

브루트포스 공격(무차별 대입 공격)은 가능한 모든 키를 하나씩 시도해 정답 키를 찾는 방법이다. 키 공간이 2n2^n일 때, 무작위로 한 번 시도해서 정답을 맞힐 확률은 다음과 같다.

P(한 번 시도로 성공)=12nP(\text{한 번 시도로 성공}) = \frac{1}{2^n}

8비트 키(28=2562^8 = 256)를 예로 들면 한 번 시도로 맞힐 확률은 1256=0.0039\frac{1}{256} = 0.0039, 즉 약 0.39퍼센트다. 평균적으로 정답을 찾기까지 시도해야 하는 횟수는 전체 키 공간의 절반 정도(운이 좋으면 더 빨리, 나쁘면 전체를 다 시도)로 어림잡을 수 있다.

평균 시도 횟수2n2=2n1\text{평균 시도 횟수} \approx \frac{2^n}{2} = 2^{n-1}

8비트라면 평균 128번 정도 시도하면 찾아낼 수 있다는 뜻이며, 컴퓨터에게는 순식간이다. 반면 128비트 키의 평균 시도 횟수는 21272^{127}로, 이는 지구상의 모든 컴퓨터가 초당 수십억 번씩 시도해도 우주의 나이보다 긴 시간이 걸리는 규모다. 05~06편에서 “이 알고리즘의 키 길이가 충분한가”를 판단할 때 이 확률 감각을 그대로 사용한다.

논리식과 진리표: 보안 정책 서술의 언어

쉽게 말하면: 방화벽 규칙이나 접근통제 정책은 결국 참·거짓을 판단하는 논리식으로 표현된다.

정보보호 관리(13~14편)의 접근통제 규칙, 방화벽 정책, 조건부 인증 규칙은 모두 논리식(참 또는 거짓 값을 갖는 명제를 연산자로 연결한 식)으로 표현할 수 있다. 기본 논리연산자는 다음과 같다.

연산자기호
논리곱(AND)\land두 명제가 모두 참일 때만 참
논리합(OR)\lor두 명제 중 하나라도 참이면 참
부정(NOT)¬\lnot명제의 참/거짓을 뒤집음

예를 들어 “사내 IP 대역에서 접속했고(P) AND 유효한 인증서를 제시했다(Q)“라는 접근 허용 규칙을 PQP \land Q로 쓸 수 있다. 진리표로 이 규칙을 확인하면 다음과 같다.

PPQQPQP \land Q
거짓거짓
거짓거짓
거짓거짓거짓

이 표는 “IP 조건과 인증서 조건 둘 다 만족해야 접속이 허용된다”는 정책을 정확하게 표현한다. 만약 정책이 “IP 대역 조건 또는 인증서 조건 중 하나만 만족해도 허용”이라면 PQP \lor Q로 바뀌고, 진리표에서 참이 되는 경우의 수도 3가지로 늘어난다. 14편의 접근통제 모델(MAC·DAC·RBAC)이나 방화벽 규칙을 읽을 때, “그리고(AND)“인지 “또는(OR)“인지를 정확히 구분하는 것이 정책 해석의 핵심이며, 이 구분을 틀리면 정반대의 접근 결과를 예측하게 된다.

일상 언어의 “또는”은 문맥에 따라 배타적(둘 중 하나만)일 수도 있지만, 논리학의 OR(\lor)은 기본적으로 포괄적이어서 둘 다 참인 경우도 참으로 취급한다. 보안 정책 문서에서 이 둘을 구분하지 않고 쓰면 의도와 다른 접근통제 규칙이 만들어질 수 있다.

자주 틀리는 점

  • 모듈러 연산을 나머지가 아니라 몫으로 착각: 17mod517 \bmod 5의 답은 몫인 3이 아니라 나머지인 2다.
  • 모듈러 지수 계산에서 중간 나머지 생략을 잊음: 제곱-곱 알고리즘의 핵심은 매 단계 나머지를 취해 숫자를 작게 유지하는 것이다. 끝까지 큰 수로 계산한 뒤 마지막에만 나머지를 취해도 수학적으로는 같은 답이 나오지만, 실제 암호 시스템에서는 그렇게 하면 계산이 불가능할 정도로 느려진다.
  • 이산로그 문제를 일반 로그처럼 쉽게 풀 수 있다고 오해: 정방향(거듭제곱)은 쉽고 역방향(지수 찾기)은 어렵다는 비대칭성이 핵심이며, 이 비대칭성 자체가 공개키 암호의 안전성 근거다.
  • XOR과 OR을 혼동: 11=01 \oplus 1 = 0이지만 11=11 \lor 1 = 1이다. 두 연산자의 진리표 마지막 행이 다르다는 점을 기억한다.
  • 키 길이와 키 공간 크기의 관계를 선형으로 오해: 키 길이가 1비트 늘 때마다 키 공간은 더하기 1이 아니라 곱하기 2(즉 2n2^n)로 늘어난다.
  • 논리식의 AND와 OR을 일상어 감각으로만 판단: 보안 정책 문서의 “그리고/또는”은 반드시 논리식으로 옮겨 진리표로 검증해야 한다.

핵심 정리

  • 모듈러 연산은 나머지를 취하는 연산이며, 덧셈·곱셈에 대한 분배 성질 덕분에 큰 수를 작게 유지하며 계산할 수 있다.
  • 모듈러 지수는 제곱-곱 알고리즘으로 빠르게 계산하며, 이는 RSA·디피-헬만 계산의 기초가 된다. 모듈러 역원은 모듈러 세계의 나눗셈 역할을 한다.
  • 이산로그 문제는 정방향(거듭제곱)은 쉽지만 역방향(지수 찾기)은 어려운 계산 비대칭성을 가지며, 이것이 여러 공개키 암호의 안전성 근거다.
  • XOR은 같은 값을 두 번 적용하면 원래대로 되돌아오는 성질이 있어 스트림 암호의 암·복호화에 그대로 쓰인다.
  • 키 공간은 2n2^n으로 커지며, 브루트포스의 평균 성공 시도 횟수는 2n12^{n-1}이다. 이 감각이 안전한 키 길이 판단의 기준이 된다.
  • 보안 정책은 AND·OR·NOT으로 이루어진 논리식과 진리표로 정확히 표현·검증할 수 있다.

마무리 복습

문제 14지선다
17을 5로 나눈 나머지, 즉 17 mod 5의 값은?
문제 24지선다
제곱-곱 알고리즘으로 3^7 mod 11을 계산한 값은?
문제 34지선다
이산로그 문제가 공개키 암호의 안전성 근거가 되는 이유로 가장 적절한 것은?
문제 44지선다
1010과 0110을 XOR한 결과는?
문제 54지선다
키 길이가 8비트에서 16비트로 늘어나면 키 공간의 크기는 어떻게 변하는가?

참고 자료

Last updated on