컴퓨터가 어떻게 오버플로 오류없이 지수 수학을 계산할 수 있습니까?


32

RSA 암호화 / 복호화 방법을 연구하면서이 기사를 찾았 습니다. RSA 알고리즘의 예

이 메시지를 해독하려면 이것이 필요합니다 여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오64 비트 / 32 비트 시스템 의 경우 전체 결과 가 너무 커서 하나의 레지스터에 큰 값을 보유 할 수 있다고 생각하지 않습니다. 컴퓨터가 오버플로없이 어떻게합니까?


이 질문은 금주슈퍼 사용자 질문입니다 . 자세한 내용
블로그 항목 을 읽 거나 블로그에 직접 참여 하십시오.


6
이것이 cs.stackexchange.com으로 마이그레이션 된 경우 더 나은 답변을 얻을 수 있을지 궁금합니다. 이것은 CS / Math 사이트에 더 잘 맞을 것 같습니다. 낮은 것의 실제 세부 사항에 훨씬 더 초점을 맞춘 것은 실제로 낮은 수준입니다.
Zoredache

1
이것은 슈퍼 유저에게 충분합니다.
제임스 메르 츠

답변:


40

정수 계수 조작 링 동형 (이므로 위키 ℤ에서)이 -> ℤ / nℤ,

(X * Y) mod N = (X mod N) * (Y mod N) mod N

약간의 간단한 대수로 직접 확인할 수 있습니다. ( mod오른쪽 의 마지막 은 모듈 링의 곱셈 정의로 인해 나타납니다.)

컴퓨터는이 트릭을 사용하여 많은 수의 자릿수를 계산하지 않고도 모듈 식 링으로 지수를 계산합니다.

               / 1 I = 0,
               |
(X ^ I) mod N = <(X * (X ^ (I-1) mod N)) mod NI 홀수,
               |
               \ (X ^ (I / 2) mod N) ^ 2 mod NI 짝수 & I / = 0.

알고리즘 형태로

-- compute X^I mod N
function expmod(X, I, N)
    if I is zero
        return 1
    elif I is odd
        return (expmod(X, I-1, N) * X) mod N
    else
        Y <- expmod(X, I/2, N)
        return (Y*Y) mod N
    end if
end function

원하는 경우이를 사용 (855^2753) mod 3233하여 16 비트 레지스터만으로 계산할 수 있습니다 .

그러나 RSA의 X 및 N 값은 레지스터에 맞지 않을 정도로 훨씬 큽니다. 모듈러스는 일반적으로 길이가 1024-4096 비트입니다! 따라서 컴퓨터가 곱셈을 "긴"방식으로, 곱셈을 수동으로하는 것과 같은 방식으로 곱셈을 수행 할 수 있습니다. 컴퓨터는 숫자 0-9를 사용하는 대신 "단어"0-2 16 -1 또는 이와 유사한 것을 사용합니다. (16 비트 만 사용한다는 것은 어셈블리 언어에 의존하지 않고 2 개의 16 비트 숫자를 곱하고 전체 32 비트 결과를 얻을 수 있음을 의미합니다. 어셈블리 언어에서는 일반적으로 전체 64 비트 결과 또는 64 비트 컴퓨터를 얻는 것이 매우 쉽습니다. 전체 128 비트 결과입니다.)

-- Multiply two bigints by each other
function mul(uint16 X[N], uint16 Y[N]):
    Z <- new array uint16[N*2]
    for I in 1..N
        -- C is the "carry"
        C <- 0
        -- Add Y[1..N] * X[I] to Z
        for J in 1..N
            T <- X[I] * Y[J] + C + Z[I + J - 1]
            Z[I + J - 1] <- T & 0xffff
            C <- T >> 16
        end
        -- Keep adding the "carry"
        for J in (I+N)..(N*2)
            T <- C + Z[J]
            Z[J] <- T & 0xffff
            C <- T >> 16
        end
    end
    return Z
end
-- footnote: I wrote this off the top of my head
-- so, who knows what kind of errors it might have

이것은 X의 단어 수와 Y의 단어 수를 곱한 시간과 거의 같은 시간에 X에 Y를 곱합니다. 이것을 O (N 2 ) 시간이라고합니다. 위의 알고리즘을보고 따로 따로 선택하면 학교에서 가르치는 것과 동일한 "긴 곱셈"입니다. 10 자리로 기억 된 시간표는 없지만, 앉아서 계산하면 여전히 1,926,348 x 8,192,004를 곱할 수 있습니다.

긴 곱셈 :

    1,234
  x 5,678
---------
    9,872
   86,38
  740,4
6,170
---------
7,006,652

Strassen의 빠른 푸리에 방법과 같이 곱셈 ( Wikipedia )과 관련하여 더 빠른 알고리즘이 실제로 있으며 , 더하기와 빼기를 수행하지만 곱셈은 덜하는 간단한 방법이 있으므로 전체적으로 더 빠릅니다. GMP와 같은 숫자 라이브러리는 숫자의 크기에 따라 다른 알고리즘을 선택할 수 있습니다. 푸리에 변환은 가장 큰 숫자에 대해서만 가장 빠르며 작은 숫자는 더 간단한 알고리즘을 사용합니다.


+1이지만 mod NChinese Remainder Theorem의 끝에 여분 의 것이 없습니다 . ( (16 mod 5)과 같지 않음 (4 mod 5) * (4 mod 5): 전자는 1, 후자는 16입니다.)
ruakh

@ruakh : 수정했습니다. 실제로 말하고 싶지만, R / kR은 R / k1R x R / k2R x ... R / knR과 동형입니다. 내가 너무 오래 그것은 아무것도 볼 어렵다 것을 위해 * 과부하를 봤는데 하지만 모듈. 다시 말해서, 나의 일반적인 표기법에 따르면 mod불필요합니다.
Dietrich Epp

1
@Synetech : 그러나 나는이 네 단어를 너무나 좋아합니다. "독자 운동."
Dietrich Epp

1
(X * Y) mod N = (X mod N) * (Y mod N) mod N사실이지만 중국 나머지 정리와는 아무런 관련이 없습니다.
Dennis

1
@ 데니스 : 나는 대답에서 공동 도메인의 구조를 분명히했습니다. (내가 그것을 쓴 이후로 그것은 나에게 모호하지 않다 ...)
Dietrich Epp

9

간단히 대답하면 스스로 할 수는 없으며 할 수 없다는 것입니다. 실제로, x- 비트 머신의 개념을 취하면, 제한된 수의 숫자가있는 것처럼, 제한된 수의 숫자가있는 것처럼, 제한된 수의 숫자가 있습니다. 십진법.

즉, 매우 많은 수의 컴퓨터 표현 은 암호화 분야의 큰 구성 요소 입니다. 컴퓨터에는 매우 큰 숫자를 나타내는 여러 가지 방법이 있으며 각각 다음과 같이 다양합니다.

각 방법마다 장단점이 있으며 여기에 모든 방법을 나열하지는 못하지만 매우 간단한 방법을 제시합니다.

정수가 0-99의 값만 보유 할 수 있다고 가정하십시오. 어떻게 숫자 100을 나타낼 수 있습니까? 이것은 처음에는 불가능 해 보일 수 있지만 단일 변수 만 고려하기 때문입니다. 이라는 정수 units와 이라는 정수가 있으면 hundreds쉽게 100을 나타낼 수 있습니다 hundreds = 1; units = 0;. 9223 :과 같이 더 큰 숫자를 쉽게 나타낼 수 있습니다 hundreds = 92; units = 23.

이것은 쉬운 방법이지만 매우 비효율적이라고 주장 할 수 있습니다. 컴퓨터가 할 수있는 것의 경계를 넓히는 대부분의 알고리즘과 마찬가지로, 일반적으로 전력 (대수를 나타냄)과 효율성 (빠른 검색 / 저장) 사이의 줄다리기입니다. 앞에서 말했듯이 컴퓨터에서 많은 수를 나타내는 여러 가지 방법이 있습니다. 방법을 찾아서 실험 해보십시오!

이것이 귀하의 질문에 대한 답변이 되었기를 바랍니다.

추가 자료 : 기사 와이 기사 는 더 많은 정보를 제공하는 데 유용 할 수 있습니다.


3

이것이 수행 될 수있는 방법 (반복 된 제곱 등을 포함하는 훨씬 빠른 방법이 있음)은 곱하는 것이며 모든 곱셈 후에 계수를 취합니다. 모듈러스 제곱이 2 ^ 32 (또는 2 ^ 64)보다 작 으면 오버플로가 발생하지 않습니다.


3

당신이 할 수있는 같은 방법.

나는 당신이 342 * 189가 무엇인지 알지 못한다고 추측 할 것입니다. 그러나 다음 사실을 알고 있습니다.

9 * 2 = 18
9 * 4 = 36
9 * 3 = 27
8 * 2 = 16
8 * 4 = 32
8 * 3 = 24
1 * 2 = 2
1 * 4 = 4
1 * 3 = 3

18 + 360 + 2700 + 160 + 3200 + 24000 + 200 + 4000 + 30000 = 64638

이러한 간단한 사실을 알고이를 조작하는 기술을 배운다면 다른 방법으로는 할 수 없었던 산술을 할 수 있습니다.

마찬가지로 한 번에 64 비트 이상의 수학을 처리 할 수없는 컴퓨터는 더 큰 문제를 더 작은 조각으로 쉽게 나누고 작은 조각을 한 다음 다시 모아서 더 큰 답을 형성 할 수 있습니다. 대답 할 수없는 문제.


0

덧셈과 뺄셈에 관한 한 많은 CPU에는 산술 연산이 오버플로 된 경우 설정된 "캐리 비트"가 있습니다. 따라서 결과를 저장하는 데 8 바이트가 필요하고 CPU가 32 비트 (4 개의 8 비트 바이트와 같음) 인 경우 먼저 "낮은 단어"와 "높은 단어"에 대해 두 가지 추가 작업을 수행 할 수 있습니다. 오버플로를 처리하는 캐리 비트로. 캐리 비트를 먼저 비워야합니다. 이것이 더 높은 비트 CPU가 성능을 향상시키는 이유 중 하나입니다.

물론 이것은 8 비트 CPU에 대한 제한된 어셈블러 경험에서 비롯된 것입니다. 캐리 비트가 곱하기 및 divde 명령어가있는 최신 CPU에서 어떻게 작동하는지 모르겠습니다. 인텔이 아닌 RISC CPU도 다르게 동작 할 수 있습니다.

부동 소수점 수학에 대해서는별로 알지 못하지만 기본적으로 바이트는 고정 된 수의 장소를 나타내지 만 특정 장소는 아닙니다. 그것이 "부동"지점이라고하는 이유입니다. 예를 들어 숫자 34459234는 3.4459234 또는 3.4459234E + 20 (3.4459234 x 10 ^ 20)과 거의 동일한 메모리 공간을 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.