Skip to main content
info

zkApp programmability is not yet available on the Mina Mainnet, but zkApps can now be deployed on Berkeley Testnet.

SHA-256

SHA-2 is a set of cryptographic hash functions designed by the National Security Agency (NSA) as an improved version of SHA-1, offering enhanced security and comprising multiple variants based on hash size, such as SHA-256 and SHA-512. It is also the predecessor of Keccak (SHA-3). The SHA-2 family is available with different output lengths, including 256-bit (SHA-256) or 512-bit (SHA-512). o1js supports only SHA-2 with an output length of 256 bits.

What is SHA-2 and SHA-256?

SHA-256, a part of the SHA-2 family, is a cryptographic hash function that generates a 256-bit (32-byte) hash output, widely used for traditional Web2 applications and protocols and blockchain technology. For example, Bitcoin's block headers are hashed twice using SHA-256.

SHA-256 and Poseidon

As an o1js developer, you are likely familar with the Poseidon zero knowledge native hash function. Poseidon operates over the native Pallas base field and uses parameters generated specifically for Mina which makes Poseidon the most efficient hash function available in o1js.

In contrast, SHA-2 is a hash function that requires binary arithmetic. It operates over binary data and is not native to most zero knowledge proofs. For this reason, SHA-256 is not as efficient as Poseidon. However, it is still very useful for verifying Ethereum transactions and blocks. So, when you choose what hash function to use, important considerations include the use case and the data that needs to be hashed.

Basic usage

SHA-256 is available in the following configuration under the Hash namespace in o1js:

  • Hash.SHA2_256: SHA2-256 hash function with output size of 256 bits.

Because SHA-256 operates over binary data instead of native Field elements like Poseidon, o1js uses the Bytes type. Bytes is a fixed-length array of bytes that can be used to represent binary data. Under the hood, Bytes is represented as an array of UInt8 elements.

In order to use Bytes, you must extend the Bytes class and specify the length of bytes. For a detailed explanation, take a look at How Keccak utilizes Bytes

// define a preimage
let preimage = 'The quick brown fox jumps over the lazy dog';

// create a Bytes class that represents 43 bytes
class Bytes43 extends Bytes(43) {}

// convert the preimage to bytes
let preimageBytes = Bytes43.fromString(preimage);

// hash the preimage
let hash = Hash.SHA2_256.hash(preimageBytes);

console.log(hash.toHex());
//d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592

See the o1js repository for a hashing example that uses SHA-256 and Keccak.

SHA-256 - API reference

// hash bytes using SHA256 with output size of 256 bits
Hash.SHA2_256.hash(bytes);