RIPEMD-160
From Rosetta Code
RIPEMD-160
You are encouraged to solve this task according to the task description, using any language you may know.
You are encouraged to solve this task according to the task description, using any language you may know.
RIPEMD-160 is another hash function; it computes a 160-bit message digest.
There is a RIPEMD-160 home page, with test vectors and pseudocode for RIPEMD-160. For padding the message, RIPEMD-160 acts like MD4 (RFC 1320).
Find the RIPEMD-160 message digest of a string of octets. Use the ASCII encoded string “Rosetta Code”. You may either call an RIPEMD-160 library, or implement RIPEMD-160 in your language.
Contents |
[edit] D
import std.stdio, std.digest.ripemd;
void main() {
auto txt = "Rosetta Code";
writeln("%-(%02x%)", txt.ripemd160Of());
}
b3be159860842cebaa7174c8fff0aa9e50a5199f
[edit] Go
package main
import (
"code.google.com/p/go.crypto/ripemd160"
"fmt"
)
func main() {
h := ripemd160.New()
h.Write([]byte("Rosetta Code"))
fmt.Printf("%x\n", h.Sum(nil))
}
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
[edit] Java
import org.bouncycastle.crypto.digests.RIPEMD160Digest;
import org.bouncycastle.util.encoders.Hex;
public class RosettaRIPEMD160
{
public static void main (String[] argv) throws Exception
{
byte[] r = "Rosetta Code".getBytes("US-ASCII");
RIPEMD160Digest d = new RIPEMD160Digest();
d.update (r, 0, r.length);
byte[] o = new byte[d.getDigestSize()];
d.doFinal (o, 0);
Hex.encode (o, System.out);
System.out.println();
}
}
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
[edit] Objeck
class Hash {
function : Main(args : String[]) ~ Nil {
in := "Rosetta Code"->ToByteArray();
hash := Encryption.Hash->RIPEMD160(in);
hash->ToHexString()->PrintLine();
}
}
Output:
B3BE159860842CEBAA7174C8FFF0AA9E50A5199F
[edit] Perl 6
=begin CREDITS
Crypto-JS v2.0.0
http:#code.google.com/p/crypto-js/
Copyright (c) 2009, Jeff Mott. All rights reserved.
=end CREDITS
sub rotl($n, $b) { $n +< $b +| $n +> (32 - $b) }
sub prefix:<m^> { +^$^x % 2**32 }
sub infix:<m+> { ($^x + $^y) % 2**32 }
constant r1 = <
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
>;
constant r2 = <
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
>;
constant s1 = <
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
>;
constant s2 = <
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
>;
constant F =
* +^ * +^ *,
{ ($^x +& $^y) +| (m^$^x +& $^z) },
(* +| m^*) +^ *,
{ ($^x +& $^z) +| ($^y +& m^$^z) },
* +^ (* +| m^*),
;
constant K1 = <0x00000000 0x5a827999 0x6ed9eba1 0x8f1bbcdc 0xa953fd4e> »xx» 16;
constant K2 = <0x50a28be6 0x5c4dd124 0x6d703ef3 0x7a6d76e9 0x00000000> »xx» 16;
our proto rmd160($) returns Buf {*}
multi rmd160(Str $s) { rmd160 $s.encode: 'ascii' }
multi rmd160(Buf $data) {
my @b = $data.list, 0x80;
push @b, 0 until (8*@b-448) %% 512;
my $len = 8 * $data.elems;
push @b, gather for ^8 { take $len % 256; $len div= 256 }
my @word = gather for @b -> $a, $b, $c, $d {
take reduce * *256 + *, $d, $c, $b, $a;
}
my @h = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0;
loop (my $i = 0; $i < @word; $i += 16) {
my @X = my @Y = @h;
for ^80 -> $j {
my $T = rotl(
@X[0] m+ F[$j div 16](|@X[1..3]) m+ (@word[$i+r1[$j]] // 0) m+ K1[$j],
s1[$j]
) m+ @X[4];
@X = @X[4], $T, @X[1], rotl(@X[2], 10) % 2**32, @X[3];
$T = rotl(
@Y[0] m+ F[(79-$j) div 16](|@Y[1..3]) m+ (@word[$i+r2[$j]] // 0) m+ K2[$j],
s2[$j]
) m+ @Y[4];
@Y = @Y[4], $T, @Y[1], rotl(@Y[2], 10) % 2**32, @Y[3];
}
@h = @h[1..4,^1] Z[m+] @X[2..4,^2] Z[m+] @Y[3..4,^3];
}
return Buf.new: gather for @h -> $word is rw {
for ^4 { take $word % 256; $word div= 256 }
}
}
say rmd160 "Rosetta Code";
Output:
Buf:0x<b3 be 15 98 60 84 2c eb aa 71 74 c8 ff f0 aa 9e 50 a5 19 9f>
[edit] Python
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import hashlib
>>> h = hashlib.new('ripemd160')
>>> h.update(b"Rosetta Code")
>>> h.hexdigest()
'b3be159860842cebaa7174c8fff0aa9e50a5199f'
>>>
[edit] Racket
#lang racket
(require (planet soegaard/digest:1:2/digest))
(ripemd160 #"Rosetta Code")
Output:
"b3be159860842cebaa7174c8fff0aa9e50a5199f"
[edit] Ruby
Use 'digest' from Ruby's standard library.
require 'digest'
puts Digest::RMD160.hexdigest('Rosetta Code')
Use 'openssl' from Ruby's standard library.
require 'openssl'
puts OpenSSL::Digest::RIPEMD160.hexdigest('Rosetta Code')
Implement RIPEMD-160 in Ruby.
require 'stringio'
module RMD160
# functions and constants
MASK = (1 << 32) - 1
F = [
proc {|x, y, z| x ^ y ^ z},
proc {|x, y, z| (x & y) | (x.^(MASK) & z)},
proc {|x, y, z| (x | y.^(MASK)) ^ z},
proc {|x, y, z| (x & z) | (y & z.^(MASK))},
proc {|x, y, z| x ^ (y | z.^(MASK))},
].freeze
K = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]
KK = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]
R = [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]
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]
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]
module_function
def rol(value, shift)
(value << shift).&(MASK) | (value.&(MASK) >> (32 - shift))
end
# Calculates RIPEMD-160 message digest of _string_. Returns binary
# digest. For hexadecimal digest, use
# +*RMD160.rmd160(string).unpack('H*')+.
def rmd160(string)
# initial hash
h0 = 0x67452301
h1 = 0xefcdab89
h2 = 0x98badcfe
h3 = 0x10325476
h4 = 0xc3d2e1f0
io = StringIO.new(string)
block = ""
term = false # appended "\x80" in second-last block?
last = false # last block?
until last
# Read next block of 16 words (64 bytes, 512 bits).
io.read(64, block) or (
# Work around a bug in Rubinius 1.2.4. At eof,
# MRI and JRuby already replace block with "".
block.replace("")
)
# Unpack block into 32-bit words "V".
case len = block.length
when 64
# Unpack 16 words.
x = block.unpack("V16")
when 56..63
# Second-last block: append padding, unpack 16 words.
block.concat("\x80"); term = true
block.concat("\0" * (63 - len))
x = block.unpack("V16")
when 0..55
# Last block: append padding, unpack 14 words.
block.concat(term ? "\0" : "\x80")
block.concat("\0" * (55 - len))
x = block.unpack("V14")
# Append bit length, 2 words.
bit_len = string.length << 3
x.push(bit_len & MASK, bit_len >> 32)
last = true
else
fail "impossible"
end
# Process this block.
a, b, c, d, e = h0, h1, h2, h3, h4
aa, bb, cc, dd, ee = h0, h1, h2, h3, h4
j = 0
5.times {|ro|
f, ff = F[ro], F[4 - ro]
k, kk = K[ro], KK[ro]
16.times {
a, e, d, c, b = e, d, rol(c, 10), b,
rol(a + f[b, c, d] + x[R[j]] + k, S[j]) + e
aa, ee, dd, cc, bb = ee, dd, rol(cc, 10), bb,
rol(aa + ff[bb, cc, dd] + x[RR[j]] + kk, SS[j]) + ee
j += 1
}
}
h0, h1, h2, h3, h4 =
(h1 + c + dd) & MASK, (h2 + d + ee) & MASK,
(h3 + e + aa) & MASK, (h4 + a + bb) & MASK,
(h0 + b + cc) & MASK
end # until last
[h0, h1, h2, h3, h4].pack("V5")
end
end
if __FILE__ == $0
# Print an example RIPEMD-160 digest.
str = 'Rosetta Code'
printf "%s:\n %s\n", str, *RMD160.rmd160(str).unpack('H*')
end
[edit] Tcl
package require ripemd160
puts [ripemd::ripemd160 -hex "Rosetta Code"]
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f