Last active
April 14, 2025 13:21
-
-
Save artjomb/7ef1ee574a411ba0dd1933c1ef4690d1 to your computer and use it in GitHub Desktop.
Convert a byte array to a word array and back in CryptoJS-compatible fashion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function byteArrayToWordArray(ba) { | |
var wa = [], | |
i; | |
for (i = 0; i < ba.length; i++) { | |
wa[(i / 4) | 0] |= ba[i] << (24 - 8 * i); | |
} | |
return CryptoJS.lib.WordArray.create(wa, ba.length); | |
} | |
function wordToByteArray(word, length) { | |
var ba = [], | |
i, | |
xFF = 0xFF; | |
if (length > 0) | |
ba.push(word >>> 24); | |
if (length > 1) | |
ba.push((word >>> 16) & xFF); | |
if (length > 2) | |
ba.push((word >>> 8) & xFF); | |
if (length > 3) | |
ba.push(word & xFF); | |
return ba; | |
} | |
function wordArrayToByteArray(wordArray, length) { | |
if (wordArray.hasOwnProperty("sigBytes") && wordArray.hasOwnProperty("words")) { | |
length = wordArray.sigBytes; | |
wordArray = wordArray.words; | |
} | |
var result = [], | |
bytes, | |
i = 0; | |
while (length > 0) { | |
bytes = wordToByteArray(wordArray[i], Math.min(4, length)); | |
length -= bytes.length; | |
result.push(bytes); | |
i++; | |
} | |
return [].concat.apply([], result); | |
} |
Combined and rewrote the words-to-bytes-function to be a bit faster. Just in case someone needs it.
function cryptArrToByteArr(wordArray) {
var bytes = new Uint8Array(wordArray.sigBytes);
var fullwords = wordArray.sigBytes >>> 2; //equal div 4
var lastbytes = wordArray.sigBytes % 4;
var word, offs;
for (var i = 0; i < fullwords; i++) {
word = wordArray.words[i];
offs = i<<2;
bytes[offs] = word >>> 24;
bytes[offs+1] = (word >>> 16) & 0xFF;
bytes[offs+2] = (word >>> 8) & 0xFF;
bytes[offs+3] = word & 0xFF;
}
if (lastbytes > 0) {
word = wordArray.words[fullwords];
offs = fullwords<<2;
bytes[offs] = word >>> 24;
if (length > 1) bytes[offs+1] = (word >>> 16) & 0xFF;
if (length > 2) bytes[offs+2] = (word >>> 8) & 0xFF;
}
return bytes;
}
The above code has errors too, although I definitely prefer its intended efficiency:
if (lastbytes > 0) {
word = wordArray.words[fullwords];
offs = fullwords<<2;
bytes[offs] = word >>> 24;
if (lastbytes > 1) bytes[offs+1] = (word >>> 16) & 0xFF;
if (lastbytes > 2) bytes[offs+2] = (word >>> 8) & 0xFF;
}
In case anyone comes here looking for a solution, here is what I ended up using:
/** Returns a crypto-JS compatible Word Array, based on the byte array provided */
static toWordArray(bytes) {
var words = [];
for (var j = 0; j < bytes.length; j++) {
words[(j>>>2)] |= bytes[j] << (24 - (8 * (j%4)));
}
return CryptoJS.lib.WordArray.create(words, bytes.length);
}
/** Returns a byte array, based on the crypto-JS compatible word array provided */
static fromWordArray(wordArray) {
var bytes = new Uint8Array(wordArray.sigBytes);
for (var j=0; j<wordArray.sigBytes; j++) {
bytes[j] = (wordArray.words[(j>>>2)] >>> (24 - (8 * (j%4)))) & 0xFF
}
return bytes;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thank a lot <3