Advertisement
fmg75

sha256

May 8th, 2024
999
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.71 KB | Cybersecurity | 0 0
  1. # https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
  2.  
  3.  
  4. def _sigma0(num: int):
  5.     """As defined in the specification."""
  6.     num = (_rotate_right(num, 7) ^
  7.            _rotate_right(num, 18) ^
  8.            (num >> 3))
  9.     return num
  10.  
  11.  
  12. def _sigma1(num: int):
  13.     """As defined in the specification."""
  14.     num = (_rotate_right(num, 17) ^
  15.            _rotate_right(num, 19) ^
  16.            (num >> 10))
  17.     return num
  18.  
  19.  
  20. def _capsigma0(num: int):
  21.     """As defined in the specification."""
  22.     num = (_rotate_right(num, 2) ^
  23.            _rotate_right(num, 13) ^
  24.            _rotate_right(num, 22))
  25.     return num
  26.  
  27.  
  28. def _capsigma1(num: int):
  29.     """As defined in the specification."""
  30.     num = (_rotate_right(num, 6) ^
  31.            _rotate_right(num, 11) ^
  32.            _rotate_right(num, 25))
  33.     return num
  34.  
  35.  
  36. def _ch(x: int, y: int, z: int):
  37.     """As defined in the specification."""
  38.     return (x & y) ^ (~x & z)
  39.  
  40.  
  41. def _maj(x: int, y: int, z: int):
  42.     """As defined in the specification."""
  43.     return (x & y) ^ (x & z) ^ (y & z)
  44.  
  45.  
  46. def _rotate_right(num: int, shift: int, size: int = 32):
  47.     """Rotate an integer right."""
  48.     return (num >> shift) | (num << size - shift)
  49.  
  50. # Función para generar el mensaje binario según la especificación
  51. def generate_binary_message(message: bytearray) -> bytes:
  52.         """Return a SHA-256 hash from the message passed.
  53.    The argument should be a bytes, bytearray, or
  54.    string object."""
  55.        
  56.         if isinstance(message, str):
  57.             message = bytearray(message, 'ascii')
  58.         elif isinstance(message, bytes):
  59.             message = bytearray(message)
  60.         elif not isinstance(message, bytearray):
  61.             raise TypeError
  62.        
  63.         # Longitud original del mensaje en bits
  64.         length = len(message) * 8
  65.         # Agregar el bit "1" al final del mensaje
  66.         message += b'\x80'
  67.         # Calcular la cantidad de ceros necesarios para el relleno
  68.         padding_zeros = (448 - (length + 1) % 512) % 512
  69.         # Agregar los ceros de relleno
  70.         message += b'\x00' * (padding_zeros // 8)
  71.         # Agregar la longitud del mensaje original como una cadena binaria de 64 bits
  72.         message += length.to_bytes(8, 'big')
  73.         return message
  74.  
  75.  
  76.  
  77. # constantes "K" page 11
  78.  
  79. K = [
  80.     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  81.     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  82.     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  83.     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  84.     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  85.     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  86.     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  87.     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  88. ]
  89.  
  90.  
  91. def generate_hash(message: bytes) -> bytearray:
  92.     """Return a SHA-256 hash from the message passed.
  93.    The argument should be a bytes, bytearray, or
  94.    string object."""
  95.  
  96.     # Aplicar el relleno al mensaje
  97.     padded_message = generate_binary_message(message)
  98.  
  99.     # Parsing
  100.     blocks = []  # contains 512-bit chunks of message
  101.     for i in range(0, len(padded_message), 64):  # 64 bytes is 512 bits
  102.         blocks.append(padded_message[i:i + 64])
  103.  
  104.     # SHA-256 Hash Computation
  105.     hash_values = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
  106.                    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]
  107.  
  108.     for message_block in blocks:
  109.         # Prepare message schedule
  110.         message_schedule = []
  111.         for t in range(0, 64):
  112.             if t <= 15:
  113.                 # adds the t'th 32 bit word of the block,
  114.                 # starting from leftmost word
  115.                 # 4 bytes at a time
  116.                 message_schedule.append(bytes(message_block[t * 4:(t * 4) + 4]))
  117.             else:
  118.                 term1 = _sigma1(int.from_bytes(message_schedule[t - 2], 'big'))
  119.                 term2 = int.from_bytes(message_schedule[t - 7], 'big')
  120.                 term3 = _sigma0(int.from_bytes(message_schedule[t - 15], 'big'))
  121.                 term4 = int.from_bytes(message_schedule[t - 16], 'big')
  122.  
  123.                 # append a 4-byte byte object
  124.                 schedule = ((term1 + term2 + term3 + term4) % 2**32).to_bytes(4, 'big')
  125.                 message_schedule.append(schedule)
  126.  
  127.         assert len(message_schedule) == 64
  128.  
  129.         # Initialize working variables
  130.         a, b, c, d, e, f, g, h = hash_values
  131.  
  132.         # Iterate for t=0 to 63
  133.         for t in range(64):
  134.             t1 = ((h + _capsigma1(e) + _ch(e, f, g) + K[t] +
  135.                    int.from_bytes(message_schedule[t], 'big')) % 2**32)
  136.  
  137.             t2 = (_capsigma0(a) + _maj(a, b, c)) % 2**32
  138.  
  139.             h, g, f, e, d, c, b, a = g, f, e, (d + t1) % 2**32, c, b, a, (t1 + t2) % 2**32
  140.  
  141.         # Compute intermediate hash value
  142.         hash_values = [(x + y) % 2**32 for x, y in zip(hash_values, [a, b, c, d, e, f, g, h])]
  143.  
  144.     # concatenation by fmg
  145.     result_bytes = b"".join(h.to_bytes(4, 'big') for h in hash_values)
  146.     return result_bytes
  147.  
  148.  
  149. import sys
  150.  
  151. if __name__ == "__main__":
  152.     # Verificar si se proporcionó un mensaje como argumento
  153.     if len(sys.argv) != 2:
  154.         print("Uso: python3 sha256.py mensaje")
  155.         sys.exit(1)
  156.  
  157.     # Obtener el mensaje del primer argumento (ignorando el nombre del script)
  158.     mensaje = sys.argv[1]
  159.  
  160.     # Calcular y mostrar el hash del mensaje
  161.     print(generate_hash(mensaje.encode()).hex())
Tags: #hash #SHA256
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement