쌍마다 서로소인 여러 수로 나눈 나머지를 모아 두면, 그것만으로 원래 수가 하나의 합동류로 정해진다. 중국인의 나머지 정리는 그런 수가 반드시 존재하고 그 합동류가 유일하다 는 것을 보장하고, 그 수를 직접 만드는 방법까지 준다.
이 포스트에서 다루는 내용
설정 : m 1 , … , m r m_1, \ldots, m_r m 1 , … , m r 이 서로 쌍으로 서로소(pairwise coprime)이고 m = m 1 ⋯ m r m = m_1 \cdots m_r m = m 1 ⋯ m r
보장 : 임의의 c 1 , … , c r c_1, \ldots, c_r c 1 , … , c r 에 대해 x ≡ c i ( m o d m i ) x \equiv c_i \pmod{m_i} x ≡ c i ( mod m i ) 를 동시에 만족하는 x x x 가 m o d m \bmod\ m mod m 에서 유일하게 존재
구성 : M i = m / m i M_i = m/m_i M i = m / m i , N i = M i − 1 m o d m i N_i = M_i^{-1} \bmod m_i N i = M i − 1 mod m i , x = ∑ c i M i N i m o d m x = \sum c_i M_i N_i \bmod m x = ∑ c i M i N i mod m
응용 : RSA-CRT 최적화 (처리 속도 약 4배 향상)
정확한 설정
m 1 , … , m r m_1, \ldots, m_r m 1 , … , m r 이 쌍으로 서로소(pairwise coprime) : 임의의 i ≠ j i \neq j i = j 에 대해 gcd ( m i , m j ) = 1 \gcd(m_i, m_j) = 1 g cd( m i , m j ) = 1 .
여기서 주의할 점은 전체 gcd가 1인 것 과 쌍으로 서로소 는 다르다는 것이다. 예를 들어 { 6 , 10 , 15 } \{6, 10, 15\} { 6 , 10 , 15 } 는 gcd ( 6 , 10 , 15 ) = 1 \gcd(6,10,15)=1 g cd( 6 , 10 , 15 ) = 1 이지만, gcd ( 6 , 10 ) = 2 ≠ 1 \gcd(6,10)=2 \neq 1 g cd( 6 , 10 ) = 2 = 1 이므로 쌍으로 서로소가 아니다.
m = m 1 ⋅ m 2 ⋯ m r m = m_1 \cdot m_2 \cdots m_r m = m 1 ⋅ m 2 ⋯ m r 로 정의한다.
정리 : 임의의 정수 c 1 , … , c r c_1, \ldots, c_r c 1 , … , c r 에 대해, 다음 연립 합동식을 동시에 만족하는 x x x 가 m o d m \bmod\ m mod m 에서 유일하게 존재한다.
x ≡ c 1 ( m o d m 1 ) , x ≡ c 2 ( m o d m 2 ) , … , x ≡ c r ( m o d m r ) x \equiv c_1 \pmod{m_1}, \quad x \equiv c_2 \pmod{m_2}, \quad \ldots, \quad x \equiv c_r \pmod{m_r} x ≡ c 1 ( mod m 1 ) , x ≡ c 2 ( mod m 2 ) , … , x ≡ c r ( mod m r )
유일성 증명
x x x 와 y y y 가 모두 연립 합동식을 만족한다고 하자. 그러면 각 i i i 에 대해
x ≡ c i ( m o d m i ) , y ≡ c i ( m o d m i ) ⟹ m i ∣ ( x − y ) x \equiv c_i \pmod{m_i}, \quad y \equiv c_i \pmod{m_i} \implies m_i \mid (x - y) x ≡ c i ( mod m i ) , y ≡ c i ( mod m i ) ⟹ m i ∣ ( x − y )
m 1 , … , m r m_1, \ldots, m_r m 1 , … , m r 이 쌍으로 서로소이고 모두 ( x − y ) (x-y) ( x − y ) 를 나누므로, 이들의 곱도 ( x − y ) (x-y) ( x − y ) 를 나눈다.
m = m 1 ⋯ m r ∣ ( x − y ) ⟹ x ≡ y ( m o d m ) m = m_1 \cdots m_r \mid (x - y) \implies x \equiv y \pmod{m} m = m 1 ⋯ m r ∣ ( x − y ) ⟹ x ≡ y ( mod m )
따라서 해는 m o d m \bmod\ m mod m 에서 유일하다.
존재성 증명 — 구성 (Construction)
다음과 같이 변수를 정의한다.
M i = m m i ( m i 를 제외한 나머지를 모두 곱한 값) M_i = \frac{m}{m_i} \quad \text{($m_i$를 제외한 나머지를 모두 곱한 값)} M i = m i m ( m i 를 제외한 나머지를 모두 곱한 값 )
M i M_i M i 와 m i m_i m i 는 서로소이다 (m i m_i m i 를 제외한 나머지의 곱이므로). 따라서 M i M_i M i 의 m o d m i \bmod\ m_i mod m i 역원이 존재한다.
N i = M i − 1 ( m o d m i ) (베주 항등식으로 계산) N_i = M_i^{-1} \pmod{m_i} \quad \text{(베주 항등식으로 계산)} N i = M i − 1 ( mod m i ) ( 베주 항등식으로 계산 )
이제 다음을 해(解)로 정의한다.
x = ∑ i = 1 r c i M i N i ( m o d m ) x = \sum_{i=1}^{r} c_i M_i N_i \pmod{m} x = i = 1 ∑ r c i M i N i ( mod m )
검증 : j j j 번째 조건 x ≡ c j ( m o d m j ) x \equiv c_j \pmod{m_j} x ≡ c j ( mod m j ) 를 확인한다.
x m o d m j = ∑ i = 1 r c i M i N i m o d m j x \bmod m_j = \sum_{i=1}^{r} c_i M_i N_i \bmod m_j x mod m j = i = 1 ∑ r c i M i N i mod m j
i ≠ j i \neq j i = j 인 항: M i = m / m i M_i = m/m_i M i = m / m i 에 m j m_j m j 가 인수로 포함되어 있으므로 M i ≡ 0 ( m o d m j ) M_i \equiv 0 \pmod{m_j} M i ≡ 0 ( mod m j ) . 해당 항은 사라진다.
i = j i = j i = j 인 항: M j N j ≡ 1 ( m o d m j ) M_j N_j \equiv 1 \pmod{m_j} M j N j ≡ 1 ( mod m j ) (역원의 정의). 따라서 c j M j N j ≡ c j ( m o d m j ) c_j M_j N_j \equiv c_j \pmod{m_j} c j M j N j ≡ c j ( mod m j ) .
x ≡ c j ( m o d m j ) ✓ x \equiv c_j \pmod{m_j} \quad \checkmark x ≡ c j ( mod m j ) ✓
쉽게 말하면
CRT는 "여러 개의 작은 시계를 보고 하나의 큰 시계 시각을 알아내는 방법"이다. 서로소인 여러 수로 나눈 나머지들을 동시에 만족하는 수가 딱 하나 존재하고, 그 수를 명시적으로 구성할 수 있다. RSA에서는 이를 이용해 큰 수의 연산을 작은 수들의 연산으로 쪼개서 약 4배 빠르게 처리한다.
단계별 계산 예시
연립 합동식: x ≡ 2 ( m o d 3 ) x \equiv 2 \pmod{3} x ≡ 2 ( mod 3 ) , x ≡ 3 ( m o d 5 ) x \equiv 3 \pmod{5} x ≡ 3 ( mod 5 ) , x ≡ 2 ( m o d 7 ) x \equiv 2 \pmod{7} x ≡ 2 ( mod 7 )
m = 3 × 5 × 7 = 105 m = 3 \times 5 \times 7 = 105 m = 3 × 5 × 7 = 105
CRT 구성 계산표
단계 1 — M i M_i M i 계산:
M 1 = 105 3 = 35 , M 2 = 105 5 = 21 , M 3 = 105 7 = 15 M_1 = \frac{105}{3} = 35, \quad M_2 = \frac{105}{5} = 21, \quad M_3 = \frac{105}{7} = 15 M 1 = 3 105 = 35 , M 2 = 5 105 = 21 , M 3 = 7 105 = 15
단계 2 — N i N_i N i 계산 (베주 항등식 또는 직접 탐색):
35 ≡ 2 ( m o d 3 ) ⟹ N 1 = 2 − 1 ( m o d 3 ) = 2 ( 2 × 2 = 4 ≡ 1 ) 35 \equiv 2 \pmod{3} \implies N_1 = 2^{-1} \pmod{3} = 2 \quad (2 \times 2 = 4 \equiv 1) 35 ≡ 2 ( mod 3 ) ⟹ N 1 = 2 − 1 ( mod 3 ) = 2 ( 2 × 2 = 4 ≡ 1 )
21 ≡ 1 ( m o d 5 ) ⟹ N 2 = 1 − 1 ( m o d 5 ) = 1 21 \equiv 1 \pmod{5} \implies N_2 = 1^{-1} \pmod{5} = 1 21 ≡ 1 ( mod 5 ) ⟹ N 2 = 1 − 1 ( mod 5 ) = 1
15 ≡ 1 ( m o d 7 ) ⟹ N 3 = 1 − 1 ( m o d 7 ) = 1 15 \equiv 1 \pmod{7} \implies N_3 = 1^{-1} \pmod{7} = 1 15 ≡ 1 ( mod 7 ) ⟹ N 3 = 1 − 1 ( mod 7 ) = 1
단계 3 — 합산:
x = 2 ⋅ 35 ⋅ 2 + 3 ⋅ 21 ⋅ 1 + 2 ⋅ 15 ⋅ 1 = 140 + 63 + 30 = 233 x = 2 \cdot 35 \cdot 2 + 3 \cdot 21 \cdot 1 + 2 \cdot 15 \cdot 1 = 140 + 63 + 30 = 233 x = 2 ⋅ 35 ⋅ 2 + 3 ⋅ 21 ⋅ 1 + 2 ⋅ 15 ⋅ 1 = 140 + 63 + 30 = 233
233 m o d 105 = 23 233 \bmod 105 = 23 233 mod 105 = 23
검증 : 23 = 7 × 3 + 2 23 = 7 \times 3 + 2 23 = 7 × 3 + 2 ✓, 23 = 4 × 5 + 3 23 = 4 \times 5 + 3 23 = 4 × 5 + 3 ✓, 23 = 3 × 7 + 2 23 = 3 \times 7 + 2 23 = 3 × 7 + 2 ✓
연산 보존 성질
x x x 가 ( c 1 , … , c r ) (c_1, \ldots, c_r) ( c 1 , … , c r ) 에, y y y 가 ( d 1 , … , d r ) (d_1, \ldots, d_r) ( d 1 , … , d r ) 에 대응할 때, CRT 표현에서의 연산이 원래 연산을 보존한다.
x + y ⟷ ( c 1 + d 1 , c 2 + d 2 , … , c r + d r ) x + y \longleftrightarrow (c_1 + d_1,\ c_2 + d_2,\ \ldots,\ c_r + d_r) x + y ⟷ ( c 1 + d 1 , c 2 + d 2 , … , c r + d r )
x ⋅ y ⟷ ( c 1 d 1 , c 2 d 2 , … , c r d r ) x \cdot y \longleftrightarrow (c_1 d_1,\ c_2 d_2,\ \ldots,\ c_r d_r) x ⋅ y ⟷ ( c 1 d 1 , c 2 d 2 , … , c r d r )
즉, m m m 에 대한 큰 연산을 m i m_i m i 들에 대한 작은 연산들로 분해 할 수 있고, 결과를 다시 합칠 수 있다. 이것이 CRT 최적화의 핵심이다.
응용 — RSA-CRT 최적화
RSA 복호화는 m = c d m o d n m = c^d \bmod n m = c d mod n (n = p q n = pq n = pq )을 계산하는데, d d d 가 수백 비트이면 비용이 크다.
RSA-CRT 방법 : n = p q n = pq n = pq (p p p , q q q 소수, gcd ( p , q ) = 1 \gcd(p,q)=1 g cd( p , q ) = 1 )일 때 CRT를 적용한다.
m p = c d p ( m o d p ) , d p = d m o d ( p − 1 ) (페르마의 소정리 적용) m_p = c^{d_p} \pmod{p}, \quad d_p = d \bmod (p-1) \quad \text{(페르마의 소정리 적용)} m p = c d p ( mod p ) , d p = d mod ( p − 1 ) ( 페르마의 소정리 적용 )
m q = c d q ( m o d q ) , d q = d m o d ( q − 1 ) m_q = c^{d_q} \pmod{q}, \quad d_q = d \bmod (q-1) m q = c d q ( mod q ) , d q = d mod ( q − 1 )
m p m_p m p 와 m q m_q m q 를 구한 뒤 CRT로 m m o d n m \bmod n m mod n 을 복원한다.
속도 향상 이유. 비용을 세려면 모형을 먼저 정해야 한다. 모듈러스가 ℓ \ell ℓ 비트일 때 교과서 곱셈으로 모듈러 곱셈 한 번이 O ( ℓ 2 ) O(\ell^2) O ( ℓ 2 ) 이고, 제곱·곱셈 방식은 지수의 비트 수만큼 곱셈을 돌린다. 지수도 ℓ \ell ℓ 비트면 지수 연산 한 번은 O ( ℓ 3 ) O(\ell^3) O ( ℓ 3 ) 이다.
RSA-CRT에서는 두 가지가 함께 반으로 줄어든다. 모듈러스가 n n n 에서 p p p , q q q 로 바뀌어 ℓ / 2 \ell/2 ℓ /2 비트가 되고, 지수도 d d d 에서 d_p = d mod (p-1) 로 바뀌어 ℓ / 2 \ell/2 ℓ /2 비트가 된다. 그래서 한 번의 비용이
\left(rac{\ell}{2}
ight)^3 = rac{\ell^3}{8}
로 떨어진다. 이것을 두 번 하므로 합이 ℓ 3 / 4 \ell^3/4 ℓ 3 /4 , 곧 원래의 1 / 4 1/4 1/4 이다. 약 4배 가속 은 여기서 나온다.
지수가 짧아지는 부분을 빼먹으면 각각 1 / 4 1/4 1/4 에 두 번이라 1 / 2 1/2 1/2 , 곧 2배밖에 되지 않는다. 두 몫이 함께 줄어드는 것이 핵심이다.
CRT로 다시 합치는 비용은 O ( ℓ 2 ) O(\ell^2) O ( ℓ 2 ) 수준이라 ℓ 3 \ell^3 ℓ 3 앞에서 묻힌다. 다만 이 4배는 교과서 곱셈을 전제로 한 값이다. 곱셈에 더 빠른 알고리즘을 쓰면 지수가 달라져 배수도 달라진다.
핵심 정리
CRT는 쌍으로 서로소인 모듈러스들에 대한 연립 합동식이 m o d m \bmod\ m mod m 에서 유일한 해를 가짐을 보장한다.
유일성: 두 해의 차가 모든 m i m_i m i 의 배수이므로 m m m 의 배수 → m o d m \bmod\ m mod m 에서 동일. 존재성: 구성적 증명으로 해를 명시적으로 구성한다.
연산 보존 성질 덕분에 큰 모듈러스 연산을 작은 연산들로 분해·병렬화할 수 있다. 이것이 RSA-CRT의 수학적 근거다.
RSA-CRT는 n = p q n = pq n = pq 구조를 활용해 복호화 속도를 약 4배 향상시킨다. 모듈러스와 지수가 함께 절반이 되어 ℓ 3 \ell^3 ℓ 3 비용이 1 / 8 1/8 1/8 로 줄고, 그것을 두 번 하므로 1 / 4 1/4 1/4 이다. 교과서 곱셈을 전제로 한 값이다.
다음 포스트
Find Prime — 소수 판별과 확률적 소수 탐색 — 소수 밀도 추정, Fermat 테스트의 한계, Witness와 Miller-Rabin 테스트까지 — RSA에서 큰 소수를 어떻게 찾는지 다룬다.