Skip to content

Commit

Permalink
Merge pull request #36 from crypto-browserify/feature/hash-base
Browse files Browse the repository at this point in the history
use hash-base
  • Loading branch information
dcousens authored Nov 10, 2016
2 parents 632a2f2 + 8eec0fb commit 21e2873
Show file tree
Hide file tree
Showing 24 changed files with 543 additions and 984 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
node_modules

npm-debug.log
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2013-2014 sha.js contributors
Copyright (c) 2013-2016 sha.js contributors

Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and
Expand Down
58 changes: 22 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,39 @@
# sha.js

Streamable SHA hashes in pure javascript.
[![NPM Package](https://img.shields.io/npm/v/sha.js.svg?style=flat-square)](https://www.npmjs.org/package/sha.js)
[![Build Status](https://img.shields.io/travis/crypto-browserify/sha.js.svg?branch=master&style=flat-square)](https://travis-ci.org/crypto-browserify/sha.js)
[![Dependency status](https://img.shields.io/david/crypto-browserify/sha.js.svg?style=flat-square)](https://david-dm.org/crypto-browserify/sha.js#info=dependencies)

[![build status](https://secure.travis-ci.org/crypto-browserify/sha.js.png)](http://travis-ci.org/crypto-browserify/sha.js)
[![NPM](http://img.shields.io/npm/v/sha.js.svg)](https://www.npmjs.org/package/sha.js)
[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)

Node style `SHA` on pure JavaScript.

## Example

``` js
var createHash = require('sha.js')

var sha256 = createHash('sha256')
var sha512 = createHash('sha512')

var h = sha256.update('abc', 'utf8').digest('hex')
console.log(h) //ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

//LEGACY, do not use in new systems:
var sha0 = createHash('sha')
var sha1 = createHash('sha1')
```js
var shajs = require('sha.js')

console.log(shajs('sha256').update('42').digest('hex'))
// => 73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049
console.log(new shajs.SHA256().update('42').digest('hex'))
// => 73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049

var sha256stream = shajs('sha256')
sha256stream.end('42')
console.log(sha256stream.read().toString('hex'))
// => 73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049
```

## supported hashes

sha.js currently implements:


* sha256
* sha512
* sha1 (legacy, no not use in new systems)
* sha (legacy, no not use in new systems)

## Note

Note, this doesn't actually implement a stream, but wrapping this in a stream is trivial.
but is does update incrementally, so you can hash things larger than ram, and also, since it reuses
the typedarrays, it uses a constant amount of memory (except when using base64 or utf8 encoding,
see code comments)


## Acknowledgements

This work is derived from Paul Johnston's ["A JavaScript implementation of the Secure Hash Algorithm"]
(http://pajhome.org.uk/crypt/md5/sha1.html)

`sha.js` currently implements:

- SHA (SHA-0) -- **legacy, do not use in new systems**
- SHA-1 -- **legacy, do not use in new systems**
- SHA-224
- SHA-256
- SHA-384
- SHA-512

## License

Expand Down
43 changes: 0 additions & 43 deletions bin.js

This file was deleted.

69 changes: 0 additions & 69 deletions hash.js

This file was deleted.

26 changes: 0 additions & 26 deletions hexpp.js

This file was deleted.

14 changes: 7 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
var exports = module.exports = function SHA (algorithm) {
algorithm = algorithm.toLowerCase()
algorithm = algorithm.toUpperCase()

var Algorithm = exports[algorithm]
if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)')

return new Algorithm()
}

exports.sha = require('./sha')
exports.sha1 = require('./sha1')
exports.sha224 = require('./sha224')
exports.sha256 = require('./sha256')
exports.sha384 = require('./sha384')
exports.sha512 = require('./sha512')
exports.SHA = require('./lib/sha')
exports.SHA1 = require('./lib/sha1')
exports.SHA224 = require('./lib/sha224')
exports.SHA256 = require('./lib/sha256')
exports.SHA384 = require('./lib/sha384')
exports.SHA512 = require('./lib/sha512')
30 changes: 30 additions & 0 deletions lib/padding.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict'
exports.block64 = function () {
this._block[this._blockOffset++] = 0x80
if (this._blockOffset > 56) {
this._block.fill(0, this._blockOffset, 64)
this._update()
this._blockOffset = 0
}

this._block.fill(0, this._blockOffset, 56)
this._block.writeUInt32BE(this._length[1], 56)
this._block.writeUInt32BE(this._length[0], 60)
this._update()
}

exports.block128 = function () {
this._block[this._blockOffset++] = 0x80
if (this._blockOffset > 112) {
this._block.fill(0, this._blockOffset, 128)
this._update()
this._blockOffset = 0
}

this._block.fill(0, this._blockOffset, 112)
this._block.writeUInt32BE(this._length[3], 112)
this._block.writeUInt32BE(this._length[2], 116)
this._block.writeUInt32BE(this._length[1], 120)
this._block.writeUInt32BE(this._length[0], 124)
this._update()
}
93 changes: 93 additions & 0 deletions lib/sha.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use strict'
var inherits = require('inherits')
var HashBase = require('hash-base')
var padding = require('./padding')

var W = new Array(80)
var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6]

function SHA () {
HashBase.call(this, 64)

this._a = 0x67452301
this._b = 0xefcdab89
this._c = 0x98badcfe
this._d = 0x10325476
this._e = 0xc3d2e1f0
}

inherits(SHA, HashBase)

SHA.prototype._expandMessage = function (W) {
for (var i = 0; i < 16; ++i) W[i] = this._block.readInt32BE(i * 4)
for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]
}

SHA.prototype._update = function () {
this._expandMessage(W)

var a = this._a | 0
var b = this._b | 0
var c = this._c | 0
var d = this._d | 0
var e = this._e | 0

for (var i = 0; i < 80; ++i) {
var t
if (i < 20) {
t = (e + fn0(b, c, d) + rotl5(a) + W[i] + K[0]) | 0
} else if (i < 40) {
t = (e + fn1(b, c, d) + rotl5(a) + W[i] + K[1]) | 0
} else if (i < 60) {
t = (e + fn2(b, c, d) + rotl5(a) + W[i] + K[2]) | 0
} else { // i < 80
t = (e + fn1(b, c, d) + rotl5(a) + W[i] + K[3]) | 0
}

e = d
d = c
c = rotl30(b)
b = a
a = t
}

this._a = (a + this._a) | 0
this._b = (b + this._b) | 0
this._c = (c + this._c) | 0
this._d = (d + this._d) | 0
this._e = (e + this._e) | 0
}

SHA.prototype._digest = function () {
padding.block64.call(this)

var buffer = new Buffer(20)
buffer.writeInt32BE(this._a, 0)
buffer.writeInt32BE(this._b, 4)
buffer.writeInt32BE(this._c, 8)
buffer.writeInt32BE(this._d, 12)
buffer.writeInt32BE(this._e, 16)
return buffer
}

function rotl5 (num) {
return (num << 5) | (num >>> 27)
}

function rotl30 (num) {
return (num << 30) | (num >>> 2)
}

function fn0 (b, c, d) {
return (b & c) | ((~b) & d)
}

function fn1 (b, c, d) {
return b ^ c ^ d
}

function fn2 (b, c, d) {
return (b & c) | (b & d) | (c & d)
}

module.exports = SHA
24 changes: 24 additions & 0 deletions lib/sha1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'
var inherits = require('inherits')
var HashBase = require('hash-base')
var SHA = require('./sha')

function SHA1 () {
SHA.call(this)
}

inherits(SHA1, HashBase)

SHA1.prototype._expandMessage = function (W) {
for (var i = 0; i < 16; ++i) W[i] = this._block.readInt32BE(i * 4)
for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16])
}

SHA1.prototype._update = SHA.prototype._update
SHA1.prototype._digest = SHA.prototype._digest

function rotl1 (num) {
return (num << 1) | (num >>> 31)
}

module.exports = SHA1
Loading

0 comments on commit 21e2873

Please sign in to comment.