* defines the **mandatory** baseline algorithm `HASH-ASL1-256`;
* reserves ranges for future classical and post-quantum algorithms;
* specifies how these algorithms are used when deriving `Reference` values:
* via `ASL/CORE-REF-DERIVE/1` in `ASL/1-CORE`, and
* via `ENC/ASL1-CORE v1` binary encoding of `ReferenceBytes`.
This is a **substrate primitive profile**, not kernel, but:
> In Amduat 2.0, all **identity-critical** `Reference.hash_id` values used by the standard stack (ASL/1-STORE, TGK/1-CORE, PEL/1, CIL/1, FER/1, FCT/1, OI/1) MUST be interpreted according to this registry.
---
## 1. Scope
### 1.1 In scope
This specification standardizes:
1. The **ASL1 hash family**: common properties all algorithms must satisfy.
2. A **registry** from `HashId` → algorithm descriptor:
digest[...] // remaining bytes in the frame are the digest
```
**Note:** `Reference` carries only `hash_id` and `digest`. There is no extra “family” field on-wire. For Amduat 2.0, `HashId` values in ASL/1 contexts are **globally** interpreted using this `HASH/ASL1` registry.
---
## 3. The ASL1 Hash Family
### 3.1 Family properties
All `"ASL1"` algorithms MUST be **cryptographic hash functions**:
* **Preimage resistance** – infeasible to find `x` for a given digest `d` with `H(x) = d`.
* **Second-preimage resistance** – infeasible, given `x`, to find `x' ≠ x` with `H(x') = H(x)`.
* **Collision resistance** – infeasible to find any `(x, x')`, `x ≠ x'` with `H(x) = H(x')`.
Each `"ASL1"` algorithm:
* accepts arbitrary-length `OctetString` inputs,
* produces a **fixed-length**`OctetString` digest,
* MUST support **incremental / streaming** operation:
* a single forward-only pass over input,
* no need to buffer entire input.
These properties allow:
* hashing large canonical encodings incrementally,
* use in streaming stores and execution engines.
### 3.2 Family name and global use
* Family name: `"ASL1"`.
Within Amduat 2.0:
* all **identity-critical**`Reference.hash_id` values used by the standard stack are interpreted as entries in this `"ASL1"` registry;
*`HASH/ASL1` is therefore the **global assignment** for `HashId` in ASL/1 identity contexts.
If other hash families are used in non-ASL contexts (e.g., external APIs), they **MUST NOT** reuse `HashId` values defined here for `Reference.hash_id` in ASL/1-CORE. They should either:
* live in separate fields / structures; or
* use distinct namespaces not confused with `Reference.hash_id`.
### 3.3 HashId space
`HashId` is `uint16` and appears in `Reference.hash_id` and in `ReferenceBytes.hash_id`.
This registry reserves:
*`0x0000` — **Reserved** (never a valid algorithm).
*`0x8000–0xFFFF` — post-quantum or specialized `"ASL1"` algorithms.
Each algorithm has an intrinsic digest length `L` (>0 bytes), defined by its normative spec. This document does not impose an upper bound beyond “finite and practically representable in implementations.” (ENC/ASL1-CORE v1 does not carry the length explicitly; length is implied by framing and cross-checked against `L` when the algorithm is known.)
---
## 4. Algorithm Registry
### 4.1 Registry (v0.2.4)
The `"ASL1"` registry is a mapping:
```text
HashId (uint16) -> Algorithm descriptor
```
At version 0.2.4:
| HashId | Name | Digest (bytes) | Status | Notes |
this becomes the **canonical default** Reference derivation for Amduat 2.0.
Unless a profile explicitly opts out, all identity-critical `Reference` values for Artifacts encoded under `ASL_ENC_CORE_V1`**MUST** use this `(P, H)` pair.
*`0x8001` — `HASH-ASL1-PQ1`; first post-quantum algorithm, TBD.
*`0x8002–0x80FF` — reserved block for additional post-quantum / specialized algorithms.
Implementations MUST NOT treat these IDs as usable until a future `HASH/ASL1` revision defines them normatively.
---
## 5. Interaction with ASL/1-CORE & ENC/ASL1-CORE v1
### 5.1 Reference derivation
`ASL/1-CORE` defines `ASL/CORE-REF-DERIVE/1`. `HASH/ASL1` simply supplies the `"ASL1"` algorithms and `HashId`s.
Given:
* Artifact `A`,
* encoding profile `P`,
* algorithm `H` with `HashId = HID`,
then:
```text
ArtifactBytes = encode_P(A)
digest = H(ArtifactBytes)
Reference = { hash_id = HID, digest = digest }
```
All ASL/1 conformant components **MUST** use this procedure for any `(EncodingProfileId, HashId)` pair they claim to support.
### 5.2 ReferenceBytes under ENC/ASL1-CORE v1
`ENC/ASL1-CORE v1` encodes a `Reference` as:
```text
u16 hash_id
digest[...] // remaining bytes in the enclosing frame are the digest
```
This profile does **not** carry an explicit digest length; framing is provided by the enclosing structure (e.g., length-prefix, message boundary).
When an implementation both:
* decodes `ReferenceBytes` under `ENC/ASL1-CORE v1`, and
* implements `HASH/ASL1` and recognizes `hash_id`,
then it MUST enforce:
```text
len(digest) == canonical_digest_length(hash_id)
```
where `canonical_digest_length(hash_id)` is taken from this registry.
Any mismatch MUST be treated as an encoding / integrity error by the consumer.
If a `hash_id` is unknown (or HASH/ASL1 is not implemented), an implementation MAY still treat the bytes as a generic `Reference { hash_id, digest }`, but:
* it cannot recompute or verify the digest cryptographically, and
* higher layers MAY treat such a `Reference` as unsupported or lower-trust.
---
## 6. Crypto Agility & Evolution
### 6.1 Immutability of assignments
Once a `HashId` is assigned to an algorithm, its:
* digest length,
* underlying construction,
* behavior on all inputs,
MUST NOT change in any way that alters output values for the **same input bytes**.
For example:
*`HashId = 0x0001` MUST always denote SHA-256 semantics; future revisions cannot redefine it as anything that changes the digest for the same input bytes (e.g. “SHA-256 plus domain separator”).
If domain separation or similar techniques are required, they MUST be expressed at the **input construction** level (e.g. in `CID/1` or encoding profiles), not by changing the hash function definition.
### 6.2 Adding new algorithms
A new `"ASL1"` algorithm MAY be added in a future `HASH/ASL1` version if and only if:
* it satisfies the family properties in §3.1;
* it has a fixed digest length `L > 0` bytes;
* its spec includes:
* assigned `HashId`,
* digest length,
* normative algorithm definition (via external standard or full spec),
* status (`MANDATORY`, `RECOMMENDED`, `OPTIONAL`, `EXPERIMENTAL`);
* it is introduced via:
* a new `HASH/ASL1` version,
* at least one ADR,
* published test vectors.
Existing `HashId` assignments MUST NOT be repurposed.
### 6.3 Coexistence and migration (informative)
Higher layers can use `"ASL1"`’s crypto agility by:
* computing more than one `Reference` for the same Artifact (multi-hash),
* storing those in receipts, overlays, or catalogs,
* defining profile-specific policies like:
* “from date D, compute both `HASH-ASL1-256` and `HASH-ASL1-PQ1` for all new Artifacts; prefer 0x8001 for new dependencies.”
`HASH/ASL1` itself:
* does not prescribe when to migrate,
* only guarantees that `HashId` mappings and algorithms are stable.
The frame boundary (e.g., length prefix or message boundary) determines where the digest ends. A consumer that knows `hash_id = 0x0001` and implements HASH/ASL1 will:
* expect exactly 32 digest bytes,
* treat any other length as an error.
This `Reference` can be used consistently across `ASL/1-STORE`, `TGK/1-CORE`, `PEL/1`, `CIL/1`, `FER/1`, `FCT/1`, `OI/1`, with equality defined by `ASL/1-CORE`.