2011-04-28 10 views
2

私は大学で勉強するのに役立つRSAの実装を少し書いています。私は修正できないバグを見つけました。Pythonで同じキーの解読出力が異なりますRSA

ここで私が持っているコードは、これまでです:

import numpy 

def primesfrom2to(n): 
    """ Input n>=6, Returns a array of primes, 2 <= p < n 
     Taken from: http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188 """ 
    sieve = numpy.ones(n/3 + (n%6==2), dtype=numpy.bool) 
    for i in xrange(1,int(n**0.5)/3+1): 
     if sieve[i]: 
      k=3*i+1|1 
      sieve[  k*k/3  ::2*k] = False 
      sieve[k*(k-2*(i&1)+4)/3::2*k] = False 
    return numpy.r_[2,3,((3*numpy.nonzero(sieve)[0][1:]+1)|1)] 

def extended_gcd(a, b): 
    if b == 0: 
     return (1, 0) 
    else: 
     q = a/b 
     r = a - b * q 
     s, t = extended_gcd(b, r) 
     return (t, s - q * t) 

def pick_e(phi): 
    primes = primesfrom2to(phi) 
    e = primes[0] 
    i = 0 
    while phi % e != 1 and 1 < e < phi: 
     i += 1 
     e = primes[i] 
    return e 

def RSA(p, q, e=None): 
    n = p * q 
    phi = (p-1) * (q-1) 
    if not e: 
     e = pick_e(phi) 
    x, y = extended_gcd(e, phi) 
    d = x % phi 
    return (e, n), (d, n) 

def encrypt(P, public_key): 
    C = P**public_key[0] % public_key[1] 
    return C 

def decrypt(C, private_key): 
    P = C**private_key[0] % private_key[1] 
    return P 

public_key, private_key = RSA(11, 13) 
public_key2, private_key2 = RSA(11, 13, 7) 
print public_key, private_key 
print public_key2, private_key2 

print "public_key and private_key" 
print "plaintext -> ciphertext -> plaintext" 
for i in range(1,10): 
    c = encrypt(i, public_key) 
    p = decrypt(c, private_key) 
    print "%9d -> %10d -> %9d" % (i, c, p) 

print "public_key2 and private_key2" 
print "plaintext -> ciphertext -> plaintext" 
for i in range(1,10): 
    c = encrypt(i, public_key2) 
    p = decrypt(c, private_key2) 
    print "%9d -> %10d -> %9d" % (i, c, p) 

私が手出力は次のようになります。

(7, 143) (103, 143) 
(7, 143) (103, 143) 
public_key and private_key 
plaintext -> ciphertext -> plaintext 
     1 ->   1 ->   1 
     2 ->  128 ->   0 
     3 ->   42 ->   0 
     4 ->   82 ->   0 
     5 ->   47 ->  15 
     6 ->   85 ->  126 
     7 ->   6 ->   0 
     8 ->   57 ->  47 
     9 ->   48 ->   0 
public_key2 and private_key2 
plaintext -> ciphertext -> plaintext 
     1 ->   1 ->   1 
     2 ->  128 ->   2 
     3 ->   42 ->   3 
     4 ->   82 ->   4 
     5 ->   47 ->   5 
     6 ->   85 ->   6 
     7 ->   6 ->   7 
     8 ->   57 ->   8 
     9 ->   48 ->   9 

キーが同じであるため、両方の出力は同じである必要があります。誰かが私が間違っているのを見ることができますか?

+0

(少なくとも:-)私のために)期待どおりにコードが動作する

return int(e) 

でreturn文を交換する場合、これはあなたの質問に答えていますが、あなたはあなたのコードが正しいことをやっていることを確認することができます[pycrypto](http://www.dlitz.net/software/pycrypto/)で。 – nmichaels

+0

それはこの難問とは何かを持っている: (PDB) 'Cの== 128単位 真 (PDB)'(128 ** 103%143)==(C ** 103%143) ' 偽 –

答えて

1

あなたのpick_e関数は、明らかにintの代わりにnumpy.int64を返しています。あなたは

+0

このただし、floatではなくnumpy.int64です。これが私のコメントが上記のように判明した理由です。 –

+0

また、**の代わりにmath.powを使用した場合、@Frank Schmittが示唆しているintキャストなしで暗号化が機能します。私はこれについて説明していない。 –

+0

ヒントのおかげで、私はそれを修正しました(floppyをnumpy.int64に置き換えました) –

関連する問題