Bilgisayarlar taşma hataları olmadan üstel matematiği nasıl hesaplayabilir?


32

Bazı RSA şifreleme / şifre çözme yöntemlerini inceleyerek bu makaleyi buldum: RSA Algoritması Örneği

Bu mesajın şifresini çözmek gerekiyor. görüntü tanımını buraya girin

Toplamı görüntü tanımını buraya girino kadar büyük ki, 64-bit / 32-bit bir makine için, bir kayıtta bu kadar büyük bir değer tutabileceğine inanmıyorum. Bilgisayar taşma olmadan nasıl yapar?


Bu soru Haftanın Süper Kullanıcısı Sorusuydu . Daha fazla ayrıntı için blog girişini
okuyun veya bloga kendiniz katkıda bulunun


6
Acaba bu cs.stackexchange.com'a taşınırsa daha iyi bir cevap alır mısınız diye merak ediyorum. Bu, düşük şeylerin gerçek detaylarına çok daha fazla odaklanan bir CS / Math sitesine daha uygun olabilir gibi görünmektedir.
Zoredache

1
Bu Süper Kullanıcı için yeterince geçerlidir.
James Mertz

Yanıtlar:


40

Tamsayı modülü işlemi, ℤ -> ℤ / nℤ 'den bir halka homomorfizmi ( Wikipedia ) olduğu için,

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

Bunu kendiniz biraz basit cebir ile doğrulayabilirsiniz. ( modSağ taraftaki finalin , modüler bir halkadaki çarpma tanımı nedeniyle göründüğünü unutmayın.)

Bilgisayarlar bu numarayı modüler halkalardaki üstel sayıları hesaplamak için çok sayıda basamak hesaplamak zorunda olmadan kullanır.

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

Algoritmik formda,

-- 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

İsterseniz, (855^2753) mod 3233yalnızca 16 bitlik kayıtlarla hesaplamak için bunu kullanabilirsiniz .

Ancak, RSA'daki X ve N değerleri çok daha büyüktür, bir sicile sığmayacak kadar büyüktür. Bir modül tipik olarak 1024-4096 bit uzunluğundadır! Böylece, bir bilgisayarı çarpma işlemini "uzun" yolla, aynı şekilde elle çarpma işlemine sokabilirsiniz. Sadece yerine 0-9 kullanmak yerine, bilgisayar "kelimelerini" 0-2 kullanacağı 16 böyle -1 falan. (Yalnızca 16 bit kullanarak, iki 16 bit sayıyı çarpabileceğimiz ve derleme diline başvurmadan tam 32 bit sonuç alabileceğimiz anlamına gelir. , tam 128 bit sonuç.)

-- 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

Bu, X'i Y ile Y'de çarparak, X'deki kelimelerin sayısına kabaca eşit bir sürede Y'deki kelimelerin sayısı ile çarpacaktır. Buna O (N 2 ) zamanı denir . Yukarıdaki algoritmaya bakarsanız ve ayırırsanız, okulda öğrettikleri aynı "uzun çarpma" olur. 10 haneye kadar hafızaya alınmış zaman çizelgelerine sahip değilsiniz, ancak eğer oturup çalışırsanız hala 1.926.348 x 8,192,004 ile çarpabilirsiniz.

Uzun çarpma:

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

Strassen'in hızlı Fourier yöntemi gibi çarpma ( Wikipedia ) gibi bazı daha hızlı algoritmalar ve daha fazla toplama ve çıkarma yapan, ancak daha az çarpma yapan ve daha genel olarak sonuçlanan daha basit yöntemler var. GMP gibi sayısal kütüphaneler, sayıların ne kadar büyük olduğuna bağlı olarak farklı algoritmalar seçebilir: Fourier dönüşümü yalnızca en büyük sayılar için en hızlıdır, küçük sayılar daha basit algoritmalar kullanır.


+1, ancak mod NÇin Kalan Teoremi'nin sonunda fazladan bir şey eksik . ( (16 mod 5)Eşit değildir (4 mod 5) * (4 mod 5): eski 1, ikincisi 16'dır.)
ruakh

@ ruakh: Düzeltildi. Gerçekten söylemek istediğim halde, R / kR, R / k1R x R / k2R x ... R / knR'ye göre izomorfiktir, burada k1..kn çift kopyadır, ürünleri k'dir ve R, esas ideal bir alandır. O kadar uzun o şey olarak görmek zor olduğu için * aşırı oldum ama modüler. Başka bir deyişle, benim normal gösterim kurallarım altında modbu gereksizdir.
Dietrich Epp

1
@Synetech: Fakat bu dört kelimeyi çok seviyorum: “Okuyucu için egzersiz.”
Dietrich Epp

1
(X * Y) mod N = (X mod N) * (Y mod N) mod Ndoğrudur, ancak Çin Kalan Teoremi ile ilgisi yoktur.
Dennis,

1
@Dennis: Şimdi cevapta kod alanının yapısını açıklığa kavuşturdum. (Yazdığımdan beri bana asla belirsiz geliyor ...)
Dietrich Epp

9

Basit cevap, kendi başlarına değil, yapamayacaklarıdır. Aslında, eğer bir x-bit makinesi kavramını alırsanız, sınırlı sayıda bit ile temsil edilebilecek sınırlı sayıda sayı vardır, tıpkı 2 basamakla gösterilebilen sınırlı sayıda sayı olduğu gibi ondalık sistemi.

Olduğu söyleniyor, çok büyük sayıların bilgisayar temsili kriptografi alanının büyük bir bileşenidir . Bir bilgisayarda çok büyük sayıları temsil etmenin birçok yolu vardır, her biri bir sonrakine göre değişir.

Bu yöntemlerin her birinin farklı avantajları ve dezavantajları vardır ve burada tüm yöntemleri listelemiyorum / listelemiyorum ancak çok basit bir tane sunacağım.

Bir tamsayının yalnızca 0-99 arasındaki değerleri tutabildiğini varsayalım. Kişi 100 sayısını nasıl temsil edebilir? Bu ilk başta imkansız görünebilir, ancak bunun nedeni sadece tek bir değişkeni göz önünde bulundurmamızdır. Bir tamsayılı unitsve bir tanesini aradıysam hundreds, 100: 'ü kolayca temsil edebilirdim hundreds = 1; units = 0;. 9223: gibi daha büyük bir sayıyı kolayca temsil edebilirim hundreds = 92; units = 23.

Bu kolay bir yöntem olsa da, çok verimsiz olduğu iddia edilebilir. Bir bilgisayarın yapabileceklerinin sınırlarını zorlayan çoğu algoritma gibi, bu genellikle güç (büyük sayıları temsil eder) ve verimlilik (hızlı alım / depolama) arasındaki bir mücadeledir. Daha önce de söylediğim gibi, bilgisayarlarda büyük sayıları temsil etmenin birçok yolu vardır; sadece bir yöntem bulun ve deneyin!

Umarım bu sorunuzu cevaplamıştır!

Daha fazla okuma:Bu makale ve bu daha fazla bilgi için kullanışlı olabilir.


3

Bunun yapılabilmesi (tekrarlanan kareleri ve benzerlerini içeren çok daha hızlı yollar vardır) çarpmadır ve her çarpmadan sonra modülü alır. Kare modülü 2 ^ 32 (veya 2 ^ 64) 'ten küçük olduğu sürece, bu asla taşma yapmaz.


3

Yapabileceğin gibi.

342 * 189'un ne olduğunu önceden bilmediğini tahmin edeceğim. Ancak aşağıdaki gerçekleri biliyorsunuz:

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

Bu basit gerçekleri bilerek ve onları işlemek için bir teknik öğrenerek, başka türlü yapamayacağınız aritmetik işlemler yapabilirsiniz.

Aynı şekilde, bir seferde 64 bitten fazla matematik işleyemeyen bir bilgisayar, daha büyük sorunları kolayca daha küçük parçalara bölebilir, daha küçük parçaları yapabilir ve daha önce daha büyük olan cevabı oluşturmak için bunları bir araya getirebilir. cevaplanamayan bir problem.


0

Toplama ve çıkarma işlemleri söz konusu olduğunda, birçok CPU aritmetik işlemin taşması durumunda ayarlanan bir "carry bit" e sahiptir. Bu nedenle, bir sonuç 8 byte'lık bir depoya ihtiyaç duyarsa ve CPU 32-bit ise (ki bu 4-bitlik baytları doldurur), önce "düşük kelime" ve sonra "yüksek kelime" olmak üzere iki ekleme işlemi yapabilir. taşıma biti taşma ile ilgileniyor. Önce taşıma biti temizlemek gerekir. Bu, yüksek bit işlemcilerin performansı artırmasının bir nedenidir, çünkü bu kadar yapılması gerekmez.

Tabii ki bu 8-bit CPU'larla sınırlı montajcı deneyimimden kaynaklanıyor. Carry bit'in çarpma ve bölme talimatlarıyla modern işlemcilerle nasıl çalıştığını bilmiyorum. Intel olmayan RISC CPU'ları da farklı şekilde davranabilir.

Kayan nokta matematiği hakkında pek bir şey bilmiyorum ama temel olarak baytlar belirli bir yeri değil, belirli yerleri temsil ediyor. Bu yüzden buna "kayan nokta" denir. Örneğin, 34459234 sayısı, 3.4459234 veya 3.4459234E + 20 ile yaklaşık olarak aynı bellek alanını tüketecektir (bu 3.4459234 x 10 ^ 20'dir).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.