We have just released Revision 1 of Version 0.9.1 of the Pomcor JavaScript Cryptographic library (PJCL), which changes the way in which library functions are defined, making it easier to use PJCL in Node.js. In this post I describe the change and explain why it is important for full stack web application development.
A key feature of JavaScript is that it can be used both on the client side and the server side, using Node.js on the server. This allows full stack developers to use only one programming language when developing Node.js web applications. There is however a big difference between client-side and server-side JavaScript when it comes to using libraries or other pre-existing code.
JavaScript has no built-in mechanism for importing external code into
a program analogous to the #include preprocessor directive of C and
C++, and different methods are used for making use of external code on
the client and server sides. In the browser, a script tag is used to
import code in an HTML file, and importScripts()
is used
to import code in a web worker. In Node.js, external code must be
placed in a module, the module must be referenced by a call
to require()
, and functions exported by the module
must be referenced as methods of an object returned by
require()
.
This results in cryptographic code being written differently for the client and the server, even though client and server code are tightly integrated in a Node.js project. Client code may use a third-party cryptographic library or the Web Cryptography API of the W3C, implemented by the browsers. Server code will typically use the built-in crypto module of Node.js, which is a wrapper of OpenSSL.
PJCL prefixes its global functions and variables
with pjcl
, a trademark of Pomcor, and can thus be used in
any JavaScript environment without naming conflicts. In Node.js,
however, before Revision 1, either library code and client code had to
be placed in the same file, or library code had to be wrapped in a
module and referenced via the object produced by requiring the module.
Revision 1 differs from the original Version 0.9.1 in the way in which functions are defined. Function names are now global variables whose values are anonymous functions. For example, instead of defining
function pjclDSASignMsg(rbgStateStorage,p,q,g,x,msg) {...}
we now define
pjclDSASignMsg = function(rbgStateStorage,p,q,g,x,msg) {...}
Furthermore, global variables are now declared implicitly without
using the var
keyword.
This has no performance impact, and requires no changes in client code
running on a browser, while making it possible to call library
functions in Node.js server-side code exactly as in client-side code.
The library can now be referenced as-is in a call
to require()
, and its functions can be referenced
directly. That is, instead of wrapping the library into a Node.js
module such as, e.g.,
wrapped-pjcl.js
, exporting the functions you need,
and referencing those functions via the object produced by requiring
the module, as in:
var crypto = require(./wrapped-pjcl.js);
var sig = crypto.pjclDSASignMsg(rbgStateStorage,p,q,g,x,msg);
you simply write
require(./pjcl.js);
var sig = pjclDSASignMsg(rbgStateStorage,p,q,g,x,msg);
This should facilitate the development of Node.js web applications
with cryptographic functionality, by allowing full stack developers to
use PJCL both on the client side and the server side.