jayce0071 / crypto-js

Automatically exported from code.google.com/p/crypto-js
0 stars 0 forks source link

typed arrays support always use entire buffer if a view is passed in #63

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
With a typed array view, the .buffer refers to the entire buffer, whereas the 
view might only be referencing a portion of it.  That is:

  var b = new ArrayBuffer(12);
  var v = new Uint8Array(b, 4, 4); // creates a 4-byte view starting at index 4

at this point:

  v.length == 4
  v.buffer.byteLength == 12  (because it's the original created buffer, not a sub-buffer).

The lib-typedarrays code as written will hash the entire buffer instead of just 
the view.  Additionally, using DataView adds an unnecessary performance cost.  
Instead, something like this would both fix the problem and be faster:

if (arg instanceof ArrayBuffer) {
  dataBuffer = new Uint8Array(arg);
} else if (arg instanceof Int32Array || arg instanceof Uint32Array || ...) {
  dataBuffer = new Uint8Array(arg.buffer, arg.byteOffset, arg.byteLength);
}

...
   words[i >>> 2] |= dataBuffer[i] << (24 - (i % 4) * 8);
...

(I should've just written a patch, but didn't want to deal with svn! :)

A further optimization is possible in some cases by just creating a Uint32Array 
view, assuming that both the offset and length are 4-byte-aligned.  In that 
case, the words member could also possibly just be a Uint32Array (assuming no 
Array features are used on it).

Original issue reported on code.google.com by vladim...@gmail.com on 9 Jan 2013 at 7:13

GoogleCodeExporter commented 9 years ago
My code ignores the byte offset and length, you're absolutely right about that. 
I'll fix that up, quite likely by using what you posted nearly verbatim.

For a while, I had also tried using a Uint32Array. The problem I ran into is 
that the endianness is never guaranteed. It depends on the underlying hardware. 
That's how I ended up using DataView, because I can pass an argument to 
indicate whether the result should be big or little endian. Of course, if I 
read only one byte at a time, then that's a moot point.

Original comment by Jeff.Mott.OR on 10 Jan 2013 at 6:14

GoogleCodeExporter commented 9 years ago
Fixed in r586 and available in the latest release.

Original comment by Jeff.Mott.OR on 15 Jan 2013 at 2:55