Yes, it's actually an untrusted event because you ignore a lot of process of trusted key events, e.g., targeting focused element. I don't know if bookmarklet is running on chrome or content. If it's running on chrome, you can use nsIDOMWindowUtils.sendKeyEvent() for generating trusted key events.
Bookmarklets run in the context of a web page, with the privileges of the web page. It wouldn't be safe to mix in higher privileges while still running in the context of the web page, because a site could modify "String.prototype.charCodeAt" or create a getter/setter pair for "window.s", changing the behavior of your bookmarklet or even running its own code while the bookmarklet is running. (I suppose we could move bookmarklets to a "wrapper" model like Greasemoneky, but that would break page-specific bookmarklets that do want to interact with page JS.) You could explore a mixed-privilege setup such as Greasemonkey or a Firefox extension, but I'd recommend using "e.value += s;" followed by calling the page's onchange handler yourself.
Calling onchange handler is not always sufficient. For instance, my barcode scanner uses TAB as the final delimiter of the barcode, and in the browser, obviously, TAB moves to the next input field. Are you suggesting I should replicate all the complexities of the TAB handling (including analyzing tabindex fields) in my bookmarklet? I need onkeypress rather than onchange.
Interesting twist. We don't want to expose "normal" tab behavior to web pages, because the "normal" tab order includes the address bar and items in third-party iframes. But it might be sensible to have a window.advanceFocus() or window.nextElementInTabOrder that stays within the document. This seems to be a somewhat common thing for web developers to want to do, so please consider suggesting it to the WhatWG :) http://stackoverflow.com/questions/7208161/focus-next-element-in-tab-index