# JavaScrypt Development Log

### 2003 September 24

Modified `formatPlaintext` in `aes.js` to fill plaintext buffers that aren't an even number of 32 byte AES blocks with pseudorandom bytes from `getRandomBytes` rather than zeroes.

Extracted the JavaScript code embedded in `index.html` into a new `jscrypt.js` module. This will make it easier to programmatically assemble the "lean" version from the main file.

Updated the `Makefile` to explicitly list the JavaScript modules included in the archive as opposed to including them with a wildcard specification. This permits keeping the compressed JavaScript files for the lean version in the same directory without having them included in the archive.

Added mark-up to `index.html` to denote those parts to be dropped when assembling the lean version.

### 2003 September 25

For some reason, on Mozilla 1.3/Linux, the "Key" edit line displayed in a larger Courier font in the lean version (but not the full version, which has no changes whatsoever which should affect the style of this box). I removed "Courier" from the `font-family` and left it as "monospace", which appears to work everywhere. No other browser had any problem with Courier as an alternative to monospace.

### 2003 September 27

Added the three ECB test cases from the NIST standard test set to the `test.html` testbed. Each button plugs the key, plaintext, and ciphertext for the test in the corresponding boxes; you may then encrypt and decrypt to verify nothing changes. Key size and block size are now sensed automatically based on the length of the hexadecimal value in the field.

### 2003 September 28

Integrated the `pass_phrase.html` and `stego.html` pages along with their supporting `wordtab.js` and `stegodict.js` files. Added these files to the appropriate places in the `Makefile`.

Added the ability to suppress the generation of headers and trailers in Base64 armour by setting `base64addsent` to `false` before calling `armour_base64` in `armour.js`. This permits Stego to optionally suppress headers when it's being used to steganify a Base64 file belonging to another application.

### 2003 September 29

Added user-defined seed specification to `pass_phrase.html`. If a pseudorandom seed is requested, its value is displayed in the user-defined seed field so it may be saved for subsequent use.

### 2003 November 15

Extracted the entropy collection logic from `javascrypt.html` and `pass_phrase.html` into a new `entropy.js` module. Added a new `mouseMotionEntropy` function which captures mouse motion events and collects a specified number of subsequent triples of screen X and Y co-ordinates (we use the absolute screen position as it is more entropic than position within the client window), and the time of the mouse movement. This primes the entropy array with reasonably high quality data before most operations which require it.

Modified `jscrypt.js` to use `AESprng` in `aesprng.js` to generate the initial vector for CBC encryption and pad to an even number of blocks (if required). The AES-based pseudorandom generator is primed with a seed computed from the entropy vector.

Updated `aesprng_test.html` to conform with the changes to initial vector generation.

### 2003 November 17

Increased the maximum length of the key in `javascrypt.html` and the seed in `pass_phrase.html` to 1024 characters,

### 2003 November 18

Replaced `"./"` link targets in references to the JavaScrypt home page with `"index.html"` so these links work correctly when referencing the pages from a `file:` URL on a machine to which the user has downloaded the pages.

### 2003 November 19

Modified `aesprng_test.html` to generate hexadecimal pseudorandom streams suitable for testing with ENT, and rewrote the code which assembles the strings and stuffs them into the results dialogue box to run about a thousand times faster, avoiding JavaScript's (at least on Mozilla) exponential slowdown when appending large results to `textarea` value fields.

### 2003 November 20

Further cleaned up `aesprng_test.html` so it's comprehensible without reading the source code. It now lets you specify the number of bytes to be generated and whether they're generated with the `next` or `nextInt` methods with HTML controls, shows the number of bytes when generated if the script is paused by an "unresponsive" warning, and lets you generate seeds just like `pass_phrase.html` does. I also cleaned up the format of the output it generates so it look just like an "XD" output and no longer requires the "`-s`" option when converting to binary with XD. The `aesprng_test.html` being sufficiently civilised now, I included it in the source distribution.

Added comments to the methods in `aesprng.js`.

Added missing `example.html` description to `distribution.html`.

### 2003 November 21

Fixed truncation of warning message in `index.html` if JavaScript is not enabled. I also added a gimmick so that the background of the JavaScript enabled field is pink if JavaScript isn't present and green if it is.

Modified all Fourmilab links outside the JavaScrypt document tree to include an explicit "`http://www.fourmilab.ch/`". This permits them to function even when the pages are accessed from a local copy via a `file:` URL.

The welcome page, `index.html`, was needlessly including several JavaScript modules it never actually used. I removed the script includes for them.

### 2003 November 27

Modified the `nextInt` methods in `aesprng.js` and `lecuyer.js` to avoid the bias which results from using a modulus to obtain a pseudorandom value with a range which isn't a power of two. As explained in section 10.8 of Ferguson and Schneier's Practical Cryptography, to avoid a bias toward smaller values, one must generate pseudorandom values between 0 and the next higher power of two minus one, then discard results which are out of range in order to preserve a uniform distribution within the requested range. In `aesprng.js`, this fix has two additional salutary effects. First of all, it reduces the number of raw bytes generated to the minimum required to produce the desired result range and, if the requested range is 0-255, produces identical results to those obtained by calling the `next()` method directly.

### 2003 November 29

As reported by Steven Wittens, `jscrypt.js` failed to handle plaintexts which contained Unicode characters greater than 0xFF. The conversion of the plaintext string to the AES plaintext byte array simply truncated characters to 8 bits. I added a new `utf-8.js` module which handles transformation between Unicode strings and UTF-8 encoded byte streams. Canonical transformation is implemented in the functions `unicode_to_utf8` and `utf8_to_unicode`, which take a string argument and return the encoded or decoded string.

For use with JavaScrypt, the wrapper functions `encode_utf8` and `decode_utf8` are used to provide more efficient representation of the very common case of text which consists only of ASCII and Latin-1 characters. If its argument contains neither any characters with code points greater than or equal to 0xFF nor the character 0x9D (Unicode OPERATING SYSTEM COMMAND), `encode_utf8` is an identity transformation--the encoded string is identical to the input. Otherwise, `encode_utf8` returns a string which begins with the character 0x9D acting as a sentinel, followed by the UTF-8 encoding of the argument string. The `decode_utf8` function checks for the presence of the 0x9D sentinel and decodes the balance of the argument string as UTF-8 or returns the argument unchanged accordingly. Now, it might have been more logical to use one of the two Unicode PRIVATE USE control characters as the sentinels, but both of them are overloaded by characters in the regrettable "Windows-1252" character set. Characters from that set have no business appearing in JavaScript strings, but you never know what somebody is going to paste into an HTML text box, so this choice keeps such text from being unnecessarily expanded to UTF-8.

Both `jscrypt.js` and `pass_phrase.html` now apply `encode_utf8` to text keys and seeds. This avoids the loss of information in upper bytes of characters greater than 0x7F. Since `encode_utf8` is an identity for strings without such characters, this change is upward compatible with any key or seed consisting entirely of ASCII and Latin-1 graphic characters.

Added this development log to the Web directory, and provided a link from the main page.

### 2004 March 19

The "lean" version, `jscrypt.html` failed to embed the JavaScript code for `utf-8.js` because the program which does the embedding assumed file names consisted only of alphanumeric characters and failed to recognise the external script reference to that file. I modified the embedding program accordingly and rebuilt `jscrypt.html` with it. Earlier testing failed to reveal this problem which only manifested itself when the lean version was copied to a directory which did not contain `utf-8.js`.

### 2005 December 16

The `formatPlaintext` function in `aes.js` uses a heuristic instead of `instanceof` to decide whether its argument is a string (primitive or reference) or an array of bytes (numbers) in order to remain compatible with versions of Internet Explorer prior to 5.0 which did not implement `instanceof`. Unfortunately, this trick ran afoul of changes to the JavaScript implementation in Mozilla Firefox 1.5. After a bit of experimentation, I made the test even more tricky and complicated and it now seems to work on Firefox 1.5 as well as Firefox 1.0, Mozilla, Opera, Internet Explorer (although I have nothing older than 6.0) and Netscape 4.7 on SGI.

The link for verifying the distribution signing key on KeyServer was broken due to a change in their domain name; fixed.

Added `content-type` declarations of `charset=iso-8859-1` to all HTML documents and fixed most validation errors reported by the W3C HTML validator for 4.01 Transitional. A few remain, however, so we're not claiming full compliance. The problem is that without the `wrap="off"` attribute in a number of `textarea` fields, undesired line wrapping will occur. You're supposed to be able to control this with the CSS `white-space: pre` statement, but it doesn't seem to do anything inside a `textarea`, even in Firefox 1.5. So, there's no option but to leave the `wrap` in place, even though the validator complains about it.

The HTML 4.01 compatibility fixes broke the Perl program which creates the "lean" version of the encryption/decryption page; fixed.

### 2005 December 24

Upgraded the following files for XHTML 1.0 syntax and validated them for compliance: `aesprng_test.html`, `distribution.html`, `example.html`, `index.html`, and `log.html`.

### 2005 December 25

Upgraded the following files for XHTML 1.0 syntax and validated them for compliance: `javascrypt.html`, `pass_phrase.html`, and `stego.html`.

Removed `wrap="off"` attributes in `<textarea>` fields, as this is not an XHTML 1.0 (or HTML 4.01) supported mode. The CSS mode which is supposed to provide an equivalent doesn't work in current browsers, but in any case this is purely an aesthetic and presentation issue: wrapping of text within a `textarea` does not affect its processing.

Modified the `flense.pl` Perl program used to build the `jscrypt.html` "lean" version of the encryption/decryption utility use XHTML "`CDATA`" quoting of embedded JavaScript code to avoid validation errors. The XHTML quoting is commented out with JavaScript comments to avoid problems with older browsers.

This document is in the public domain.

### Back to JavaScrypt