# Raw\_hash: one-call SHA-256 for tuples of integers in SimplicityHL

**URL:** <https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78>\
**Category:** SimplicityHL development\
**Created:** [September 28, 2026, 11:31am UTC](https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78 "2026-09-28T11:31:10Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![LesterEvSe](https://yyz1.discourse-cdn.com/flex007/user_avatar/community.simplicity-lang.org/lesterevse/32/67_2.png) [@LesterEvSe](https://community.simplicity-lang.org/u/LesterEvSe)\
**Post date:** [September 28, 2026, 11:31am UTC](https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78/1 "2026-09-28T11:31:10Z")

</div>

Hashing several values in SimplicityHL currently means threading a SHA-256 context through a chain of jets:

```rust
let ctx1: Ctx8 = jet::sha_256_ctx_8_init();
let ctx2: Ctx8 = jet::sha_256_ctx_8_add_2(ctx1, 0x5120);
let ctx3: Ctx8 = jet::sha_256_ctx_8_add_32(ctx2, tweaked_key);
let hash: u256 = jet::sha_256_ctx_8_finalize(ctx3);

```

Every hash of a compound value spans several lines of ctx-threading, which is noisy in application code.

[PR #423](https://github.com/BlockstreamResearch/SimplicityHL/pull/423) adds an unstable `raw_hash` builtin that does the same in one call:

```rust
let hash: u256 = raw_hash::<(u16, u256)>((0x5120, tweaked_key));

```

**How it works**  
It accepts a tuple of unsigned integers: `u8`, `u16`, `u32`, `u64`, `u128`, `u256`. It compiles to `init`, then one `sha_256_ctx_8_add_N` jet per element in source order, then `finalize`. It’s unstable, so it’s enabled with the `-Z raw_hash` flag.

**Why it’s “raw”**  
It hashes the concatenated bytes with no type or length information. Different inputs can therefore produce the same hash: for example, `(u8, u8)` holding `(0x51, 0x20)` and `(u16,)` holding `(0x5120,)` hash identically. Use it only where the layout of the hashed data is fixed and agreed on, and add your own tag or domain separation where it matters. A hash that’s unambiguous across types needs a more complete type system in SimplicityHL first, so that’s planned as a separate, later step ([discussion in #374](https://github.com/BlockstreamResearch/SimplicityHL/issues/374)).

---

<div class="post-metadata">

**Author:** ![stringhandler](https://avatars.discourse-cdn.com/v4/letter/s/c57346/32.png) [@stringhandler](https://community.simplicity-lang.org/u/stringhandler)\
**Post date:** [September 28, 2026, 12:21pm UTC](https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78/2 "2026-09-28T12:21:23Z")

</div>

Really cool. Nice to have the types in there.

I also added a [PR for the `chain!` built-in](https://github.com/BlockstreamResearch/SimplicityHL/pull/425). This is simpler, but doesn’t explicitly use the types, which could lead to footguns.

---

<div class="post-metadata">

**Author:** ![LesterEvSe](https://yyz1.discourse-cdn.com/flex007/user_avatar/community.simplicity-lang.org/lesterevse/32/67_2.png) [@LesterEvSe](https://community.simplicity-lang.org/u/LesterEvSe)\
**Post date:** [September 28, 2026, 12:55pm UTC](https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78/3 "2026-09-28T12:55:42Z")

</div>

Thanks! I took a quick look at your PR. `chain!` looks useful, because it solves the reading order in general, while `raw_hash` is specifically for hashing a tuple of values.

I think they fit different cases: `chain!` works for any sequence of steps, for example when the context starts from a tag, or when a step is a helper that adds several fields, or for types that have no `add_N` jet. `raw_hash` covers the simple case where you just want the digest of a flat tuple of integers, and the types pick the jets for you.

We could say this in the documentation once both land

---

<div class="post-metadata">

**Author:** ![schoen](https://avatars.discourse-cdn.com/v4/letter/s/b3f665/32.png) [@schoen](https://community.simplicity-lang.org/u/schoen)\
**Post date:** [September 28, 2026, 3:02pm UTC](https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78/4 "2026-09-28T15:02:56Z")

</div>

I was having a discussion with the developers of the [SHRINCS verifier implementation](https://github.com/BlockstreamResearch/shrincs-simplicity-verifier) about some inefficiencies in calling hash updates this way. An AI pointed out that if we used [structural typecasts](https://docs.simplicity-lang.org/simplicityhl-reference/type_casting/) we can often reduce the overhead by combining multiple hash updates into fewer.

I think that specific optimization works very well with `raw_hash`! The compiler can notice the fewest number of updates that would apply to the overall data in the individual `raw_hash` call, and use the structural typecast to combine the input data appropriately.

As a trivial example, `raw_hash::<u8, u8, u8, u8>((a, b, c, d))` could emit a single `jet::sha_256_ctx_8_add_4` call instead of four `jet::sha_256_ctx_8_add_1` calls. The caller _could_ have done the typecast into a `u32` itself, but the compiler can be helpful and take care of this for the caller.

---

<div class="post-metadata">

**Author:** ![LesterEvSe](https://yyz1.discourse-cdn.com/flex007/user_avatar/community.simplicity-lang.org/lesterevse/32/67_2.png) [@LesterEvSe](https://community.simplicity-lang.org/u/LesterEvSe)\
**Post date:** [September 28, 2026, 3:21pm UTC](https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78/5 "2026-09-28T15:21:30Z")

</div>

Could you create an issue for that in the SimplicityHL repo? Maybe we can optimize it further. While writing the contracts in price-oracle, we noticed that replacing the `jet::sha_256_ctx_8_add_N` jets with `jet::sha_256_block` and `jet::sha_256_iv()` produces more optimized code, although it is harder to read: [price-oracle/contracts/simf/storm\_eye/storm\_tree.simf at master · BlockstreamResearch/price-oracle · GitHub](https://github.com/BlockstreamResearch/price-oracle/blob/master/contracts/simf/storm_eye/storm_tree.simf)

---

<div class="post-metadata">

**Author:** ![schoen](https://avatars.discourse-cdn.com/v4/letter/s/b3f665/32.png) [@schoen](https://community.simplicity-lang.org/u/schoen)\
**Post date:** [September 28, 2026, 9:37pm UTC](https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78/6 "2026-09-28T21:37:53Z")

</div>

As the PR has already landed in SimplicityHL, I documented this at [Built-in Functions](https://docs.simplicity-lang.org/simplicityhl-reference/builtin/).

---

<div class="post-metadata">

**Author:** ![schoen](https://avatars.discourse-cdn.com/v4/letter/s/b3f665/32.png) [@schoen](https://community.simplicity-lang.org/u/schoen)\
**Post date:** [September 28, 2026, 10:54pm UTC](https://community.simplicity-lang.org/t/raw-hash-one-call-sha-256-for-tuples-of-integers-in-simplicityhl/78/7 "2026-09-28T22:54:08Z")

</div>

@LesterEvSe I suggested the compiler optimization here: [raw\_hash can be more optimized · Issue #426 · BlockstreamResearch/SimplicityHL · GitHub](https://github.com/BlockstreamResearch/SimplicityHL/issues/426)
