SHA-256 cryptographic hash function implementation for TypeScript and JavaScript
npx @tessl/cli install tessl/npm-stablelib--sha256@2.0.0@stablelib/sha256 provides a TypeScript implementation of the SHA-256 cryptographic hash function. It offers both streaming (incremental) and one-shot hashing capabilities with state serialization support for optimization in HMAC/PBKDF2 scenarios.
npm install @stablelib/sha256import { SHA256, hash, DIGEST_LENGTH, BLOCK_SIZE } from "@stablelib/sha256";For CommonJS:
const { SHA256, hash, DIGEST_LENGTH, BLOCK_SIZE } = require("@stablelib/sha256");import { hash, SHA256 } from "@stablelib/sha256";
// One-shot hashing (recommended for simple use cases)
const data = new TextEncoder().encode("Hello, World!");
const digest = hash(data);
console.log(digest); // Uint8Array(32) containing the hash
// Streaming hashing (for large data or incremental processing)
const hasher = new SHA256();
hasher.update(new TextEncoder().encode("Hello, "));
hasher.update(new TextEncoder().encode("World!"));
const streamDigest = hasher.digest();
console.log(streamDigest); // Same result as one-shot hashing
// Reusing hasher instance
hasher.reset();
hasher.update(data);
const reusedDigest = hasher.digest();@stablelib/sha256 is built around two main patterns:
hash() function for simple one-shot hashing operationsSHA256 class for streaming operations, state management, and advanced use cases like HMAC/PBKDF2 optimizationStandard SHA-256 algorithm constants for reference and validation.
/** Length of SHA-256 hash output in bytes (always 32) */
export const DIGEST_LENGTH: number;
/** Block size used by SHA-256 algorithm in bytes (always 64) */
export const BLOCK_SIZE: number;Convenience function for simple hashing operations without managing state.
/**
* Computes SHA-256 hash of the input data
* @param data - Input data to hash
* @returns SHA-256 hash digest (32 bytes)
*/
function hash(data: Uint8Array): Uint8Array;Usage Example:
import { hash } from "@stablelib/sha256";
// Hash a string
const message = new TextEncoder().encode("Hello World");
const digest = hash(message);
// Hash binary data
const binaryData = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
const binaryDigest = hash(binaryData);Main SHA-256 class for incremental hashing and advanced operations.
/**
* SHA-256 cryptographic hash algorithm implementation
* Implements SerializableHash interface for state management
*/
class SHA256 {
/** Length of hash output (always 32) */
readonly digestLength: number;
/** Block size (always 64) */
readonly blockSize: number;
/** Creates new SHA-256 instance with initialized state */
constructor();
/**
* Resets hash state making it possible to re-use this instance to hash other data
* @returns this instance for method chaining
*/
reset(): this;
/**
* Cleans internal buffers and resets hash state
* Securely wipes sensitive data from memory
*/
clean(): void;
/**
* Updates hash state with the given data
* @param data - Input data to add to hash
* @param dataLength - Number of bytes to read from data (defaults to data.length)
* @returns this instance for method chaining
* @throws Error when trying to update already finalized hash
*/
update(data: Uint8Array, dataLength: number = data.length): this;
/**
* Finalizes hash state and puts hash into output buffer
* If hash was already finalized, puts the same value
* @param out - Output buffer to write hash to (must be at least 32 bytes)
* @returns this instance for method chaining
*/
finish(out: Uint8Array): this;
/**
* Returns the final hash digest
* @returns SHA-256 hash digest as new Uint8Array (32 bytes)
*/
digest(): Uint8Array;
}Usage Examples:
import { SHA256 } from "@stablelib/sha256";
// Basic streaming hashing
const hasher = new SHA256();
hasher.update(new TextEncoder().encode("Part 1"));
hasher.update(new TextEncoder().encode("Part 2"));
const result = hasher.digest();
// Processing large data in chunks
const largeHasher = new SHA256();
const chunkSize = 1024;
for (let i = 0; i < largeData.length; i += chunkSize) {
const chunk = largeData.slice(i, i + chunkSize);
largeHasher.update(chunk);
}
const largeResult = largeHasher.digest();
// Reusing hasher for multiple operations
const reusableHasher = new SHA256();
reusableHasher.update(data1);
const hash1 = reusableHasher.digest();
reusableHasher.reset(); // Reset for next operation
reusableHasher.update(data2);
const hash2 = reusableHasher.digest();
// Cleanup when done
reusableHasher.clean();Advanced functionality for HMAC/PBKDF2 optimization where hash state needs to be saved and restored.
/**
* State serialization methods for performance optimization in cryptographic protocols
*/
interface SHA256StateManagement {
/**
* Returns hash state for later restoration
* Only works with unfinished hash state
* @returns Serializable state object
* @throws Error if hash is already finished
*/
saveState(): SavedState;
/**
* Restores previously saved hash state
* @param savedState - State object returned by saveState()
* @returns this instance for method chaining
*/
restoreState(savedState: SavedState): this;
/**
* Securely cleans saved state object
* @param savedState - State object to clean
*/
cleanSavedState(savedState: SavedState): void;
}
/**
* Serializable state object for save/restore operations
*/
type SavedState = {
/** Internal hash state */
state: Int32Array;
/** Buffered data (undefined if no buffered data) */
buffer: Uint8Array | undefined;
/** Length of buffered data */
bufferLength: number;
/** Total bytes processed */
bytesHashed: number;
};Usage Example:
import { SHA256 } from "@stablelib/sha256";
// HMAC optimization pattern
const hasher = new SHA256();
hasher.update(hmacKeyPadding); // Process key padding
// Save state after key processing
const keyState = hasher.saveState();
// First message
hasher.update(message1);
const hash1 = hasher.digest();
// Restore state for second message (reuse key processing)
hasher.restoreState(keyState);
hasher.update(message2);
const hash2 = hasher.digest();
// Clean up saved state
hasher.cleanSavedState(keyState);
hasher.clean();The SHA-256 implementation includes proper error handling for invalid operations:
update() on a finalized hash throws an errorsaveState() on a finished hash throws an errorimport { SHA256 } from "@stablelib/sha256";
const hasher = new SHA256();
hasher.update(data);
const digest = hasher.digest(); // Hash is now finalized
try {
hasher.update(moreData); // This will throw
} catch (error) {
console.error("Cannot update finalized hash:", error.message);
}
try {
hasher.saveState(); // This will also throw
} catch (error) {
console.error("Cannot save finished state:", error.message);
}hash() function for simple one-shot operationsSHA256 class for streaming large data or when you need to reuse the hasherclean() when done to ensure secure memory cleanup