From 7aff5874180a00bc9b01204ca71595f6e68ee721 Mon Sep 17 00:00:00 2001 From: Divyansh Gupta Date: Sat, 27 Apr 2024 14:57:32 +0530 Subject: [PATCH] feat(ripemd160): implement ripemd160 hashing algo As on using pycryptodome -> autograder test is giving error that no module found 'Crypto' --- Block.py | 4 +- Helper.py | 15 ++- Output.txt | 1 - RIPEMD160.py | 137 ++++++++++++++++++++++++++ __pycache__/Block.cpython-311.pyc | Bin 7022 -> 6848 bytes __pycache__/Helper.cpython-311.pyc | Bin 6904 -> 6798 bytes __pycache__/RIPEMD160.cpython-311.pyc | Bin 0 -> 5896 bytes main.py | 1 - run.sh | 1 - 9 files changed, 146 insertions(+), 13 deletions(-) create mode 100644 RIPEMD160.py create mode 100644 __pycache__/RIPEMD160.cpython-311.pyc diff --git a/Block.py b/Block.py index a4cbf118..e272092f 100644 --- a/Block.py +++ b/Block.py @@ -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 @@ -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) diff --git a/Helper.py b/Helper.py index 6d253171..61fa9c13 100755 --- a/Helper.py +++ b/Helper.py @@ -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 @@ -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() \ No newline at end of file +# print h.hexdigest() +# print(HASH160(a.to_bytes(4,"big"))) \ No newline at end of file diff --git a/Output.txt b/Output.txt index deccdd45..a0a398bf 100644 --- a/Output.txt +++ b/Output.txt @@ -1,5 +1,4 @@ 0060e92f3f18ee206e1350f1cabe4ff319851d4c3c64b8d2d90e03000000000000000000d40eb0df1c5945f0059bfb300ab3d2f2064ad229f15aaac08d9f7c6896d0a395b48c2a66ffff001f627f0100 -block hash: 4de570732a1ad7f2277e60e60d1968a9c9bdbc7cd4cecacac6c8e9fc7dc20000 010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff11030cd3bf0c004f4345414e2e58595a002effffffff02e412bf13000000001976a9142c30a6aaac6d96687291475d7d52f4b469f665a688ac0000000000000000266a24aa21a9ed07528e9068d79f4fa737ce2b8cdea09f1b9c3c7a588948ff29e9d29d9a9cb2ef0120000000000000000000000000000000000000000000000000000000000000000000000000 dcd522b3588c7adb0418454539e1a929fff936f211e5a20383fdcbc3ad8751b9 423c61f1ec58b9400a373e1052c26debdd5d55eb0057900c3dcf41f54762486c diff --git a/RIPEMD160.py b/RIPEMD160.py new file mode 100644 index 00000000..ae9770ba --- /dev/null +++ b/RIPEMD160.py @@ -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) + diff --git a/__pycache__/Block.cpython-311.pyc b/__pycache__/Block.cpython-311.pyc index 8a02464a7a545b623d05e3d07464c1fd06e728f4..78a06c7aec6ae0bb4b023f3a531561adb3378d83 100644 GIT binary patch delta 259 zcmaE7cEFT(IWI340}zBB(MfCB$lJ-o$hCPo&v~ZF=lJazIVST7EN0T=n|xTHaQQfFi%i??fFKS8vuAYh~1n1&Npe2~E}_ z5wI+fxW$r|lbC*s-`6oB-p}99*)=}Q(I?ckC~)#4aXrS}lLaMiu!VsX$4-7PF+tLc zkyZQy1Bm>{%)lnt68(V*ER-^NhU5#z+{ukn>+CC;7)3rXU?)F<#lPT?EfNRX1OWLf BM&|$k delta 358 zcmX?L`p%4ZIWI340}wd%>ZA#7p4wRz|%zkcb(O&}1zV0m}l3 zTP$fgiRriaeH|m>{rvr$UE{+XeL`J}f+m}Y>oM+}oGgBWEgYmcZnC4q1W6A@R`CxE wAo3$K1Djw=^am!eP{QO_5-%9@CSR6ZXJ5|5DDr^;JNXeT{so6@kvPyM0NJ5uL;wH) diff --git a/__pycache__/Helper.cpython-311.pyc b/__pycache__/Helper.cpython-311.pyc index c35c61f91818d07b3ae2e43bc2b468da2f2ca789..eb8d29f95783af759a8e2c34a9363d1c93830954 100644 GIT binary patch delta 1077 zcmZ8fT}TvB6rQ^~JG<^Wth%l?>e_0$wHm7?{(xeN5%zBw7%R07JEJbm?#h`pddr6% zilmhL7E}*CL=Z^XLq$PCAQ^#=GT~bg`w#>bgpqa5tVwlu=ey^ed+xd4`R@JRaic@N zFUwv5$N2006RQid!sZwDhC>d+nHJ+B6Es0%hAZyE*=a~=XWYqzh4V-1ORfmnSHdAR!)YP16de97S5AadkXQa$rLN$y;?h@24 zeQ<6vzrEm|Qq8FY9i0&2pIie><}FgTI*ePO0l{PlVY>v>Q?Q;tlbSJW!>8~qX_@)> zD|Z!(@%QdVj55z-*2JH98fxs?<*7_Ak;^8GR4!-e2|c5w)C{!quO3Rq5=-qxV+_rk z-X>PTpL;vY?0sH6lgw&*A~TbQe(vyDcJ|vknHV?-x(K=v&g3s69?la_=;UvTL(x7m z4g(%42)%2apL)W1Z}o?II_xS4QHLdhu4)jo9caYKVkwgj z4;S>Xe3X#5r~-Bg!~Cj$4rwmR%2KSPg$*3V%#=1(ElaWpuL)EKZ8_z% z4i`}WX%%#&I>wI&_F&)BffeezJJ==>Iq2fqV69w%rsV=PGpS?dtzbs=EofgVbp zWQ_))94DwF@DorJL_Ve{leJ_<2<)d#R}Jk1{RBe8v(m=zWkzmu}vS@C_vvSQmD${rg|%#Z_w|C)@Q|*nwg}bj>pQ*)@Ly7xnw> delta 1191 zcmZWoU1%It6rP*CJDc6)t5Z^QZOlPQwEg0N!|*jPzp-VnO!Bt3-jG`?>#@? z{mz}QYfozC4b#kMG#*_W{rFnjw8U!rs9hF*Vm{$&ZjUb;$@!$v+{BmKyxw+a3~@%Q z_U&@W?9aca632SUilpm=PQa$!9gyaI!}o%)?)ZK^yadDRLOvDQ_#n091WT{i#$g0A z`lK*$qhz7d-yf<_7#t!91ZRuWfX$mW-q(-m2AK;2H}XXsN^OWV{*f9Kqxd9sgpyQx zZ;F?2t9N8LE>iTGVLfcseJ>1sRaZ^dbDA)Qx%81edDh=apA!_kmU&qeaXT}fkApL+ zxzKV|y}8nW2|Qp#dqS|V@8%*ifgXk$!#KfvyO#;4c9}XHC-_OLCZm+{RYNtyDD#oG z_%Dl-?D7^tBo=}s&9QDB)iSR7uk;j-n%@g!{kFL(#3Y{1?tk+Q4(06Co=AdnTo{cP zaG0h@cmb2LJJLl4JJc^aKw7{o{+PW&SG{do>!efar`B>Uq3+yB;lXALHjhBd%6^vUB$Y^=5QeYL);V#@8uW72%abm^~c(p z4FwmdBg+nuE^rpT!eP4OSB2mBj&uEEIun5!Ug@vQ7s-s0;4~K%oF%&|Bb{H53Zi|T z1a)6sR6a1DNbhU~k`^p!N72G_1-t$Z%F?eyaHF(iO_F=u%xVvuW7{Dh`#jz%4;Et5 zMmGnvS|PajSNVfD*3v&C*YC7%MG0@{FUT*%=K|Y$2`>!vNukl=V6KE~$-c|*BIlIA z`bLSS`ZUs4mg&b)QF=*Ta=k?rgj6!_Vj8?<)o{ngUwf{bsp-ix)3gbnP>wbF0)Bg| z+GAbI4PG_d*{j*rnFrF`mc=`=_|3apvV2#TH)Z*OQ9QJ5RPGp+EyKQR*qhP@e!$fN z*=V^d fzM6mrE%~tp1^m!@MeN{pYjZd$4nEZW4{?HLj)Nuc diff --git a/__pycache__/RIPEMD160.cpython-311.pyc b/__pycache__/RIPEMD160.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e0da10132142c879683bf01bad34ea7f7a8d8af GIT binary patch literal 5896 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 U8pR>%DWk15;xX#EJ4JN=2mW7uBLDyZ literal 0 HcmV?d00001 diff --git a/main.py b/main.py index 2b726cf4..86084ca9 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,6 @@ from Helper import * from Transacttions import * from Block import * -import Crypto all_files = list_all_tx() # print(len(all_files)) diff --git a/run.sh b/run.sh index 1f1f464a..568f921e 100755 --- a/run.sh +++ b/run.sh @@ -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