Skip to content

Commit

Permalink
feat(ripemd160): implement ripemd160 hashing algo
Browse files Browse the repository at this point in the history
As on using pycryptodome -> autograder test is giving error that no module found 'Crypto'
  • Loading branch information
15IITian committed Apr 27, 2024
1 parent 4c9726c commit 9794b9b
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 14 deletions.
4 changes: 3 additions & 1 deletion Block.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ def create_block(cls, tx_files):
# get the data related to tx mined in our block
(tx_count,tx_included,fees_collected,weight_stored)=Block.get_mined_tx_data(tx_files)

# print("fee_included:{}",format(fees_collected))
# print("weight stored: {}".format(weight_stored))
# create an instance of a block
block= Block(version,prev_block_in_bytes,merkle_root_hash,timestamp,bits_in_bytes,nonce,tx_hashes_list)
# get the serliased block header
Expand Down Expand Up @@ -152,7 +154,7 @@ def create_block(cls, tx_files):
print(valid_block.serialize_blockheader())
# print("{} {} {} {} {} {} ".format(valid_block.version,(valid_block.prev_block).hex(),(valid_block.merkle_root).hex(),valid_block.timestamp,(valid_block.bits).hex(),valid_block.nonce))

print("block hash: {}".format(valid_block.hash()))
# print("block hash: {}".format(valid_block.hash()))
# serliased coinbase transaction
print(serliased_coinbase_tx)

Expand Down
15 changes: 6 additions & 9 deletions Helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@


import json,hashlib,os

import Crypto
from Crypto.Hash import RIPEMD160
from RIPEMD160 import ripemd160


## This function will return all the the transactions
Expand Down Expand Up @@ -172,18 +170,17 @@ def merkle_root(hashes):
def HASH160(s):
#sha256 followed by ripemd160
# return hashlib.new('ripemd160', hashlib.sha256(s).digest()).digest()
ripemd160 = RIPEMD160.new()
ripemd160.update(s)
return ripemd160.hexdigest()
return ripemd160(s)


# a= 5
a= 5
# print(HASH160(a.to_bytes(4,"big")))





# print(ripemd160(a.to_bytes(4,"big")).hex())
# h = RIPEMD160.new()
# h.update(b'Hello')
# print h.hexdigest()
# print h.hexdigest()
# print(HASH160(a.to_bytes(4,"big")))
137 changes: 137 additions & 0 deletions RIPEMD160.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Copyright (c) 2021 Pieter Wuille
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test-only pure Python RIPEMD160 implementation."""

# This is required because new verions of openssl do not allow for using
# ripemd160 unless you manually configure openssl accordinly. To solve we
# use a pure python ripemd implementation that was added to Bitcoin Core
# to deal with the same issue.


#import unittest

# Message schedule indexes for the left path.
ML = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
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
]

# Message schedule indexes for the right path.
MR = [
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
]

# Rotation counts for the left path.
RL = [
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
]

# Rotation counts for the right path.
RR = [
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
]

# K constants for the left path.
KL = [0, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]

# K constants for the right path.
KR = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0]


def fi(x, y, z, i):
"""The f1, f2, f3, f4, and f5 functions from the specification."""
if i == 0:
return x ^ y ^ z
elif i == 1:
return (x & y) | (~x & z)
elif i == 2:
return (x | ~y) ^ z
elif i == 3:
return (x & z) | (y & ~z)
elif i == 4:
return x ^ (y | ~z)
else:
assert False


def rol(x, i):
"""Rotate the bottom 32 bits of x left by i bits."""
return ((x << i) | ((x & 0xffffffff) >> (32 - i))) & 0xffffffff


def compress(h0, h1, h2, h3, h4, block):
"""Compress state (h0, h1, h2, h3, h4) with block."""
# Left path variables.
al, bl, cl, dl, el = h0, h1, h2, h3, h4
# Right path variables.
ar, br, cr, dr, er = h0, h1, h2, h3, h4
# Message variables.
x = [int.from_bytes(block[4*i:4*(i+1)], 'little') for i in range(16)]

# Iterate over the 80 rounds of the compression.
for j in range(80):
rnd = j >> 4
# Perform left side of the transformation.
al = rol(al + fi(bl, cl, dl, rnd) + x[ML[j]] + KL[rnd], RL[j]) + el
al, bl, cl, dl, el = el, al, bl, rol(cl, 10), dl
# Perform right side of the transformation.
ar = rol(ar + fi(br, cr, dr, 4 - rnd) + x[MR[j]] + KR[rnd], RR[j]) + er
ar, br, cr, dr, er = er, ar, br, rol(cr, 10), dr

# Compose old state, left transform, and right transform into new state.
return h1 + cl + dr, h2 + dl + er, h3 + el + ar, h4 + al + br, h0 + bl + cr


def ripemd160(data):
"""Compute the RIPEMD-160 hash of data."""
# Initialize state.
state = (0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0)
# Process full 64-byte blocks in the input.
for b in range(len(data) >> 6):
state = compress(*state, data[64*b:64*(b+1)])
# Construct final blocks (with padding and size).
pad = b"\x80" + b"\x00" * ((119 - len(data)) & 63)
fin = data[len(data) & ~63:] + pad + (8 * len(data)).to_bytes(8, 'little')
# Process final blocks.
for b in range(len(fin) >> 6):
state = compress(*state, fin[64*b:64*(b+1)])
# Produce output.
return b"".join((h & 0xffffffff).to_bytes(4, 'little') for h in state)


#class TestFrameworkKey(unittest.TestCase):
# def test_ripemd160(self):
# """RIPEMD-160 test vectors."""
# # See https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
# for msg, hexout in [
# (b"", "9c1185a5c5e9fc54612808977ee8f548b2258d31"),
# (b"a", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"),
# (b"abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"),
# (b"message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36"),
# (b"abcdefghijklmnopqrstuvwxyz",
# "f71c27109c692c1b56bbdceb5b9d2865b3708dbc"),
# (b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
# "12a053384a9c0c88e405a06c27dcf49ada62eb2b"),
# (b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
# "b0e20b6e3116640286ed3a87a5713079b21f5189"),
# (b"1234567890" * 8, "9b752e45573d4b39f4dbd3323cab82bf63326bfb"),
# (b"a" * 1000000, "52783243c1697bdbe16d37f97f68f08325dc1528")
# ]:
# self.assertEqual(ripemd160(msg).hex(), hexout)

Binary file modified __pycache__/Block.cpython-311.pyc
Binary file not shown.
Binary file modified __pycache__/Helper.cpython-311.pyc
Binary file not shown.
Binary file added __pycache__/RIPEMD160.cpython-311.pyc
Binary file not shown.
1 change: 0 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from Helper import *
from Transacttions import *
from Block import *
import Crypto
all_files = list_all_tx()
# print(len(all_files))

Expand Down
1 change: 0 additions & 1 deletion Output.txt → output.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
0060e92f3f18ee206e1350f1cabe4ff319851d4c3c64b8d2d90e03000000000000000000d40eb0df1c5945f0059bfb300ab3d2f2064ad229f15aaac08d9f7c6896d0a395b48c2a66ffff001f627f0100
block hash: 4de570732a1ad7f2277e60e60d1968a9c9bdbc7cd4cecacac6c8e9fc7dc20000
010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff11030cd3bf0c004f4345414e2e58595a002effffffff02e412bf13000000001976a9142c30a6aaac6d96687291475d7d52f4b469f665a688ac0000000000000000266a24aa21a9ed07528e9068d79f4fa737ce2b8cdea09f1b9c3c7a588948ff29e9d29d9a9cb2ef0120000000000000000000000000000000000000000000000000000000000000000000000000
dcd522b3588c7adb0418454539e1a929fff936f211e5a20383fdcbc3ad8751b9
423c61f1ec58b9400a373e1052c26debdd5d55eb0057900c3dcf41f54762486c
Expand Down
3 changes: 1 addition & 2 deletions run.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Update this file to run your own code
#!/bin/bash

pip install pycryptodomex
# Run main.py and redirect output to Output.txt

python main.py > Output.txt
python main.py > output.txt

0 comments on commit 9794b9b

Please sign in to comment.