@ -1,5 +1,10 @@
var assert = require ( 'nanoassert' )
var wasm = require ( './blake2b' ) ( )
var b4a = require ( 'b4a' )
var wasm = null
var wasmPromise = typeof WebAssembly !== "undefined" && require ( './blake2b' ) ( ) . then ( mod => {
wasm = mod
} )
var head = 64
var freeList = [ ]
@ -16,7 +21,7 @@ var PERSONALBYTES = module.exports.PERSONALBYTES = 16
function Blake2b ( digestLength , key , salt , personal , noAssert ) {
if ( ! ( this instanceof Blake2b ) ) return new Blake2b ( digestLength , key , salt , personal , noAssert )
if ( ! ( wasm && wasm . exports ) ) throw new Error ( 'WASM not loaded. Wait for Blake2b.ready(cb)' )
if ( ! wasm ) throw new Error ( 'WASM not loaded. Wait for Blake2b.ready(cb)' )
if ( ! digestLength ) digestLength = 32
if ( noAssert !== true ) {
@ -45,34 +50,39 @@ function Blake2b (digestLength, key, salt, personal, noAssert) {
this . digestLength = digestLength
this . finalized = false
this . pointer = freeList . pop ( )
this . _ memory = new Uint8Array ( wasm . memory . buffer )
wasm . memory . fill ( 0 , 0 , 64 )
wasm . memory [ 0 ] = this . digestLength
wasm . memory [ 1 ] = key ? key . length : 0
wasm . memory [ 2 ] = 1 // fanout
wasm . memory [ 3 ] = 1 // depth
this . _ memory . fill ( 0 , 0 , 64 )
this . _ memory [ 0 ] = this . digestLength
this . _ memory [ 1 ] = key ? key . length : 0
this . _ memory [ 2 ] = 1 // fanout
this . _ memory [ 3 ] = 1 // depth
if ( salt ) wasm . memory . set ( salt , 32 )
if ( personal ) wasm . memory . set ( personal , 48 )
if ( salt ) this . _ memory . set ( salt , 32 )
if ( personal ) this . _ memory . set ( personal , 48 )
if ( this . pointer + 216 > wasm . memory . length ) wasm . realloc ( this . pointer + 216 ) // we need 216 bytes for the state
wasm . exports . blake2b_init ( this . pointer , this . digestLength )
if ( this . pointer + 216 > this . _ memory . length ) this . _ realloc ( this . pointer + 216 ) // we need 216 bytes for the state
wasm . blake2b_init ( this . pointer , this . digestLength )
if ( key ) {
this . update ( key )
wasm . memory . fill ( 0 , head , head + key . length ) // whiteout key
wasm . memory [ this . pointer + 200 ] = 128
this . _ memory . fill ( 0 , head , head + key . length ) // whiteout key
this . _ memory [ this . pointer + 200 ] = 128
}
}
Blake2b . prototype . _ realloc = function ( size ) {
wasm . memory . grow ( Math . max ( 0 , Math . ceil ( Math . abs ( size - this . _ memory . length ) / 65536 ) ) )
this . _ memory = new Uint8Array ( wasm . memory . buffer )
}
Blake2b . prototype . update = function ( input ) {
assert ( this . finalized === false , 'Hash instance finalized' )
assert ( input instanceof Uint8Array , 'input must be Uint8Array or Buffer' )
if ( head + input . length > wasm . memory . length ) wasm . realloc ( head + input . length )
wasm . memory . set ( input , head )
wasm . exports . blake2b_update ( this . pointer , head , head + input . length )
if ( head + input . length > this . _ memory . length ) this . _ realloc ( head + input . length )
this . _ memory . set ( input , head )
wasm . blake2b_update ( this . pointer , head , head + input . length )
return this
}
@ -81,19 +91,19 @@ Blake2b.prototype.digest = function (enc) {
this . finalized = true
freeList . push ( this . pointer )
wasm . exports . blake2b_final ( this . pointer )
wasm . blake2b_final ( this . pointer )
if ( ! enc || enc === 'binary' ) {
return wasm . memory . slice ( this . pointer + 128 , this . pointer + 128 + this . digestLength )
return this . _ memory . slice ( this . pointer + 128 , this . pointer + 128 + this . digestLength )
}
if ( enc === 'hex ' ) {
return hexSlice ( wasm . memory , this . pointer + 128 , this . digestLength )
if ( typeof enc === 'string ' ) {
return b4a . toString ( this . _ memory , enc , this . pointer + 128 , this . pointer + 128 + this . digestLength )
}
assert ( enc instanceof Uint8Array && enc . length >= this . digestLength , 'input must be Uint8Array or Buffer' )
for ( var i = 0 ; i < this . digestLength ; i ++ ) {
enc [ i ] = wasm . memory [ this . pointer + 128 + i ]
enc [ i ] = this . _ memory [ this . pointer + 128 + i ]
}
return enc
@ -102,44 +112,23 @@ Blake2b.prototype.digest = function (enc) {
// libsodium compat
Blake2b . prototype . final = Blake2b . prototype . digest
Blake2b . WASM = wasm && wasm . buffer
Blake2b . WASM = wasm
Blake2b . SUPPORTED = typeof WebAssembly !== 'undefined'
Blake2b . ready = function ( cb ) {
if ( ! cb ) cb = noop
if ( ! wasm ) return cb ( new Error ( 'WebAssembly not supported' ) )
// backwards compat, can be removed in a new major
var p = new Promise ( function ( reject , resolve ) {
wasm . onload ( function ( err ) {
if ( err ) resolve ( )
else reject ( )
cb ( err )
} )
} )
return p
if ( ! wasmPromise ) return cb ( new Error ( 'WebAssembly not supported' ) )
return wasmPromise . then ( ( ) => cb ( ) , cb )
}
Blake2b . prototype . ready = Blake2b . ready
Blake2b . prototype . getPartialHash = function ( ) {
return wasm . memory . slice ( this . pointer , this . pointer + 216 ) ;
return this . _ memory . slice ( this . pointer , this . pointer + 216 ) ;
}
Blake2b . prototype . setPartialHash = function ( ph ) {
wasm . memory . set ( ph , this . pointer ) ;
this . _ memory . set ( ph , this . pointer ) ;
}
function noop ( ) { }
function hexSlice ( buf , start , len ) {
var str = ''
for ( var i = 0 ; i < len ; i ++ ) str += toHex ( buf [ start + i ] )
return str
}
function toHex ( n ) {
if ( n < 16 ) return '0' + n . toString ( 16 )
return n . toString ( 16 )
}