├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.js ├── package.json └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | .DS_Store 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "0.10" 5 | - "0.11" 6 | - "0.12" 7 | - "4" 8 | - "5" 9 | - "6" 10 | env: 11 | matrix: 12 | - TEST_SUITE=unit 13 | matrix: 14 | include: 15 | - node_js: "4" 16 | env: TEST_SUITE=lint 17 | script: npm run-script $TEST_SUITE 18 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2.0.1 / 2016-06-22 2 | ------------------ 3 | - added LICENSE file. 4 | 5 | 2.0.0 / 2016-04-11 6 | ------------------ 7 | - rewritten, license change BSD-3 to MIT. [#13][#13] 8 | - stream support [#13][#13] 9 | 10 | 1.0.1 / 2015-05-05 11 | ------------------ 12 | - standard formatting 13 | 14 | 1.0.0 / 2015-01-14 15 | ------------------ 16 | - updated dev deps 17 | - added more test fixtures 18 | - updated readme with usage, testing, etc 19 | - moved from https://github.com/cryptocoinjs/ripemd160 to https://github.com/crypto-browserify/ripemd160 20 | 21 | 0.2.1 / 2014-12-31 22 | ------------------ 23 | - made license clear in `package.json` 24 | - deleted `Makefile`, moved targets to `package.json` 25 | - removed `terst` for `assert` 26 | 27 | 0.2.0 / 2014-03-09 28 | ------------------ 29 | * removed bower.json and component.json 30 | * changed 4 spacing to 2 31 | * returns `Buffer` type now, input must be Array, Uint8Array, Buffer, or string 32 | * remove deps: `convert-hex` and `convert-string` 33 | 34 | 0.1.0 / 2013-11-20 35 | ------------------ 36 | * changed package name 37 | * removed AMD support 38 | 39 | 0.0.2 / 2013-11-06 40 | ------------------ 41 | * fixed component.json file 42 | 43 | 0.0.1 / 2013-11-03 44 | ------------------ 45 | * initial release 46 | 47 | 48 | [#13]: https://github.com/crypto-browserify/ripemd160/pull/13 49 | 50 | [#12]: https://github.com/crypto-browserify/ripemd160/pull/12 51 | 52 | [#11]: https://github.com/crypto-browserify/ripemd160/pull/11 53 | 54 | [#10]: https://github.com/crypto-browserify/ripemd160/pull/10 55 | 56 | [#9]: https://github.com/crypto-browserify/ripemd160/pull/9 57 | 58 | [#8]: https://github.com/crypto-browserify/ripemd160/issues/8 59 | 60 | [#7]: https://github.com/crypto-browserify/ripemd160/pull/7 61 | 62 | [#6]: https://github.com/crypto-browserify/ripemd160/pull/6 63 | 64 | [#5]: https://github.com/crypto-browserify/ripemd160/issues/5 65 | 66 | [#4]: https://github.com/crypto-browserify/ripemd160/pull/4 67 | 68 | [#3]: https://github.com/crypto-browserify/ripemd160/pull/3 69 | 70 | [#2]: https://github.com/crypto-browserify/ripemd160/pull/2 71 | 72 | [#1]: https://github.com/crypto-browserify/ripemd160/pull/1 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 crypto-browserify 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ripemd160 2 | 3 | [![NPM Package](https://img.shields.io/npm/v/ripemd160.svg?style=flat-square)](https://www.npmjs.org/package/ripemd160) 4 | [![Build Status](https://img.shields.io/travis/crypto-browserify/ripemd160.svg?branch=master&style=flat-square)](https://travis-ci.org/crypto-browserify/ripemd160) 5 | [![Dependency status](https://img.shields.io/david/crypto-browserify/ripemd160.svg?style=flat-square)](https://david-dm.org/crypto-browserify/ripemd160#info=dependencies) 6 | 7 | [![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) 8 | 9 | Node style `ripemd160` on pure JavaScript. 10 | 11 | ## Example 12 | 13 | ```js 14 | var RIPEMD160 = require('ripemd160') 15 | 16 | console.log(new RIPEMD160().update('42').digest('hex')) 17 | // => 0df020ba32aa9b8b904471ff582ce6b579bf8bc8 18 | 19 | var ripemd160stream = new RIPEMD160() 20 | ripemd160stream.end('42') 21 | console.log(ripemd160stream.read().toString('hex')) 22 | // => 0df020ba32aa9b8b904471ff582ce6b579bf8bc8 23 | ``` 24 | 25 | ## LICENSE 26 | 27 | MIT 28 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | var Buffer = require('buffer').Buffer 3 | var inherits = require('inherits') 4 | var HashBase = require('hash-base') 5 | 6 | var ARRAY16 = new Array(16) 7 | 8 | var zl = [ 9 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10 | 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 11 | 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 12 | 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 13 | 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 14 | ] 15 | 16 | var zr = [ 17 | 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 18 | 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 19 | 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 20 | 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 21 | 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 22 | ] 23 | 24 | var sl = [ 25 | 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 26 | 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 27 | 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 28 | 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 29 | 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 30 | ] 31 | 32 | var sr = [ 33 | 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 34 | 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 35 | 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 36 | 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 37 | 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 38 | ] 39 | 40 | var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e] 41 | var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000] 42 | 43 | function RIPEMD160 () { 44 | HashBase.call(this, 64) 45 | 46 | // state 47 | this._a = 0x67452301 48 | this._b = 0xefcdab89 49 | this._c = 0x98badcfe 50 | this._d = 0x10325476 51 | this._e = 0xc3d2e1f0 52 | } 53 | 54 | inherits(RIPEMD160, HashBase) 55 | 56 | RIPEMD160.prototype._update = function () { 57 | var words = ARRAY16 58 | for (var j = 0; j < 16; ++j) words[j] = this._block.readInt32LE(j * 4) 59 | 60 | var al = this._a | 0 61 | var bl = this._b | 0 62 | var cl = this._c | 0 63 | var dl = this._d | 0 64 | var el = this._e | 0 65 | 66 | var ar = this._a | 0 67 | var br = this._b | 0 68 | var cr = this._c | 0 69 | var dr = this._d | 0 70 | var er = this._e | 0 71 | 72 | // computation 73 | for (var i = 0; i < 80; i += 1) { 74 | var tl 75 | var tr 76 | if (i < 16) { 77 | tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i]) 78 | tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i]) 79 | } else if (i < 32) { 80 | tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i]) 81 | tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i]) 82 | } else if (i < 48) { 83 | tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i]) 84 | tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i]) 85 | } else if (i < 64) { 86 | tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i]) 87 | tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i]) 88 | } else { // if (i<80) { 89 | tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i]) 90 | tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i]) 91 | } 92 | 93 | al = el 94 | el = dl 95 | dl = rotl(cl, 10) 96 | cl = bl 97 | bl = tl 98 | 99 | ar = er 100 | er = dr 101 | dr = rotl(cr, 10) 102 | cr = br 103 | br = tr 104 | } 105 | 106 | // update state 107 | var t = (this._b + cl + dr) | 0 108 | this._b = (this._c + dl + er) | 0 109 | this._c = (this._d + el + ar) | 0 110 | this._d = (this._e + al + br) | 0 111 | this._e = (this._a + bl + cr) | 0 112 | this._a = t 113 | } 114 | 115 | RIPEMD160.prototype._digest = function () { 116 | // create padding and handle blocks 117 | this._block[this._blockOffset++] = 0x80 118 | if (this._blockOffset > 56) { 119 | this._block.fill(0, this._blockOffset, 64) 120 | this._update() 121 | this._blockOffset = 0 122 | } 123 | 124 | this._block.fill(0, this._blockOffset, 56) 125 | this._block.writeUInt32LE(this._length[0], 56) 126 | this._block.writeUInt32LE(this._length[1], 60) 127 | this._update() 128 | 129 | // produce result 130 | var buffer = Buffer.alloc ? Buffer.alloc(20) : new Buffer(20) 131 | buffer.writeInt32LE(this._a, 0) 132 | buffer.writeInt32LE(this._b, 4) 133 | buffer.writeInt32LE(this._c, 8) 134 | buffer.writeInt32LE(this._d, 12) 135 | buffer.writeInt32LE(this._e, 16) 136 | return buffer 137 | } 138 | 139 | function rotl (x, n) { 140 | return (x << n) | (x >>> (32 - n)) 141 | } 142 | 143 | function fn1 (a, b, c, d, e, m, k, s) { 144 | return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0 145 | } 146 | 147 | function fn2 (a, b, c, d, e, m, k, s) { 148 | return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0 149 | } 150 | 151 | function fn3 (a, b, c, d, e, m, k, s) { 152 | return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0 153 | } 154 | 155 | function fn4 (a, b, c, d, e, m, k, s) { 156 | return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0 157 | } 158 | 159 | function fn5 (a, b, c, d, e, m, k, s) { 160 | return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0 161 | } 162 | 163 | module.exports = RIPEMD160 164 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ripemd160", 3 | "version": "2.0.2", 4 | "description": "Compute ripemd160 of bytes or strings.", 5 | "keywords": [ 6 | "string", 7 | "strings", 8 | "ripemd160", 9 | "ripe160", 10 | "bitcoin", 11 | "bytes", 12 | "cryptography" 13 | ], 14 | "license": "MIT", 15 | "files": [ 16 | "index.js" 17 | ], 18 | "main": "./index", 19 | "repository": { 20 | "url": "https://github.com/crypto-browserify/ripemd160", 21 | "type": "git" 22 | }, 23 | "scripts": { 24 | "lint": "standard", 25 | "test": "npm run lint && npm run unit", 26 | "unit": "node test/*.js" 27 | }, 28 | "dependencies": { 29 | "hash-base": "^3.0.0", 30 | "inherits": "^2.0.1" 31 | }, 32 | "devDependencies": { 33 | "hash-test-vectors": "^1.3.2", 34 | "standard": "^6.0.7", 35 | "tape": "^4.5.1" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | var test = require('tape').test 3 | var vectors = require('hash-test-vectors') 4 | 5 | var RIPEMD160 = require('../') 6 | 7 | vectors.forEach(function (vector, i) { 8 | var input = new Buffer(vector.input, 'base64') 9 | 10 | test('vector #' + (i + 1) + ' with .update', function (t) { 11 | t.same(new RIPEMD160().update(input).digest('hex'), vector.ripemd160) 12 | t.end() 13 | }) 14 | 15 | test('vector #' + (i + 1) + ' with streams', function (t) { 16 | var hash = new RIPEMD160() 17 | hash.end(input) 18 | t.same(hash.read().toString('hex'), vector.ripemd160) 19 | t.end() 20 | }) 21 | }) 22 | --------------------------------------------------------------------------------