Skip to content

Commit 422d152

Browse files
committed
up p2pkh
1 parent 3f8442c commit 422d152

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed

README.md

+68
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,74 @@ the curve where x and y are each 256-bit numbers...
397397
...
398398

399399

400+
401+
Aside - What's Hash160?
402+
403+
It's a hash function to hash and shorten public keys. Public keys
404+
if uncompressed shorten from 65 bytes to 20 bytes
405+
(or if compressed from 33 bytes). Example:
406+
407+
```
408+
pubkey = 02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737
409+
hash160(pubkey) = 93ce48570b55c42c2af816aeaba06cfee1224fae
410+
````
411+
412+
To compute the Hash160 run the public key through the SHA256 and RIPEMD160 hash functions.
413+
Example:
414+
415+
``` ruby
416+
require 'digest' # Hash (Digest) Functions
417+
418+
def hash160( pubkey )
419+
binary = [pubkey].pack( "H*" ) # Convert to binary first before hashing
420+
sha256 = Digest::SHA256.digest( binary )
421+
ripemd160 = Digest::RMD160.digest( sha256 )
422+
ripemd160.unpack( "H*" )[0] # Convert back to hex
423+
end
424+
425+
pubkey = '02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737'
426+
hash160( pubkey ) #=> '93ce48570b55c42c2af816aeaba06cfee1224fae'
427+
```
428+
429+
(Source: [`hash160.rb`](hash160.rb))
430+
431+
432+
Security Trivia I: Why use SHA256 and RIPEMD160?
433+
434+
RIPEMD160 gets used because it results in
435+
a short 160 bit (20 byte) digest BUT is not the strongest hash function on it's own,
436+
thus, SHA256 gets used for more strength. Best of both world.
437+
438+
Security Trivia II: What's RIPEMD160?
439+
440+
RACE¹ Integrity Primitives Evaluation Message Digest 160-bit
441+
442+
¹: Research and development in Advanced Communications technologies in Europe
443+
444+
``` ruby
445+
def ripemd160( message )
446+
Digest::RMD160.hexdigest( message )
447+
end
448+
449+
ripemd160( "The quick brown fox jumps over the lazy dog" )
450+
#=> "37f332f68db77bd9d7edd4969571ad671cf9dd3b"
451+
452+
ripemd160( "The quick brown fox jumps over the lazy cog" )
453+
#=> "132072df690933835eb8b6ad0b77e7b6f14acad7"
454+
455+
# The hash of a zero-length string is:
456+
ripemd160( "" )
457+
#=> "9c1185a5c5e9fc54612808977ee8f548b2258d31"
458+
```
459+
460+
(Source: [RIPEMD @ Wikipedia](https://en.wikipedia.org/wiki/RIPEMD))
461+
462+
463+
464+
...
465+
466+
467+
400468
The "official" bitcoin script notation reads:
401469

402470
```

hash160.rb

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# compute Hash160(pubkey)
2+
3+
require 'pp'
4+
require 'digest' # Hash (Digest) Functions
5+
6+
def hash160( pubkey )
7+
binary = [pubkey].pack( "H*" ) # Convert to binary first before hashing
8+
sha256 = Digest::SHA256.digest( binary )
9+
ripemd160 = Digest::RMD160.digest( sha256 )
10+
ripemd160.unpack( "H*" )[0] # Convert back to hex
11+
end
12+
13+
pubkey = "02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737"
14+
pp hash160( pubkey ) #=> "93ce48570b55c42c2af816aeaba06cfee1224fae"

ripemd160.rb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## RIPEMD (RIPE Message Digest)
2+
##
3+
## see https://en.wikipedia.org/wiki/RIPEMD
4+
5+
require 'pp'
6+
require 'digest' # Hash (Digest) Functions
7+
8+
9+
def ripemd160( message )
10+
Digest::RMD160.hexdigest( message )
11+
end
12+
13+
pp ripemd160( "The quick brown fox jumps over the lazy dog" )
14+
#=> "37f332f68db77bd9d7edd4969571ad671cf9dd3b"
15+
16+
pp ripemd160( "The quick brown fox jumps over the lazy cog" )
17+
#=> "132072df690933835eb8b6ad0b77e7b6f14acad7"
18+
19+
# The hash of a zero-length string is:
20+
pp ripemd160( "" )
21+
#=> "9c1185a5c5e9fc54612808977ee8f548b2258d31"

0 commit comments

Comments
 (0)