Resolved by meaning: synthesis::Case holds both the priors (exact-upscale) and the unmarked frames (§7.6); synthesis §11.1 lists both inputs and the three policy members; the synthesis-mark corpus's cases hold no prior; exact-upscale passes synthesis's second_layer policy through; the live-conformance table gains the upscale row in its generator column; both CI steps and both CHANGELOG entries are kept. Generated files are main's here and are regenerated in the next commit. Co-Authored-By: Claude Opus 5.5 <[email protected]>
474 lines
29 KiB
Markdown
474 lines
29 KiB
Markdown
# WAI Extension: Exact Upscale
|
||
|
||
> Status: Draft. Registers the record `wai.media.upscale`: super-resolution as an exact
|
||
> derivation, and an account of which pixels a viewer saw were sent and which the sink made. A
|
||
> sink that receives a picture at a low resolution and presents it at a higher one runs
|
||
> `wai-upscale:sr2` (or `wai-upscale:sr4`): the pinned upscale of
|
||
> [integer-operators](integer-operators.md) §5E E11 plus a detail an integer network computes
|
||
> from the picture, every operation one of `wai-ops/1`, under a **prior** the sink holds by its
|
||
> SHA-256 (SPEC §3.1). Every sink computes the same bytes, so the high-resolution picture is a
|
||
> function of the transmitted bytes and the prior, and anyone holding both recomputes it. Since
|
||
> the sink's upscale is known exactly, an origin can send a **residual** against it, a `WIR1`
|
||
> payload of [staged-delivery](staged-delivery.md) Appendix A, and sign an **upscale record**
|
||
> stating the picture it aimed at and how far the sink's output may lie from it: no sample at
|
||
> all, or a stated bound. A prior overfitted to one title, a **per-title prior**, is carried by
|
||
> its digest like any other. A sink's **presentation statement** says, for a span of what it
|
||
> presented, which pictures were transmitted, which it derived exactly, which it edited by a
|
||
> step no one can recompute and which it generated, with the pixels and frames of each; each
|
||
> sink-made picture carries an origin claim of [synthesis](synthesis.md), and a generated
|
||
> picture names the model that made it. No new transport. The reference implementation is the
|
||
> `int_sr` module of `wai-rs` (feature `neural_int`), for the derivations, and its
|
||
> `exact_upscale` module (feature `exact_upscale`), for the records; the corpus is
|
||
> [`live-conformance/upscale/`](../live-conformance/upscale/), and its second implementation is
|
||
> `live-conformance/upscale_verify.py`. The tool that trains priors is
|
||
> `tools/wai_int_sr_train.py`.
|
||
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
|
||
>
|
||
> Texts read for this revision: the WAI texts this one cites, and RFC 8032 and RFC 8785.
|
||
|
||
## 1. Scope
|
||
|
||
In scope: the prior and the two derivations, their arithmetic, colour, edges and limits, and
|
||
their graph in the integer operator set (§3); the residual and the upscale record (§4); per-title
|
||
priors (§5); the categories of presented pictures, their origin claims and the presentation
|
||
statement (§6); verification (§7).
|
||
|
||
Out of scope: a transport; how a prior is trained, which is not part of the derivation (§5); how
|
||
a sink schedules a derivation; generating a picture between two others, whose arithmetic is the
|
||
generator's and whose claim is synthesis's (§6.1); and the presentation of anything that is not a
|
||
picture.
|
||
|
||
Relationship to the core spec: `wai.media.upscale` is a **record** ([SPEC](../SPEC.md) §5): a
|
||
signed record a WAI tool emits and verifies. It names no payload format and is not dispatchable.
|
||
A prior is a parameter set of one file, pinned by SHA-256 as SPEC §3.1 pins any other (§3.5).
|
||
|
||
Relationship to [synthesis](synthesis.md): `wai-upscale:sr2` and `wai-upscale:sr4` are pinned
|
||
integer derivations of synthesis §4.3, and an assistive claim over one is proved by recomputation
|
||
from the input's decoded samples and the prior (synthesis §4.4). A picture a sink presents and
|
||
does not publish is named in a claim by the digest of its samples (synthesis §3.1).
|
||
|
||
Relationship to [determinism-tiers](determinism-tiers.md): the derivations are integer
|
||
throughout, so their output is a pure function of the input's samples and the prior's bytes, and
|
||
a sink that presents it holds the tier of the decode it ran on (determinism-tiers §2, *What a
|
||
tier covers*): `decode-equivalence` over an input at `decode-equivalence`.
|
||
|
||
## 2. Records
|
||
|
||
The records of this extension are JSON objects under the encodings of synthesis §2: byte strings
|
||
in lowercase hexadecimal, unsigned integers of at most 2^53 − 1 in plain decimal, no other number,
|
||
no boolean, terms and date-times as jwp-receipts §2.4.3 defines them, no member named twice, at
|
||
most 32 levels of nesting, exactly the members a section lists at every level, and a `kind`
|
||
naming the record; one that does not is `record_malformed`.
|
||
|
||
Every record carries `signer_pubkey` (32 bytes) and `sig` (64 bytes):
|
||
|
||
```
|
||
sig = Ed25519(signer_key, "wai:upscale\x01" || JCS(record without "sig"))
|
||
link_hash = BLAKE3("wai:upscale-link\x01" || JCS(record))
|
||
```
|
||
|
||
The signature is verified strictly ([SPEC](../SPEC.md) §7 *Signatures*): a key that fails step 1
|
||
or 2 is `bad_key`, and a signature that fails a later step `bad_signature`. A record is named by
|
||
its link hash. A picture's **samples** are its `RGB8` buffer (rows top to bottom, pixels left to
|
||
right, three bytes a pixel, no padding), and its **digest** is SHA-256 (FIPS 180-4) over them, as
|
||
synthesis §2 has it. A picture of *w* × *h* has *w* · *h* **pixels**.
|
||
|
||
## 3. The derivations
|
||
|
||
### 3.1 The prior: `WSR1`
|
||
|
||
A prior is one file. Every multi-byte field is little-endian.
|
||
|
||
| off | size | field | rule |
|
||
|---|---|---|---|
|
||
| 0 | 4 | magic `WSR1` | |
|
||
| 4 | 1 | version | `1` |
|
||
| 5 | 1 | `n_layers` | 1 to 8 |
|
||
| 6 | 2 | `act_hi` | 1 to 32767: the ceiling of every hidden activation |
|
||
| 8 | … | the layers | `n_layers` layers, one after another; nothing follows the last |
|
||
|
||
A layer:
|
||
|
||
| size | field | rule |
|
||
|---|---|---|
|
||
| 1 | `k` | 1, 3 or 5: the kernel's side |
|
||
| 1 | `shift` | 0 to 31 |
|
||
| 2 | `cout` | 1 to 64; the last layer's is 12 |
|
||
| `cout` · `cin` · `k` · `k` | weights | signed bytes, in the order `[cout][cin][k][k]` |
|
||
| 4 · `cout` | biases | signed 32-bit integers |
|
||
| 2 · `cout` | multipliers | unsigned 16-bit integers, each at least 1 |
|
||
|
||
`cin` is 3 for the first layer and the previous layer's `cout` for every other.
|
||
|
||
A reader checks, in this order, and the first that fails names the refusal: the magic
|
||
(`bad_magic`); the version, present and 1 (`version`); `n_layers` and `act_hi` (`field_range`);
|
||
then each layer in turn: its four bytes present (`truncated`), its `k`, `shift` and `cout`
|
||
(`field_range`), its arrays present (`truncated`), each multiplier at least 1 (`field_range`);
|
||
then nothing after the last layer (`trailing`). A field missing from the 8-byte header is
|
||
`truncated`. A file that fails any of these is not a prior; a record that rests on it is refused
|
||
with the record's own reason (§7.2).
|
||
|
||
### 3.2 `wai-upscale:sr2`
|
||
|
||
`wai-upscale:sr2` under a prior *P* maps a *w* × *h* picture `in` to a 2*w* × 2*h* picture `out`.
|
||
All values are integers; no formula wraps or saturates unless it says so.
|
||
|
||
1. **The base.** `base` is `up2_predict` (integer-operators §5E E11) of `in`, channel by channel,
|
||
at 2*h* × 2*w*: the arithmetic of `wai-synthesis:upscale2` (synthesis §4.1), the last row and
|
||
column repeated.
|
||
2. **Centring.** *x*₀[*c*][*y*][*x*] = `in`(*x*, *y*)[*c*] − 128, for *c* the red, green and blue
|
||
bytes in that order: a tensor of 3 channels, *h* rows and *w* columns.
|
||
3. **The layers.** For each layer *i* of *P*, in order, with input *x*ᵢ of `cin` channels:
|
||
|
||
*a*[*o*][*y*][*x*] = Σ *W*[*o*][*ci*][*ky*][*kx*] · *x̃*ᵢ[*ci*][*y* + *ky* − ⌊*k*/2⌋][*x* + *kx* − ⌊*k*/2⌋],
|
||
|
||
the sum over *ci* < `cin`, *ky* < *k*, *kx* < *k*, with *x̃*ᵢ equal to *x*ᵢ inside the picture and
|
||
0 outside it; then *v* = R_half_up((*a* + `bias`[*o*]) · `mult`[*o*], `shift`)
|
||
(integer-operators §2). For every layer but the last, *x*ᵢ₊₁ = clamp(*v*, 0, `act_hi`). The last
|
||
layer's *v*, of 12 channels, is the **detail** *d*.
|
||
4. **Sub-positions.** detail[*c*][2*y* + *i*][2*x* + *j*] = *d*[4*c* + 2*i* + *j*][*y*][*x*], for *i*,
|
||
*j* ∈ {0, 1}: `pixel_shuffle` with factor 2 (integer-operators §5.10).
|
||
5. **The output.** `out`(*x*, *y*)[*c*] = clamp(`base`(*x*, *y*)[*c*] + detail[*c*][*y*][*x*], 0, 255).
|
||
|
||
A prior whose last layer's weights and biases are all 0 gives `out` = `base`.
|
||
|
||
### 3.3 Colour, edges, scale and limits
|
||
|
||
- **Colour.** The derivation reads and writes `RGB8` samples, the three channels together: each
|
||
layer mixes all of its input's channels. It states no colour space and converts none: its
|
||
output is in its input's.
|
||
- **Edges.** The base repeats the last row and column (§3.2 step 1). The network reads zero
|
||
outside the picture after centring (step 3), which is the sample value 128 before it.
|
||
- **Scale.** `wai-upscale:sr2` doubles each side. `wai-upscale:sr4` under *P* is
|
||
`wai-upscale:sr2` under *P* of `wai-upscale:sr2` under *P*: a 4*w* × 4*h* output. No other
|
||
factor is registered.
|
||
- **Limits.** A derivation is defined for a picture of at least one pixel whose every tensor, in
|
||
either pass of `sr4`, holds at most 2^26 elements (integer-operators §3): for `sr2`, *w* · *h*
|
||
times the largest `cout` of *P*, and 12 · *w* · *h*, are at most 2^26. A picture past that has
|
||
no output under *P*.
|
||
|
||
### 3.4 Through the integer operator set
|
||
|
||
The derivation is one `WHG1` graph (integer-operators §10) and one stage operator. The lowering
|
||
`sr2/1` writes, for a prior *P*:
|
||
|
||
- two data inputs, sizes set per decode: tensor 0, the picture `[3, h, w]`, and tensor 1, its
|
||
base `[3, 2h, 2w]`, each with the policy `check` over [0, 255];
|
||
- then the operators, each one's output taking the next tensor index, every tensor `derived`
|
||
with no exponent: `rescale` of tensor 0 with no multiplier, shift 0 and a `pre` bias of −128
|
||
on each channel; for each layer, `conv` with its `cout`, kernel `k` × `k`, stride 1, zero
|
||
padding ⌊`k`/2⌋ on each side, one group, its weights at one byte, and an `rq` with one
|
||
multiplier per channel at four bytes, its one `shift`, a `pre` bias per channel at four bytes
|
||
and the rounding `half_up`; after each layer but the last, `clamp(0, act_hi)`; then
|
||
`pixel_shuffle(2)`; `add` of tensor 1 and the detail; `clamp(0, 255)`, the graph's one output.
|
||
|
||
The driver computes the base with `up2_predict` (§5E E11), supplies both inputs, and reads the
|
||
output back as `RGB8`. A sink loads the graph from its canonical bytes under `acc64` with its
|
||
bounds certificate (integer-operators §8): a prior that reads (§3.1) always meets `acc64`, since
|
||
no value it forms passes 2^63. Where the certificate also meets `acc32`, a fabric of
|
||
`wai-ops/1-i32` (integer-operators §9.1) runs it, and every operator of the graph is in that
|
||
subset. The outputs are the same integers on every fabric (integer-operators §4).
|
||
|
||
### 3.5 Pinning a prior
|
||
|
||
A prior is a parameter set of one file, `sr.wsr`, and SPEC §3.1 pins it: `sha256` is the SHA-256
|
||
of the file's bytes, with no `form`. Its `determinism` is `int-sr2` and its `tier`, where stated,
|
||
`decode-equivalence`. Nothing but the digest names a prior: not an `id`, not a title, not a
|
||
network that compares equal after reading. A sink that runs a derivation under a prior it does
|
||
not hold by that digest has run another derivation.
|
||
|
||
## 4. The residual and the upscale record
|
||
|
||
### 4.1 The residual
|
||
|
||
A **residual** is a `WIR1` payload ([staged-delivery](staged-delivery.md) Appendix A) of the
|
||
`RGB8` unit kind with `predictor` 0 (identity), `n_units` 1, `d0` and `d1` the output's height
|
||
and width, and `d2` 3. Its decode is Appendix A.4's, with the upscaled picture as the unit's
|
||
current output: each sample becomes clamp(*u* + *r* · `q`, 0, 255), *u* the upscaled sample and
|
||
*r* the decoded residual. A residual whose every *r* is the target's sample less *u*, divided by
|
||
`q` and rounded to the nearest integer, halves away from zero (staged-delivery A.4's `rdiv`),
|
||
brings every sample within ⌊`q`/2⌋ of the target's, and to it exactly when `q` is 1.
|
||
|
||
### 4.2 The upscale record
|
||
|
||
An upscale record, `kind` `"wai-upscale"`, signed by the party that sends the picture (the
|
||
origin), says what a sink presents for one picture:
|
||
|
||
| member | type | meaning |
|
||
|---|---|---|
|
||
| `kind` | string | `"wai-upscale"` |
|
||
| `object` | 32 B hex | the content hash (jwp-receipts §2.1) of the object whose decode is the input picture |
|
||
| `input` | object | `{"width", "height", "samples"}`: the input picture's size, each at least 1, and digest |
|
||
| `derivation` | string | `wai-upscale:sr2` or `wai-upscale:sr4` |
|
||
| `prior` | 32 B hex | the SHA-256 of the prior (§3.5) |
|
||
| `upscaled` | 32 B hex | the digest of the derivation's output |
|
||
| `residual` | object or `null` | `{"sha256", "q"}`: the SHA-256 of the residual's bytes and its `q`, 1 to 65535; `null` for none |
|
||
| `output` | 32 B hex | the digest of the picture a sink presents: `upscaled` with no residual; the residual's decode over the upscaled picture otherwise |
|
||
| `target` | object or `null` | with a residual, `{"samples", "bound"}`: the digest of the picture the origin aimed at, and the largest difference it states between any sample of the output and the target's, 0 to 255; `null` exactly when `residual` is |
|
||
| `issued_at` | date-time | when the signer signed it |
|
||
| `signer_pubkey`, `sig` | | §2 |
|
||
|
||
A record whose output would pass 2^26 bytes (4 · *w* · *h* · 3 for `sr2`, 16 · *w* · *h* · 3 for
|
||
`sr4`), whose `residual` and `target` are not both `null` or both objects, or with no residual
|
||
whose `output` is not its `upscaled`, is `record_malformed`.
|
||
|
||
A record with a bound of 0 says the sink presents the target, byte for byte. A record with a
|
||
residual and a larger bound says the sink presents a picture no sample of which lies further
|
||
than the bound from the target's: the target is the origin's, and what reaches the viewer is
|
||
within the bound of it.
|
||
|
||
## 5. Per-title priors
|
||
|
||
A **per-title prior** is a prior an origin made for one title: a set of frames, a programme, a
|
||
game's art. It is a `WSR1` file like any other (§3.1), pinned by its digest (§3.5), carried to a
|
||
sink as any parameter set is ([prior-carriage](prior-carriage.md)), and named by the records over
|
||
the title's pictures. Nothing in a sink's derivation depends on how the prior was made.
|
||
|
||
How a prior is trained is not part of this extension. A prior trained in floating point and
|
||
quantised to `WSR1` is exact all the same: the derivation is the integer arithmetic of §3.2 over
|
||
the prior's bytes. A tool that trains priors **SHOULD** record its seeds and inputs, and say
|
||
whether its training regenerates the same bytes; where it does not, the prior's bytes, pinned by
|
||
their digest, are what is reproducible. The reference tool, `tools/wai_int_sr_train.py`, trains
|
||
in floating point from fixed seeds, and its training is not claimed to regenerate the same bytes
|
||
on another machine.
|
||
|
||
An origin **SHOULD** send a per-title prior only where the bytes it saves over the title, at the
|
||
quality the origin delivers (its residuals' `q` and the bounds it states), exceed the prior's own
|
||
bytes plus the bytes of the records that name it. A prior that saves less costs every sink that
|
||
fetches it more than it returns.
|
||
|
||
## 6. Accounting for sink-made pictures
|
||
|
||
### 6.1 Categories and their claims
|
||
|
||
Every picture a sink presents is in one **category**:
|
||
|
||
| category | what the picture is | its origin claim (synthesis §3) |
|
||
|---|---|---|
|
||
| `transmitted` | the decode of an object the sink received, or that decode upscaled and refined by a residual to the target of an upscale record (§4.2) | the object's own claim; for a refined picture, a `convert` claim whose subject is the picture's samples and whose one input is the object the record names |
|
||
| `derived` | `wai-upscale:sr2` or `wai-upscale:sr4` of a transmitted picture, with no residual | an `assist` claim whose subject is the picture's samples, with `replicate` evidence naming the derivation and its prior |
|
||
| `asserted` | an edit of a transmitted picture by a step no verifier recomputes: an upscale or an enhancement in floating point | an `assist` claim whose subject is the picture's samples, with `attest` evidence |
|
||
| `synthesized` | a picture a model made: a frame generated between two transmitted frames, a frame that replaces a lost one | a `generate` claim whose subject is the picture's samples and whose `models` include the model that made it |
|
||
|
||
The sink signs the claim of each picture it made, as the party that performed the step (synthesis
|
||
§3.1); the origin signs the claim of a refined picture, whose samples its record fixes. A
|
||
`derived` picture is proved by recomputation from the input's samples and the prior (synthesis
|
||
§4.4); an `asserted` one is the sink's statement and nothing more; a `synthesized` one is never
|
||
labelled lower than synthesized (synthesis §3.2).
|
||
|
||
### 6.2 The presentation statement
|
||
|
||
A sink signs a **presentation statement**, `kind` `"wai-presentation"`, for a span of a viewing
|
||
session, under a key of that session (no identity of the viewer or the device):
|
||
|
||
| member | type | meaning |
|
||
|---|---|---|
|
||
| `kind` | string | `"wai-presentation"` |
|
||
| `session` | 32 B hex | fresh random bytes of the session |
|
||
| `from`, `to` | integer | the span, in microseconds of the session's clock, `from` < `to` |
|
||
| `frames` | array | 1 to 4096 entries, one for each picture presented in the span, in presentation order |
|
||
| `totals` | object | `{"frames", "pixels"}`, each a **count**: `{"transmitted", "derived", "asserted", "synthesized"}` of integers |
|
||
| `issued_at` | date-time | when it signed it |
|
||
| `signer_pubkey`, `sig` | | §2 |
|
||
|
||
An entry:
|
||
|
||
| member | type | meaning |
|
||
|---|---|---|
|
||
| `at` | integer | when it was presented: `from` ≤ `at` < `to`, and greater than the entry before it's |
|
||
| `made` | string | its category (§6.1) |
|
||
| `width`, `height` | integer | its size, each at least 1, their product at most 2^40 |
|
||
| `samples` | 32 B hex | its digest |
|
||
| `object` | 32 B hex or `null` | the content hash of the object it was decoded from or computed from; `null` exactly for `synthesized` |
|
||
| `claim` | 32 B hex | the link hash of its origin claim (synthesis §2) |
|
||
| `upscale` | 32 B hex or `null` | the link hash of the upscale record it follows, where it follows one; `null` for `asserted` and `synthesized` |
|
||
| `made_by` | 32 B hex or `null` | for `derived`, the prior's SHA-256; for `asserted` and `synthesized`, the digest of the model that made it, which for `asserted` may be `null`; `null` for `transmitted`. For `synthesized`, this is the slot `made_by` of the contribution record `wai.media.contribution`, which names the party, here the sink's model, that made a part of the media. |
|
||
| `pixels` | object | a count (above): how many of its pixels are in each category (§6.3) |
|
||
|
||
A statement that breaks a rule of this table is `record_malformed`.
|
||
|
||
### 6.3 Counting pixels and frames
|
||
|
||
An entry's pixels are counted by its category, with *W* · *H* its own pixels and *n* the pixels
|
||
of the picture it was computed from:
|
||
|
||
- `transmitted`: all *W* · *H* are `transmitted`;
|
||
- `derived`: *n* are `transmitted` and *W* · *H* − *n* `derived`;
|
||
- `asserted`: min(*n*, *W* · *H*) are `transmitted` and the rest `asserted`;
|
||
- `synthesized`: all *W* · *H* are `synthesized`.
|
||
|
||
*n* is the input size the claim's evidence states. So a picture upscaled twice on each side counts
|
||
a quarter of its pixels as transmitted, whatever it shows: the transmitted bytes carried that
|
||
many. A refined picture counts all of its pixels as transmitted: the origin fixed every one of
|
||
them, within its stated bound.
|
||
|
||
The statement's `totals.frames` counts the entries of each category, and `totals.pixels` adds the
|
||
entries' `pixels`. The fraction of the span's pixels, or frames, in a category is its count over
|
||
the sum of the four. A statement whose totals are not these sums is `fractions_mismatch`.
|
||
|
||
## 7. Verification
|
||
|
||
### 7.1 Inputs
|
||
|
||
A verifier is given, each in a list: origin claims (synthesis §3.1); upscale records;
|
||
presentation statements; the envelopes of the objects it holds, each named by its content hash;
|
||
the decoded samples it holds, each with the content hash of the object decoded; the priors it
|
||
holds, each named by its SHA-256; the residuals it holds, each named by its SHA-256; the targets
|
||
it holds, each a picture named by its digest; and a **policy** of synthesis §11.1's members and
|
||
one more:
|
||
|
||
| member | values | default | meaning |
|
||
|---|---|---|---|
|
||
| `upscale` | `accept-unrecomputed`, `require-proof` | `accept-unrecomputed` | `require-proof`: §7.2 step 4.6 applies (`upscale_not_proved`) |
|
||
|
||
### 7.2 Steps
|
||
|
||
The verifier runs these steps and stops at the first refusal, which it reports with the reason
|
||
and where: a record by its list and index (`["upscale", i]`, `["presentation", i]`), an entry of a
|
||
statement by both (`["presentation", i, "frame", j]`), or synthesis's own place in the claims
|
||
(`["synthesis", …]`).
|
||
|
||
1. **Reading.** Each upscale record, then each presentation statement, reads (§2, §4.2, §6.2) and
|
||
its signature verifies: `record_malformed`, `bad_key`, `bad_signature`.
|
||
2. **Origin claims.** Synthesis §11.2 steps 1 and 2 over the claims, with the objects, the decoded
|
||
samples, the priors and the policy: a refusal there is this verification's, at `["synthesis",
|
||
["claim", i]]`.
|
||
3. **Priors.** Nothing yet: a prior is read where a record names it (step 4).
|
||
4. **Upscale records**, in order, each by these checks in order:
|
||
1. Its prior, where the verifier holds one by `prior`: it reads (§3.1) (`prior_invalid`).
|
||
2. Its input, where the verifier holds the decoded samples of `object`: they are `width` ·
|
||
`height` · 3 bytes and their digest is `input.samples` (`input_samples_mismatch`).
|
||
3. With the prior and the input held: the derivation's output (§3.2, §3.3) has the digest
|
||
`upscaled` (`upscale_mismatch`). An input past §3.3's limits under the prior has no output,
|
||
and is refused here too.
|
||
4. Its residual, where the verifier holds one by `residual.sha256`: it reads as §4.1's payload
|
||
for the output's size with the record's `q`, and decodes to its end (staged-delivery A.3,
|
||
A.4 steps 2 and 3) (`residual_invalid`); with the upscaled picture recomputed, its decode
|
||
over that picture has the digest `output` (`output_mismatch`).
|
||
5. Its target: with a bound of 0, `output` is `target.samples`; with the output recomputed and
|
||
the target held, no sample of the output lies further from the target's than the bound
|
||
(`residual_short`).
|
||
6. Under `upscale` `require-proof`, a record whose output was not recomputed in steps 3 and 4
|
||
(with no residual, step 3; with one, steps 3 and 4): `upscale_not_proved`.
|
||
|
||
A record whose output was recomputed is **proved**; otherwise it is **not recomputed**.
|
||
5. **Presentation statements**, in order, each entry in order, by these checks in order:
|
||
1. Its claim is a claim the verifier holds (`claim_unknown`), and, where it names one, its
|
||
upscale record is one it holds (`upscale_unknown`).
|
||
2. The claim is about the entry's picture: an object claim of the entry's `object`, for a
|
||
`transmitted` entry with no upscale record; a claim whose subject is the entry's `samples`,
|
||
for every other (`frame_subject_mismatch`).
|
||
3. The claim's class is not below the category's (§6.1): `assistive` for `derived` and
|
||
`asserted`, `synthesized` for `synthesized` (`made_understated`). A sink's upscaled picture
|
||
claimed `captured` or `reconstructed`, and a generated picture claimed `assistive`, are
|
||
refused here.
|
||
4. The claim is the category's (§6.1) (`made_mismatch`):
|
||
- `transmitted` with an upscale record: the record has a residual, its `object` is the
|
||
entry's, its `output` is the entry's `samples`, and the claim is a `convert` whose one
|
||
input is that object;
|
||
- `derived`: the claim is an `assist` whose evidence is `replicate` and names
|
||
`wai-upscale:sr2` or `wai-upscale:sr4`, whose one input is the entry's `object`, and
|
||
whose output, the evidence's size scaled by the derivation's factor, is the entry's size;
|
||
where the entry names an upscale record, the record's `object` and `derivation` are the
|
||
evidence's and its `upscaled` is the entry's `samples`;
|
||
- `asserted`: the claim is an `assist` whose evidence is `attest`, whose one input is the
|
||
entry's `object`;
|
||
- `synthesized`: the claim is a `generate`.
|
||
5. For `derived`, `made_by` is the evidence's prior, and the upscale record's prior where the
|
||
entry names one (`prior_mismatch`). For `asserted` and `synthesized`, a `made_by` that is not
|
||
`null` is one of the claim's models, and for `synthesized` it is not `null`
|
||
(`made_by_mismatch`).
|
||
6. Where the verifier holds the decoded samples of a `transmitted` entry's object and the entry
|
||
names no upscale record: their digest is the entry's `samples`
|
||
(`presented_samples_mismatch`).
|
||
7. Its `pixels` are §6.3's (`pixels_mismatch`).
|
||
|
||
Then the statement's totals (§6.3, `fractions_mismatch`).
|
||
|
||
### 7.3 What an accepted case states
|
||
|
||
- the synthesis statements of the claims: for each, in order, its link hash, class and, for an
|
||
assist claim, whether it is `proved`, `not-recomputed` or `asserted` (synthesis §11.3);
|
||
- for each upscale record, in order: its link hash, `proved` or `not-recomputed`, and, where the
|
||
output was recomputed and the target held, the largest difference of any sample of the output
|
||
from the target's, or `null`;
|
||
- for each presentation statement, in order: its link hash and its totals.
|
||
|
||
## 8. Reasons
|
||
|
||
The codes this extension adds, each with where it is raised:
|
||
|
||
| reason | raised at |
|
||
|---|---|
|
||
| `record_malformed` | §2, §4.2, §6.2, §7.2 step 1 |
|
||
| `bad_key` | §2 |
|
||
| `bad_signature` | §2 |
|
||
| `prior_invalid` | §3.1, §7.2 step 4.1 |
|
||
| `input_samples_mismatch` | §7.2 step 4.2 |
|
||
| `upscale_mismatch` | §7.2 step 4.3 |
|
||
| `residual_invalid` | §4.1, §7.2 step 4.4 |
|
||
| `output_mismatch` | §7.2 step 4.4 |
|
||
| `residual_short` | §4.2, §7.2 step 4.5 |
|
||
| `upscale_not_proved` | §7.2 step 4.6 |
|
||
| `claim_unknown` | §7.2 step 5.1 |
|
||
| `upscale_unknown` | §7.2 step 5.1 |
|
||
| `frame_subject_mismatch` | §7.2 step 5.2 |
|
||
| `made_understated` | §6.1, §7.2 step 5.3 |
|
||
| `made_mismatch` | §6.1, §7.2 step 5.4 |
|
||
| `prior_mismatch` | §3.5, §7.2 step 5.5 |
|
||
| `made_by_mismatch` | §6.2, §7.2 step 5.5 |
|
||
| `presented_samples_mismatch` | §7.2 step 5.6 |
|
||
| `pixels_mismatch` | §6.3, §7.2 step 5.7 |
|
||
| `fractions_mismatch` | §6.3 |
|
||
|
||
A verifier also raises every code synthesis raises over the claims (synthesis §12), at
|
||
`["synthesis", …]`: `assistive_recompute_mismatch` among them, for a sink's upscale whose claim
|
||
states an output its derivation does not give.
|
||
|
||
## 9. Conformance
|
||
|
||
[`live-conformance/upscale/`](../live-conformance/upscale/) holds the corpus: `vectors.json`,
|
||
written from fixed seeds by `wai_upscale_vectors gen`, the priors it reads in `priors/`, each
|
||
pinned by its SHA-256 in the generator, and `sha256.json`, the digest of every derivation's
|
||
output in the corpus. It has:
|
||
|
||
- **Accepted**: `sr2` of a picture under a prior trained on generated pictures, proved by
|
||
recomputation in its upscale record and in the sink's assist claim; `sr4` under a seeded prior;
|
||
a residual that brings the output to its target exactly, and one to a bound of 2; `sr2` under a
|
||
per-title prior; and a presentation statement over a span that holds a transmitted picture, a
|
||
derived one, an asserted float upscale and a frame generated between two others, with its
|
||
totals.
|
||
- **Refused**: each reason of §8 at least once, each a control of one defect: among them an
|
||
output that does not recompute (`upscale_mismatch`, and synthesis's
|
||
`assistive_recompute_mismatch`), a prior other than the one the claim names (`prior_mismatch`),
|
||
a residual that does not reach its target (`residual_short`), an upscaled picture claimed
|
||
captured and a generated picture claimed assistive (`made_understated`), and a statement whose
|
||
totals do not add up (`fractions_mismatch`).
|
||
|
||
A conforming verifier gives every vector the outcome, the reason, the place and the statements the
|
||
corpus states. `wai_upscale_vectors verify` and the test `tests/exact_upscale.rs` check that the
|
||
corpus regenerates byte for byte, that `wai-rs` gives every vector its outcome, and that §8 lists
|
||
exactly the reference's codes. `live-conformance/upscale_verify.py` is the second
|
||
implementation, written from this text: it shares no code with `wai-rs`; it runs the derivations
|
||
from §3.2 in integer arithmetic of its own, verifies the claims with the synthesis corpus's second
|
||
implementation (`synthesis_verify.py`), decodes residuals with the staged-delivery corpus's
|
||
(`staged_verify.py`), reads §8's codes from this text, and mutates copies of the corpus and
|
||
requires every copy to be refused.
|
||
|
||
## 10. Security and privacy considerations
|
||
|
||
- A derived picture is a function of the transmitted bytes and the prior, and nothing else: it
|
||
can be checked, and it can be no more faithful than they are. What the prior adds is what it
|
||
learned from the pictures it was trained on; a proved claim says the sink ran the derivation,
|
||
not that the detail it added was in the scene.
|
||
- A prior's bytes are fetched by digest from whoever serves them. A sink that holds a prior under
|
||
a digest has the bytes the origin pinned; it trusts no name, title or `id`.
|
||
- A residual's target is the origin's statement. A verifier that does not hold the target checks
|
||
only a bound of 0, against the target's digest; the bound of a larger one rests on the origin's
|
||
signature until a verifier holds the target.
|
||
- A presentation statement shows what the session's key reports. It is not evidence that a
|
||
person watched, and it names no viewer, no device and no account. Its digests name pictures,
|
||
which a party that holds the pictures can recognise.
|
||
- A sink can leave pictures out of its statement. A statement covers the entries it lists; a gap
|
||
in `at` or a span with fewer frames than the content's rate is visible to a verifier that knows
|
||
the rate.
|