Browse Source

pass @emilbayes' test vectors

master
Mathias Buus 7 years ago
parent
commit
58f7576422
  1. 6
      .travis.yml
  2. BIN
      blake2b.wasm
  3. 44
      blake2b.wat
  4. 37
      index.js
  5. 7
      package.json
  6. 65
      test.js

6
.travis.yml

@ -0,0 +1,6 @@
sudo: false
language: node_js
node_js:
- "8"

BIN
blake2b.wasm

Binary file not shown.

44
blake2b.wat

@ -5,33 +5,35 @@
(func (export "blake2b_init") (param $ptr i32) (param $outlen i32)
;; setup param block (expect memory to be cleared)
;; 1 byte outlen.
(i32.store8 (i32.const 0) (get_local $outlen))
;; 1 byte keylen.
(i32.store8 (i32.const 1) (i32.const 0))
;; 1 byte fanout.
(i32.store8 (i32.const 2) (i32.const 1))
;; 1 byte depth.
(i32.store8 (i32.const 3) (i32.const 1))
;; init the hash
;; b array: 0-128
(i64.store (get_local $ptr) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 8)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 16)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 24)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 32)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 40)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 48)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 56)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 64)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 72)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 80)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 88)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 96)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 104)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 112)) (i64.const 0))
(i64.store (i32.add (get_local $ptr) (i32.const 120)) (i64.const 0))
;; h array: 128-192, (8 * i64)
;; TODO: support xor against param block and stuff, for now just xor against length
(i64.store (i32.add (get_local $ptr) (i32.const 128)) (i64.xor (i64.const 0x6a09e667f3bcc908) (i64.load (i32.const 0))))
(i64.store (i32.add (get_local $ptr) (i32.const 136)) (i64.const 0xbb67ae8584caa73b))
(i64.store (i32.add (get_local $ptr) (i32.const 144)) (i64.const 0x3c6ef372fe94f82b))
(i64.store (i32.add (get_local $ptr) (i32.const 152)) (i64.const 0xa54ff53a5f1d36f1))
(i64.store (i32.add (get_local $ptr) (i32.const 160)) (i64.const 0x510e527fade682d1))
(i64.store (i32.add (get_local $ptr) (i32.const 168)) (i64.const 0x9b05688c2b3e6c1f))
(i64.store (i32.add (get_local $ptr) (i32.const 176)) (i64.const 0x1f83d9abfb41bd6b))
(i64.store (i32.add (get_local $ptr) (i32.const 184)) (i64.const 0x5be0cd19137e2179))
(i64.store (i32.add (get_local $ptr) (i32.const 136)) (i64.xor (i64.const 0xbb67ae8584caa73b) (i64.load (i32.const 8))))
(i64.store (i32.add (get_local $ptr) (i32.const 144)) (i64.xor (i64.const 0x3c6ef372fe94f82b) (i64.load (i32.const 16))))
(i64.store (i32.add (get_local $ptr) (i32.const 152)) (i64.xor (i64.const 0xa54ff53a5f1d36f1) (i64.load (i32.const 24))))
(i64.store (i32.add (get_local $ptr) (i32.const 160)) (i64.xor (i64.const 0x510e527fade682d1) (i64.load (i32.const 32))))
(i64.store (i32.add (get_local $ptr) (i32.const 168)) (i64.xor (i64.const 0x9b05688c2b3e6c1f) (i64.load (i32.const 40))))
(i64.store (i32.add (get_local $ptr) (i32.const 176)) (i64.xor (i64.const 0x1f83d9abfb41bd6b) (i64.load (i32.const 48))))
(i64.store (i32.add (get_local $ptr) (i32.const 184)) (i64.xor (i64.const 0x5be0cd19137e2179) (i64.load (i32.const 56))))
;; t int.64: 192-200
(i64.store (i32.add (get_local $ptr) (i32.const 192)) (i64.const 0))

37
index.js

@ -9,8 +9,8 @@ var freeList = []
module.exports = Blake2b
function Blake2b () {
if (!(this instanceof Blake2b)) return new Blake2b()
function Blake2b (digestLength, key, salt, personal) {
if (!(this instanceof Blake2b)) return new Blake2b(digestLength, key, salt, personal)
if (!mod) throw new Error('WASM not loaded. Wait for Blake2b.ready(cb)')
if (!freeList.length) {
@ -18,9 +18,26 @@ function Blake2b () {
head += 216
}
this.digestLength = digestLength || 32
this.finalized = false
this.pointer = freeList.pop()
mod.blake2b_init(this.pointer, 32)
memory.fill(0, 0, 64)
memory[0] = this.digestLength
memory[1] = key ? key.length : 0
memory[2] = 1 // fanout
memory[3] = 1 // depth
if (salt) memory.set(salt, 32)
if (personal) memory.set(personal, 48)
mod.blake2b_init(this.pointer, this.digestLength)
if (key) {
this.update(key)
memory.fill(0, head, head + key.length) // whiteout key
memory[this.pointer + 200] = 128
}
}
Blake2b.prototype.ready = Blake2b.ready
@ -40,10 +57,18 @@ Blake2b.prototype.digest = function (enc) {
freeList.push(this.pointer)
mod.blake2b_final(this.pointer)
if (!enc || enc === 'binary') return memory.slice(this.pointer + 128, this.pointer + 128 + 32)
if (enc === 'hex') return hexSlice(memory, this.pointer + 128, 32)
if (!enc || enc === 'binary') {
return memory.slice(this.pointer + 128, this.pointer + 128 + this.digestLength)
}
if (enc === 'hex') {
return hexSlice(memory, this.pointer + 128, this.digestLength)
}
for (var i = 0; i < this.digestLength; i++) {
enc[i] = memory[this.pointer + 128 + i]
}
for (var i = 0; i < 32; i++) enc[i] = memory[this.pointer + 128 + i]
return enc
}

7
package.json

@ -7,7 +7,9 @@
"brfs": "^1.4.3"
},
"devDependencies": {
"browserify": "^14.4.0"
"blake2b": "^1.2.0",
"browserify": "^14.4.0",
"tape": "^4.6.3"
},
"browserify": {
"transform": [
@ -16,7 +18,8 @@
},
"scripts": {
"compile": "wast2wasm blake2b.wat -o blake2b.wasm",
"demo": "browserify example.js > bundle.js"
"demo": "browserify example.js > bundle.js",
"test": "tape tape.js"
},
"repository": {
"type": "git",

65
test.js

@ -0,0 +1,65 @@
var tape = require('tape')
var blake2b = require('./')
var vectors = require('blake2b/test-vectors.json')
blake2b.ready(function () {
tape('hello world', function (t) {
var hash = blake2b()
.update(Buffer.from('hello'))
.update(Buffer.from(' '))
.update(Buffer.from('world'))
.digest('hex')
t.same(hash, '256c83b297114d201b30179f3f0ef0cace9783622da5974326b436178aeef610')
t.end()
})
tape('hello world', function (t) {
var hash = blake2b(64)
.update(Buffer.from('hello'))
.update(Buffer.from(' '))
.update(Buffer.from('world'))
.digest('hex')
t.same(hash, '021ced8799296ceca557832ab941a50b4a11f83478cf141f51f933f653ab9fbcc05a037cddbed06e309bf334942c4e58cdf1a46e237911ccd7fcf9787cbc7fd0')
t.end()
})
tape('both at the same time', function (t) {
var a = blake2b()
var b = blake2b(64)
var hash = a
.update(Buffer.from('hello'))
.update(Buffer.from(' '))
.update(Buffer.from('world'))
.digest('hex')
t.same(hash, '256c83b297114d201b30179f3f0ef0cace9783622da5974326b436178aeef610')
var hash = b
.update(Buffer.from('hello'))
.update(Buffer.from(' '))
.update(Buffer.from('world'))
.digest('hex')
t.same(hash, '021ced8799296ceca557832ab941a50b4a11f83478cf141f51f933f653ab9fbcc05a037cddbed06e309bf334942c4e58cdf1a46e237911ccd7fcf9787cbc7fd0')
t.end()
})
vectors.forEach(function (vector, i) {
tape('test-vectors.json #' + i, function (t) {
var key = vector.key && Buffer.from(vector.key, 'hex')
var salt = vector.salt && Buffer.from(vector.salt, 'hex')
var personal = vector.personal && Buffer.from(vector.personal, 'hex')
var hash = blake2b(vector.outlen, key, salt, personal)
.update(Buffer.from(vector.input, 'hex'))
.digest('hex')
t.same(hash, vector.out)
t.end()
})
})
})
Loading…
Cancel
Save