« Previous | Next »

OpenSSL RIPEMD160

18 Mar 2018

I've just added RIPEMD160 to the EVP interface in OpenSSL-Pharo. This post serves as a HOWTO.

OpenSSL's C interface defines RIPEMD160 thusly:

const EVP_MD *EVP_ripemd160(void);

Create LcLibCrypto>>apiEvpRIPEMD160 for it:

apiEvpRIPEMD160
  ^ self ffiCall: #(EVP_MD* EVP_ripemd160 ())
    module: self library

Next, create LcEvpRIPEMD160 as a subclass of LcEvpMessageDigest:

LcEvpMessageDigest subclass: #LcEvpRIPEMD160
  instanceVariableNames: ''
  classVariableNames: ''
  package: 'OpenSSL-EVP'

LcEvpRIPEMD160>>initialize
  super initialize.
  handle := LcLibCrypto current apiEvpRIPEMD160.
  self errorIfNull: handle

Add class-side accessors:

LcEvpRIPEMD160 class>>blocksize
  ^ 64

LcEvpRIPEMD160 class>>hashsize
  ^ 20

And that's it! Using the test vectors from the RIPEMD160 home page and RFC 2286, the unit tests verify that we can now use RIPEMD160 for hashing and HMAC from within Pharo:

LcEvpRIPEMD160Test>>testDigest1
  | msg result |

  msg := ''.
  result := ByteArray readHexFrom: '9c1185a5c5e9fc54612808977ee8f548b2258d31' readStream.
  self assert: (md hashMessage: msg) equals: result

LcEvpRIPEMD160Test>>testHMAC1
  | msg result expectedResult |

  msg := 'Hi There'.
  key := ByteArray readHexFrom: '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b' readStream.
  expectedResult := ByteArray readHexFrom: '24cb4bd67d20fc1a5d2ed7732dcc39377f0a5668' readStream.
  result := (HMAC on: LcEvpRIPEMD160)
    key: key;
    digestMessage: msg asByteArray.
  self assert: result equals: expectedResult
Tags: cryptography, OpenSSL, security