2010-01-23 5 views
1

Tout ce que j'ai essayé m'a donné des valeurs de sortie erronées. J'ai même copié les codes C et les ai changés pour qu'ils fonctionnent en python et j'ai encore des mauvaises sorties. Qu'est-ce qui ne va pas?quel est le problème avec mon code python ripemd160?

import os, math 

def makehex(value,size=8): 
    value = hex(value)[2:] 
    if value[-1] == 'L': 
     value = value[0:-1] 
    while len(value)<size: 
     value = '0' + value 
    return value 

def makebin(value,size=32): 
    value = bin(value)[2:] 
    while len(value)<size: 
     value = '0' + value 
    return value 

def ROL(value,n): 
    return (value << n) | (value >> 32-n) 

def little_end(string,base = 16): 
    t = '' 
    if base == 2: 
     s= 8 
    if base == 16: 
     s = 2 
    for x in range(len(string)/s): 
     t = string[s*x:s*(x+1)] + t 
    return t 

def F(x,y,z,round): 
    if round<16: 
     return x^y^z 
    elif 16<=round<32: 
     return (x & y) | (~x & z) 
    elif 32<=round<48: 
     return (x | ~y)^z 
    elif 48<=round<64: 
     return (x & z) | (y & ~z) 
    elif 64<=round: 
     return x^(y | ~z) 

def RIPEMD160(data): 

# constants 
    h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE;h3 = 0x10325476; h4 = 0xC3D2E1F0 

    k = [0, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E] 
    kk = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9,0] 
    s =  [ 11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8, 
      7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12, 
      11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5, 
      11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12, 
      9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6] 
    ss=  [ 8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6, 
      9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11, 
      9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5, 
      15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8, 
      8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11] 
    r= range(16) + [ 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 
       3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 
       1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 
       4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13] 
    rr = [ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 
      6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 
      15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 
      8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 
      12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11] 

    # md4 padding + preprocessing 
    temp = '' 
    for x in data: 
     temp += makebin(ord(x),8) 
    length = len(temp)%2**64 
    temp +='1' 
    while len(temp)%512!=448: 
     temp+='0' 
    input = temp 
    temp = '' 
    for x in range(len(input)/32): 
     temp += little_end(input[32*x:32*(x+1)],2) 
    input = temp 
    temp = makebin(length,64) 
    input += temp[32:]+temp[:32] 
    t = len(input)/512 


    # the rounds 
    for i in range(t): 

      # i called the parallel round variables 2x the other round variable: a -> aa 
     a = aa = h0; b = bb = h1; c = cc = h2; d = dd = h3; e = ee = h4 
     X = input[512*i:512*(i+1)] 
     X = [int(X[32*x:32*(x+1)],2) for x in range(16)] 

     for j in range(80): 
      T = (a+ ROL((F(b, c, d, j) + X[r[j]] + k[j/16])%2**32,s[j])+e)%2**32 
      c = ROL(c, 10) 
      a = e; e = d; d = c; c = b; a = T 
      T = (aa+ ROL((F(bb,cc,dd,79-j) + X[rr[j]] + kk[j/16])%2**32,ss[j])+ee)%2**32 
      cc = ROL(cc,10) 
      aa = ee; ee = dd; dd = cc; cc = bb; aa = T 

     T = (h1+c+dd)%2**32 
     h1 = (h2+d+ee)%2**32 
     h2 = (h3+e+aa)%2**32 
     h3 = (h4+a+bb)%2**32 
     h4 = (h0+b+cc)%2**32 
     h0 = T 

    return little_end(makehex(h0))+little_end(makehex(h1))+little_end(makehex(h2))+little_end(makehex(h3))+little_end(makehex(h4)) 

    data = RIPEMD160('') 
    print data,data =='9c1185a5c5e9fc54612808977ee8f548b2258d31' # its always false 
+0

TL; DR mais un premier aperçu, je suppose que ROL devrait r Éteignez un nombre de 32 bits ?! Si c'est le cas, '... & 0xFFFFFFFF' est manquant. De toute façon, hashlib supporte RIPEMD160 ('hashlib.new (" ripemd160 ")'). – AndiDog

+0

J'imagine qu'une grande partie du problème vient de l'arithmétique entière. En C, l'algorithme s'appuierait sur un débordement de 32 bits. En Python, les entiers ne débordent pas, ils sont juste promus aux longs. – bobince

+0

j'ai déjà modulé les valeurs, donc je n'ai pas besoin de & ffffff. – calccrypto

Répondre

8
>>> import hashlib 
>>> data = '' 
>>> hashlib.new('ripemd160', data).hexdigest() 
'9c1185a5c5e9fc54612808977ee8f548b2258d31' 
+1

Je sais, mais j'essaye juste de l'implémenter moi-même, plutôt que de me fier aux programmes intégrés pour tout – calccrypto

+7

Vous voulez dire que vous préférez implémenter des erreurs vous-même plutôt que de vous appuyer sur une bibliothèque éprouvée et corrigée depuis des années? Première règle en cryptographie: Ne lancez pas votre propre bibliothèque. – nikola

1

Quels que soient les ennemis disent, votre code est beau. J'ai trouvé cela en essayant de faire fonctionner le mien. J'ai dû déboguer une bibliothèque C côte à côte avec la tienne. https://github.com/dlitz/pycrypto/blob/master/src/RIPEMD160.c

Quelques erreurs.

  1. Ceci obtenant le binaire de la valeur ASCII du caractère, au lieu de la valeur réelle.

    temp += makebin(ord(x),8) 
    
  2. Append la petite longueur endian avant de faire peu endian de X

  3. Ajouter un avant d'effectuer ROL
  4. Faire un masque sur c et T. Votre fonction ROL retourne 44 bit numéro

    import os, math 
    
    def makehex(value,size=8): 
        value = hex(value)[2:] 
        if value[-1] == 'L': 
         value = value[0:-1] 
        while len(value)<size: 
         value = '0' + value 
        return value 
    
    def makebin(value,size=32): 
        value = bin(value)[2:] 
        while len(value)<size: 
         value = '0' + value 
        return value 
    
    def ROL(value,n): 
        return (value << n) | (value >> 32-n) 
    
    def little_end(string,base = 16): 
        t = '' 
        if base == 2: 
         s= 8 
        if base == 16: 
         s = 2 
        for x in range(len(string)/s): 
         t = string[s*x:s*(x+1)] + t 
        return t 
    
    def F(x,y,z,round): 
        if round<16: 
         return x^y^z 
        elif 16<=round<32: 
         return (x & y) | (~x & z) 
        elif 32<=round<48: 
         return (x | ~y)^z 
        elif 48<=round<64: 
         return (x & z) | (y & ~z) 
        elif 64<=round: 
         return x^(y | ~z) 
    
    def RIPEMD160(data): 
    
    # constants 
        h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE;h3 = 0x10325476; h4 = 0xC3D2E1F0 
    
        k = [0, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E] 
        kk = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9,0] 
        s =  [ 11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8, 
          7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12, 
          11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5, 
          11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12, 
          9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6] 
        ss=  [ 8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6, 
          9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11, 
          9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5, 
          15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8, 
          8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11] 
        r= range(16) + [ 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 
           3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 
           1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 
           4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13] 
        rr = [ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 
          6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 
          15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 
          8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 
          12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11] 
    
        # md4 padding + preprocessing 
        temp = '' 
        for x in data: 
         temp += makebin(int(x,16),4) 
        length = len(temp)%2**64 
        temp +='1' 
        while len(temp)%512!=448: 
         temp+='0' 
        input = temp 
        temp = makebin(length,64) 
        bit_length='' 
        for x in range(len(input)/32): 
         bit_length += little_end(temp[32*x:32*(x+1)],2) 
        input += bit_length[32:]+bit_length[:32] 
        t = len(input)/512 
        # the rounds 
        for i in range(t): 
    
          # i called the parallel round variables 2x the other round variable: a -> aa 
         a = aa = h0; b = bb = h1; c = cc = h2; d = dd = h3; e = ee = h4 
         X = input[512*i:512*(i+1)] 
         X = [int(little_end(X[32*x:32*(x+1)],2),2) for x in range(16)] 
         for j in range(80): 
          T = (ROL((a+ F(b, c, d, j) + X[r[j]] + k[j/16])%2**32,s[j])+e)%2**32 
          c = ROL(c, 10)%2**32 
          a = e; e = d; d = c; c = b; b = T 
          T = (ROL((aa+ F(bb,cc,dd,79-j) + X[rr[j]] + kk[j/16])%2**32,ss[j])+ee)%2**32 
          cc = ROL(cc,10)%2**32 
          aa = ee; ee = dd; dd = cc; cc = bb; bb = T 
         T = (h1+c+dd)%2**32 
         h1 = (h2+d+ee)%2**32 
         h2 = (h3+e+aa)%2**32 
         h3 = (h4+a+bb)%2**32 
         h4 = (h0+b+cc)%2**32 
         h0 = T 
        return little_end(makehex(h0))+little_end(makehex(h1))+little_end(makehex(h2))+little_end(makehex(h3))+little_end(makehex(h4)) 
    data = RIPEMD160('') 
    print data,data =='9c1185a5c5e9fc54612808977ee8f548b2258d31'