# Hash digest verify

`hash-digest-verify` · version 1.0.0 · Hashing & signatures · free, no key needed

Recompute a fixed-length digest over encoded input bytes and compare it to an expected digest given in any encoding.

**Use when you need to: verify sha256 checksum · does this md5 match the file · check if this hash is correct.**

## Decide before calling

Read the [versioned contract](/v1/tools/hash-digest-verify/versions/1.0.0) and the supported scope below. Reuse `hash-digest-verify@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `hash-digest-verify@1.0.0` for verify sha256 checksum. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- verify sha256 checksum
- does this md5 match the file
- check if this hash is correct
- confirm sha3-256 digest
- compare base64 hash to hex hash
- validate a downloaded file checksum
- אמת גיבוב מול ערך צפוי

## Not supported

- verifying shake128/shake256/blake3 (no fixed digest length; use hash-digest-compute and compare manually)
- fetching the file or URL to hash (text/bytes must be supplied directly)

## Behavior

- algorithm is restricted to the fixed-length digest algorithms (shake128, shake256 and blake3 are invalid_input here; use hash-digest-compute for those).
- computed_hex is always the lowercase hex digest of text under algorithm, returned even when valid is false, so the caller can see the correct value.
- expected_encoding 'auto' (default) tries, in order, hex (case-insensitive), then base64 (RFC 4648 section 4, padded), then base64url (RFC 4648 section 5, unpadded), each requiring the decoded length to equal the digest length; if none match, the result is valid:false, reason:'expected_not_decodable', matched_encoding:null, with no length/syntax distinction under auto.
- An explicit expected_encoding first checks that encoding's own syntax (a failure is 'expected_not_decodable'); a syntactically valid value of the wrong decoded length is 'expected_wrong_length'. Both leave matched_encoding null.
- Once expected decodes to exactly the digest length, it is compared to the computed digest with a constant-time comparison: a mismatch is valid:false, reason:"mismatch"; a match is valid:true, reason:null, both with matched_encoding set to the encoding that produced the comparison.
- hex comparison for expected is case-insensitive; computed_hex in the output is always lowercase regardless of the case used in expected.

## Input

- `text` (string, required): max length 262144
- `input_encoding` (one of "utf8", "hex", "base64", "base64url", optional): default `"utf8"`
- `algorithm` (one of "md5", "sha1", "ripemd160", "sha224", "sha256", "sha384", "sha512", "sha512-224", "sha512-256", "sha3-224", "sha3-256", "sha3-384", "sha3-512", "keccak-256", "blake2b-256", "blake2b-512", "blake2s-256", required)
- `expected` (string, required): min length 1; max length 512
- `expected_encoding` (one of "auto", "hex", "base64", "base64url", optional): default `"auto"`

## Output

- `valid` (boolean, required)
- `reason` (one of "mismatch", "expected_not_decodable", "expected_wrong_length", null, required)
- `algorithm` (one of "md5", "sha1", "ripemd160", "sha224", "sha256", "sha384", "sha512", "sha512-224", "sha512-256", "sha3-224", "sha3-256", "sha3-384", "sha3-512", "keccak-256", "blake2b-256", "blake2b-512", "blake2s-256", required)
- `matched_encoding` (one of "hex", "base64", "base64url", null, required)
- `computed_hex` (string, required): min length 2; pattern `^[0-9a-f]+$`

## Limits

- max input bytes: 65536

## Example

Request input:

```json
{
  "text": "abc",
  "algorithm": "sha256",
  "expected": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
}
```

Response:

```json
{
  "result": {
    "valid": true,
    "reason": null,
    "algorithm": "sha256",
    "matched_encoding": "hex",
    "computed_hex": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "hash-digest-verify",
  "version": "1.0.0",
  "input": {
    "text": "abc",
    "algorithm": "sha256",
    "expected": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/hash-digest-verify/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"text":"abc","algorithm":"sha256","expected":"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"}'
```

The machine-readable contract is at [/v1/tools/hash-digest-verify/versions/1.0.0](/v1/tools/hash-digest-verify/versions/1.0.0).

### CLI

```sh
node cli.mjs run hash-digest-verify 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [Hash digest compute](/tools/hash-digest-compute): Compute a message digest (SHA-2, SHA-3, BLAKE2/3, MD5, RIPEMD-160, Keccak-256) over encoded input bytes.
- [Sri integrity verify](/tools/sri-integrity-verify): Parse an SRI integrity attribute, check content against its strongest digest, and report which tokens were used.
- [Hmac verify](/tools/hmac-verify): Recompute an HMAC and compare it, constant-time, to a signature that may carry a literal prefix and be truncated.
- [Checksum manifest verify](/tools/checksum-manifest-verify): Parse a GNU/BSD checksum manifest (sha256sum -c, tagged form) and verify caller-supplied file contents against it.
- [Merkle proof verify](/tools/merkle-proof-verify): Recompute a Merkle root (RFC 9162 or Bitcoin) from one leaf and its audit path, and compare it to a claimed root.
- [Git object id compute](/tools/git-object-id-compute): Compute the Git object id git itself would give a blob, tree, commit or tag under Git's exact object framing.
