Skip to content
Brian Turek edited this page Apr 15, 2020 · 5 revisions

Welcome to the jsSHA wiki! If there is an eventual need, this page will be split up into separate sub-pages but, for now, it will be one page with sections.

API

Starting in v3.1, the jsSHA API changed with the deprecation of setHMACKey and getHMAC in favor of specifying the HMAC key at object instantiation and getHash, respectively. I am usually loathe changing the jsSHA API and doubly so with a minor version bump. The reasoning behind this change can be read below.

Overview

Usage of jsSHA typically involves three calls:

// See below for constructor arguments
const hash = new jsSHA(...);
hash.update("Stuff to hash")
// The first argument can be one of "HEX" | "B64" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY".
// This can also be called multiple times
hash.getHash("HEX")
// For variable-length hashes (SHAKE, CSHAKE, and KMAC), you must specify the output length, in bits:
// hash.getHash("HEX", { outputLen: 256 })

Option Type

The new API options are built on a new "basic" type, called GenericInputType, that encompasses an input value:

type GenericInputType =
  | {
      value: string;
      format: "TEXT";
      encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
    }
  | {
      value: string;
      format: "B64" | "HEX" | "BYTES";
    }
  | {
      value: ArrayBuffer;
      format: "ARRAYBUFFER";
    }
  | {
      value: Uint8Array;
      format: "UINT8ARRAY";
    };

In human speak:

  • For "TEXT" string-type inputs, you must specify value which is a string, you must specify a format with the literal string "TEXT", and you may specify encoding which must be one of the literal strings "UTF8", "UTF16LE", or "UTF16BE". If encoding is omitted, it defaults to "UTF8".
  • For "B64", "HEX", and "BYTES" string-type inputs, you must specify both value which is a string and a format which must be one of the literal strings "B64", "HEX", or "BYTES".
  • For ArrayBuffer inputs, you must specify both value which is an ArrayBuffer and a format which must be the literal string "ARRAYBUFFER".
  • For Uint8Array inputs, you must specify both value which is an Uint8Array and a format which must be the literal string "UINT8ARRAY".

Constructor

The constructor is most easily understood if you group jsSHA into four families that depend on the usage: normal hashing, HMAC, CSHAKE, and KMAC. These all use a bag-of-options argument, option, that uses a "basic" input type for many of its key/value pairs.

Option Type

The new API options are built on a new "basic" type, called GenericInputType, that encompasses an input value:

type GenericInputType =
  | {
      value: string;
      format: "TEXT";
      encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
    }
  | {
      value: string;
      format: "B64" | "HEX" | "BYTES";
    }
  | {
      value: ArrayBuffer;
      format: "ARRAYBUFFER";
    }
  | {
      value: Uint8Array;
      format: "UINT8ARRAY";
    };

In human speak:

  • For "TEXT" string-type inputs, you must specify value which is a string, you must specify a format with the literal string "TEXT", and you may specify encoding which must be one of the literal strings "UTF8", "UTF16LE", or "UTF16BE". If encoding is omitted, it defaults to "UTF8".
  • For "B64", "HEX", and "BYTES" string-type inputs, you must specify both value which is a string and a format which must be one of the literal strings "B64", "HEX", or "BYTES".
  • For ArrayBuffer inputs, you must specify both value which is an ArrayBuffer and a format which must be the literal string "ARRAYBUFFER".
  • For Uint8Array inputs, you must specify both value which is an Uint8Array and a format which must be the literal string "UINT8ARRAY".

Normal Usage

// For future "TEXT" inputs:
const hash = new jsSHA(
  variant: "SHA-1" | "SHA-224" | "SHA-256" | "SHA-384" | "SHA-512" | "SHA3-224"  | "SHA3-256" | "SHA3-384" | "SHA3-512" | "SHAKE128" | "SHAKE256",
  inputFormat: "TEXT",
  options: { encoding?: "UTF8" | "UTF16LE" | "UTF16BE" }
);
// For future non-"TEXT" inputs:
const hash = new jsSHA(
  variant: "SHA-1" | "SHA-224" | "SHA-256" | "SHA-384" | "SHA-512" | "SHA3-224"  | "SHA3-256" | "SHA3-384" | "SHA3-512" | "SHAKE128" | "SHAKE256",
  inputFormat: "B64" | "HEX" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY");
);

The only difference between the two is the omission of the options argument which, as it only contains key/values relevant for parsing "TEXT" inputs, isn't needed for non-"TEXT" inputs. variant specifies the desired algorithm to use and inputFormat influences how future .update() calls are interpreted.

HMAC Usage

The HMAC constructor is a superset of the "normal" constructor but with the addition of an extra options key/value called hmacKey whose value is of type GenericInputType as described earlier. In code:

// For future "TEXT" inputs:
const hash = new jsSHA(
  variant: "SHA-1" | "SHA-224" | "SHA-256" | "SHA-384" | "SHA-512" | "SHA3-224"  | "SHA3-256" | "SHA3-384" | "SHA3-512",
  inputFormat: "TEXT",
  options: {
    encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
    hmacKey: GenericInputType
  }  
);
// For future non-"TEXT" inputs:
const hash = new jsSHA(
  variant: "SHA-1" | "SHA-224" | "SHA-256" | "SHA-384" | "SHA-512" | "SHA3-224"  | "SHA3-256" | "SHA3-384" | "SHA3-512",
  inputFormat: "B64" | "HEX" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY",
  options: {
    hmacKey: GenericInputType
  } 
);

Again, the only difference between the two forms is the omission of the encoding key in the options argument. Also note that SHAKE128 and SHAKE256 do not support HMAC.

CSHAKE Usage

The CSHAKE constructor is similarly a superset of the "normal" constructor but with the addition of an extra options keys/values called customization and funcName whose value are of type GenericInputType as described earlier. These represent the "customization" and "function-name" parameters described in the NIST CSHAKE specification. In code:

// For future "TEXT" inputs:
const hash = new jsSHA(
  variant: "CSHAKE128" | "CSHAKE256",
  inputFormat: "TEXT",
  options: {
    encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
    customization?: GenericInputType;
    funcName?: GenericInputType;
  }  
);
// For future non-"TEXT" inputs:
const hash = new jsSHA(
  variant: "CSHAKE128" | "CSHAKE256",
  inputFormat: "B64" | "HEX" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY",
  options: {
    customization?: GenericInputType;
    funcName?: GenericInputType;
  } 
);

Again, the only difference between the two forms is the omission of the encoding key in the options argument. The customization and funcName keys are both optional, as specified by NIST.

KMAC Usage

The KMAC constructor is similarly a superset of the "normal" constructor but with the addition of an extra options keys/values called customization and kmacKey whose value are of type GenericInputType as described earlier. These represent the "customization" and KMAC key parameters described in the NIST KMAC specification. In code:

// For future "TEXT" inputs:
const hash = new jsSHA(
  variant: "KMAC128" | "KMAC256",
  inputFormat: "TEXT",
  options: {
    encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
    customization?: GenericInputType;
    kmacKey: GenericInputType;
  }  
);
// For future non-"TEXT" inputs:
const hash = new jsSHA(
  variant: "KMAC128" | "KMAC256",
  inputFormat: "B64" | "HEX" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY",
  options: {
    customization?: GenericInputType;
    kmacKey: GenericInputType;
  } 
);

Again, the only difference between the two forms is the omission of the encoding key in the options argument. The customization is optional, as specified by NIST, whereas kmacKey is required.

.update(arg)

Depending on the inputFormat value specified at instantiation, .update() expects its sole argument to be either a string, ArrayBuffer, or Uint8Array. .update() may be called multiple times.

.getHash(arg, options?)

.getHash() expects the first argument to be one of the string literals "B64", "HEX", "BYTES", "ARRAYBUFFER", "UINT8ARRAY which affects the output type:

  • "B64", "HEX" and "BYTES" cause a string to be returned.
  • "ARRAYBUFFER" causes an ArrayBuffer to be returned.
  • "UINT8ARRAY" causes an Uint8Array to be returned.

For variable-length hashes (SHAKE, CSHAKE, and KMAC), options must be in the form of {outputLen: number} where outputLen is the desired output length, in bits, and must be a multiple of 8.

For "B64" output type, options may in the form of {b64Pad: string} where b64Pad is the extra padding associated with Base-64 encoding, defaulting to "=".

For "HEX" output type, options may in the form of {outputUpper: boolean} where outputUpper causes the output to be capitalized if true, defaults to false.

Clone this wiki locally