wai merge train C: SYN-3, DRED exact, telemetry aggregation, gain maps, soft bindings, splat exact, hybrid post-quantum signatures (#425 #434 #429 #430 #433 #431 #435) #461

Merged
dcharlot merged 73 commits from train/wai-c into main 2026-10-25 23:50:23 -04:00
274 changed files with 63921 additions and 410 deletions

View file

@ -188,6 +188,39 @@ on:
- 'wai/extensions/co-watch.md'
# The co-watch step runs the browser client's co-watch module against the corpus.
- 'joule-code/joule-code-rs/crates/joule-moq-web/web/room/cowatch*'
# tests/dred_exact.rs requires this extension's §8 to list the codes the reference
# reports and its §4 to state the reference's digests, tests/dred_exact_measure.rs its §6
# table, dred_verify.py reads §4 and §8, and the registry's tests read SPEC §5 against it.
- 'wai/extensions/opus-dred.md'
# tests/telemetry_aggregate.rs requires this extension's §11 to list the codes the
# reference reports, telemetry_aggregate_verify.py reads that table, and the registry's
# wire identifiers test reads its sections.
- 'wai/extensions/telemetry-aggregation.md'
# tests/telemetry_aggregate.rs requires §3.4's table to class the keys the reference
# classes, and telemetry_aggregate_verify.py reads that table and §4.1 and §4.2's shards.
- 'wai/extensions/delivery-telemetry.md'
# tests/exact_tonemap.rs requires this extension's §9 to list the codes the reference
# reports and its §6 to state the corpus's measurement, tonemap_verify.py reads §3.3's
# table, §5.4's constant and §9, and the registry's wire identifiers test reads its
# sections.
- 'wai/extensions/exact-tonemap.md'
# tests/robustness.rs requires this extension's §12 to list the codes the reference
# reports and its §4 to register the reference's transforms, robustness_verify.py reads
# both, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/robustness-evidence.md'
# tests/splat_exact.rs requires this extension's §10 to list the codes the reference
# reports and the draft schema under extensions/gltf/ to name §3.2's members,
# splat_exact_verify.py reads §10, and the registry's wire identifiers test reads its
# sections.
- 'wai/extensions/splat-exact.md'
- 'wai/extensions/gltf/**'
# splat_exact_verify.py decodes each payload with this tool's whm1/1 lowering and
# interpreter.
- 'wai/tools/wai_ops_check.py'
# tests/pq_signatures.rs requires this extension's §8 to list the codes the reference
# reports, pq_verify.py reads that table, and the registry's wire identifiers test reads
# its §2.
- 'wai/extensions/pq-signatures.md'
- 'wai/wai-web/**'
# The audio provenance check below reads the corpora above with this tool.
- 'wai/tools/wai_audio_provenance_check.py'
@ -560,7 +593,7 @@ jobs:
working-directory: wai/wai-rs
run: |
set -euo pipefail
F=world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer,receipt_claims,key_discovery,video_int,audio_int,splat_int,staged,stage_measure,telemetry,http,video_manifest
F=world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer,receipt_claims,key_discovery,video_int,audio_int,splat_int,staged,stage_measure,telemetry,http,video_manifest,pq_signatures
v() { echo "::group::$1"; cargo run -q --no-default-features --features "$F" --bin "$2" -- verify "$3"; echo "::endgroup::"; }
v worlds wai_world_vectors ../world-conformance
v spatial-audio wai_audio_vectors ../audio-conformance
@ -583,6 +616,7 @@ jobs:
v http wai_http_vectors ../http-conformance
v staged-measure wai_stage_measure ../staged-measure-conformance
v telemetry wai_telemetry ../telemetry-conformance
v pq-signatures wai_pq_vectors ../pq-conformance
# The pin corpus's second implementation: Python standard library only, sharing no
# code with wai-rs. One leg is enough — it checks digests and listing rules, which
# do not depend on the architecture — and the macOS host has python3.
@ -629,7 +663,7 @@ jobs:
shell: pwsh
working-directory: wai/wai-rs
run: |
$F = "world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer,receipt_claims,key_discovery,video_int,audio_int,splat_int,staged,stage_measure,telemetry,http,video_manifest"
$F = "world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer,receipt_claims,key_discovery,video_int,audio_int,splat_int,staged,stage_measure,telemetry,http,video_manifest,pq_signatures"
function v($grp, $bin, $path) {
Write-Output "::group::$grp"
cargo run -q --no-default-features --features $F --bin $bin -- verify $path
@ -657,6 +691,7 @@ jobs:
v http wai_http_vectors ../http-conformance
v staged-measure wai_stage_measure ../staged-measure-conformance
v telemetry wai_telemetry ../telemetry-conformance
v pq-signatures wai_pq_vectors ../pq-conformance
# wai-quantum and the quantum corpus under wasm32-wasip2, run by wasmtime. On wasm32
# usize is 32 bits, so arithmetic that cannot overflow on a 64-bit host can there: a
@ -1169,6 +1204,33 @@ jobs:
(cd wai-rs && cargo test --no-default-features --features live_moderation --lib live_moderation::)
(cd wai-rs && cargo test --no-default-features --features live_moderation --test live_moderation)
python3 -I live-conformance/live_moderation_verify.py live-conformance/moderation
# wai.audio.opus.dred.int (extensions/opus-dred.md): first the draft's weights file and
# test vectors, which the corpus names by SHA-256 and does not hold, fetched from the
# draft's locations and checked against its digests (live-conformance/dred/fetch.sh).
# Then the reference module's unit tests (the range decoder against its encoder, the
# extension draft's worked examples, payloads round-trip, weights quantized from their
# bits, the activation tables, the driver on a synthetic set), tests/dred_exact.rs (the
# corpus regenerates byte for byte from its seeds and the weights and no other file is
# there, every payload and case reaches its outcome, §8 lists exactly the module's codes,
# §4 states its digests), and in release tests/dred_exact_measure.rs (every record of the
# draft's test vectors decoded through the profile and through the floating-point
# network: the profile passes the draft's feature test, and §6's table is what it
# measures). Then the corpus's second implementation, dred_verify.py, written from the
# extension's text and sharing no code with wai-rs, which recomputes every outcome,
# digest and row in its own integer arithmetic and requires every mutated copy of the
# corpus to fail; standard library only, run isolated (-I).
- name: opus deep redundancy · wai-rs and dred_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
d="${RUNNER_TEMP:-/tmp}/dred"
bash live-conformance/dred/fetch.sh "$d" vectors
w="$d/dred_unquantized_weights.bin"
(cd wai-rs && cargo test --no-default-features --features dred_exact --lib dred_exact::)
(cd wai-rs && WAI_DRED_WEIGHTS="$w" cargo test --release --no-default-features --features dred_exact --test dred_exact)
(cd wai-rs && WAI_DRED_WEIGHTS="$w" WAI_DRED_VECTORS="$d" cargo test --release --no-default-features --features dred_exact --test dred_exact_measure)
python3 -I live-conformance/dred_verify.py live-conformance/dred "$w"
# wai.live.ads (extensions/live-ads.md): the reference module's unit tests (policies and
# annotations round-trip and their rules refuse, a break's identity, tags, events and
# asset lists written exactly), the break form of wai.video.ssai's receipt (its JSON
@ -1255,20 +1317,23 @@ jobs:
(cd wai-rs && cargo test --no-default-features --features synthesis --lib synthesis::)
(cd wai-rs && cargo test --no-default-features --features synthesis --test synthesis)
python3 -I live-conformance/synthesis_verify.py live-conformance/synthesis
# The registered watermark scheme wai-mark:tent64 (extensions/synthesis.md §7.4 to §7.8):
# the reference's unit tests (the code corrects 29 errors and its generator is the
# definition's, the layout, the embedding and the detector in every orientation, the
# battery's resampling, rotation and keyframe), then tests/synthesis_mark.rs in release,
# since it embeds and attacks every picture of the measurement sets (every file of
# live-conformance/synthesis-mark/ regenerates byte for byte, the measurement among them,
# and no other file is there; every embedding, detection and case gets what it states;
# the extension's definition, generator polynomial and shuffle are the reference's;
# §7.5.8 claims only attacks the measurement shows survived, and §7.5.6's figures are the
# measurement's); then the second implementation, synthesis_mark_verify.py with
# The registered watermark schemes wai-mark:tent64 and wai-mark:tent64s
# (extensions/synthesis.md §7.4 to §7.9): the reference's unit tests (the code corrects 29
# errors and its generator is the definition's, the layouts, the embedding and the
# detector in every orientation, the tiled detector's exact autocorrelation and its
# recovery from a crop and a rotation, the battery's resampling, rotation and keyframe),
# then tests/synthesis_mark.rs in release, since it embeds and attacks every picture of
# the measurement sets under both schemes (every file of live-conformance/synthesis-mark/
# regenerates byte for byte, both measurements among them, and no other file is there;
# every embedding, detection and case gets what it states; the extension's definitions,
# generator polynomial and shuffles are the reference's; §7.5.8 and §7.9.7 claim only
# attacks the measurements show survived, and §7.5.6's and §7.9.5's figures are the
# measurements'); then the second implementation, synthesis_mark_verify.py with
# _wai_mark.py, written from the extension's text and sharing no code with wai-rs, which
# embeds, detects and decodes itself, runs the battery's picture attacks, verifies every
# case with synthesis_verify.py, mutates copies of the corpus and weakens its own verifier
# in turn; standard library only, run isolated (-I).
# embeds, detects and decodes itself, both stages of the tiled detector among them, runs
# the battery's picture attacks, derives the frames the vectors name, verifies every case
# with synthesis_verify.py, mutates copies of the corpus and weakens its own verifier in
# turn; standard library only, run isolated (-I).
- name: synthesis watermark · wai-rs and synthesis_mark_verify.py
working-directory: wai
shell: bash
@ -1300,6 +1365,29 @@ jobs:
(cd wai-rs && cargo test --no-default-features --features exact_upscale --lib exact_upscale::)
(cd wai-rs && cargo test --no-default-features --features exact_upscale --test exact_upscale)
python3 -I live-conformance/upscale_verify.py live-conformance/upscale
# Robustness evidence for soft bindings (extensions/robustness-evidence.md): the
# reference's unit tests (gamma is the rounded power, rates are exact and reduced, every
# attack of synthesis §7.5.7's battery is a transform that gives its bytes, parameters
# outside their ranges are refused), then tests/robustness.rs in release, since
# regenerating the corpus runs the harness over the measurement sets of synthesis §7.5.8
# (every file of live-conformance/robustness/ regenerates byte for byte and no other file
# is there; every case gets what it states; §12 lists exactly the reference's codes and
# the corpus refuses a case for each; §4 registers exactly the reference's transforms;
# the tent64 records' tables are the synthesis corpus's battery.json; the tent64 claim is
# synthesis §7.5.8's list; jwp-receipts §3.1 lists the span reasons); then the second
# implementation, robustness_verify.py with _wai_mark.py, written from the extension's
# text and sharing no code with wai-rs, which reruns the conformance record's battery end
# to end and requires the same table, checks the tent64 records against battery.json and
# the claim against synthesis §7.5.8, mutates copies of the corpus and weakens its own
# verifier in turn; standard library only, run isolated (-I).
- name: robustness evidence · wai-rs and robustness_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features robustness --lib robustness::)
(cd wai-rs && cargo test --release --no-default-features --features robustness --test robustness)
python3 -I live-conformance/robustness_verify.py live-conformance/robustness
# wai.ai.usage (extensions/ai-usage.md): the reference module's unit tests (RFC 9651's
# Dictionary parser against the vocabulary's examples and the RFC's edges, statements
# read and refused in their steps' order, the precedence rule, HTTP fields compared by
@ -1582,6 +1670,78 @@ jobs:
(cd wai-rs && cargo test --no-default-features --features co_watch --test co_watch)
python3 -I live-conformance/co_watch_verify.py live-conformance/cowatch
node --test ../joule-code/joule-code-rs/crates/joule-moq-web/web/room/cowatch.test.mjs
# wai.telemetry.aggregate (extensions/telemetry-aggregation.md): the reference module's unit
# tests (the fields against a wide-arithmetic-free product, the generators' orders,
# TurboSHAKE128 against RFC 9861, HPKE against RFC 9180 A.1.1, the FLP accepting a valid
# measurement and refusing an invalid one, delivery-telemetry's key classes) and
# tests/telemetry_aggregate.rs (vectors.json regenerates byte for byte from its fixed seeds and
# no other file is there, vdaf-22/ is the draft's test vectors as published and wai-rs passes
# every one, every receipt, cell and delivery-only report gets its stated outcome, every
# reason of §11 and every reused code refuses a vector, §11 lists exactly the reference's
# codes, delivery-telemetry §3.4 classes exactly the reference's keys); then the corpus's
# second implementation, telemetry_aggregate_verify.py, written from the extension's text and
# the drafts it cites and sharing no code with wai-rs, which evaluates Prio3 itself and passes
# the draft's vectors, opens every report with its own X25519, HKDF, AES-128-GCM and HPKE,
# re-runs every flow (both aggregators' verification, the aggregation job byte for byte, the
# batch buckets, every refusal, the collection), verifies every receipt and cell with WAI's
# strict Ed25519 rule from claim-conformance, reads the key classes and the reason table from
# the texts, requires every mutated copy of the corpus to fail, and drops each of its own
# checks in turn and requires the corpus to catch the weakened verifier; standard library
# only, run isolated (-I).
- name: QoE aggregation · wai-rs and telemetry_aggregate_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features telemetry_aggregate --lib -- telemetry_aggregate:: telemetry::)
(cd wai-rs && cargo test --no-default-features --features telemetry_aggregate --test telemetry_aggregate)
python3 -I live-conformance/telemetry_aggregate_verify.py live-conformance/aggregate
# wai.media.tonemap, wai.meta.gainmap and wai.meta.st2094_50 (extensions/exact-tonemap.md):
# the reference module's unit tests (the fixed-point log2 and exp2 at known points, the
# table of K against its rule, the sRGB table, tan through its series, PCHIP slopes of a
# line, rounding of halves for both signs) and the PNG reader's, then tests/exact_tonemap.rs
# (the committed corpus regenerates byte for byte, no other file is there, every case and
# envelope gets its stated outcome, §9 lists exactly the reference's codes, §6 states the
# corpus's measurement against binary64, and frames.rgb8 is the int_video clip's decode
# whose digests its sidecar publishes); then the corpus's second implementation,
# tonemap_verify.py, written from the extension's text and sharing no code with wai-rs,
# which computes both derivations in integer arithmetic of its own, reads PNG, envelopes
# (with staged_verify.py) and both companions itself, recomputes §6's measurement, verifies
# every record with WAI's strict Ed25519 rule and BLAKE3 from claim-conformance, requires
# every mutated copy of the corpus to fail, and drops each of its own checks in turn and
# requires the corpus to catch the weakened verifier; standard library only, run isolated
# (-I).
- name: exact tone mapping · wai-rs and tonemap_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features exact_tonemap --lib -- exact_tonemap:: png_still::)
(cd wai-rs && cargo test --no-default-features --features exact_tonemap --test exact_tonemap)
python3 -I live-conformance/tonemap_verify.py live-conformance/tonemap
# wai.splat.exact (extensions/splat-exact.md): the reference module's unit tests
# (exp_neg_q16 against the exponential, binary32 ranges rounded half up exactly, the
# signed integers' grammar, the identity set carrying every byte, and tiles that leave a
# frame unchanged) and tests/splat_exact.rs (live-conformance/splat/ regenerates byte for
# byte and no other file is there, every case gets its stated outcome, §10 lists exactly the
# reference's codes, the tiles leave every view of every scene unchanged, and the draft
# schema names §3.2's members); then the corpus's second implementation,
# splat_exact_verify.py, written from the extension's text and sharing no code with wai-rs:
# it reads each glTF asset, decodes each payload with int_payload_verify.py's parser and
# rANS decoder and tools/wai_ops_check.py's whm1/1 interpreter, renders every view with its
# own integer renderer, verifies every record with WAI's strict Ed25519 rule and BLAKE3
# from claim-conformance, reads the extension's reason table, requires every mutated copy
# of the corpus to fail, drops each of its own checks in turn and changes each rule of its
# renderer in turn, and requires the corpus to catch every one; standard library only, run
# isolated (-I).
- name: exact splats · wai-rs and splat_exact_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features splat_exact --lib splat_exact::)
(cd wai-rs && cargo test --no-default-features --features splat_exact --test splat_exact)
python3 -I live-conformance/splat_exact_verify.py live-conformance/splat
# wai.live.e2ee (extensions/confidentiality.md): the corpus's second implementation,
# e2ee_verify.py, written from the extension's text and the documents it reads and
# sharing no code with the reference (joule-moq's secure_objects and joule-moq-mls,
@ -1659,6 +1819,30 @@ jobs:
# delivered shuffled, withheld and walked back with rewritten links and forks; both
# require wai_jwp_vectors and jwp_verify.py to give every chain the same verdict. Two
# fixed seeds each, so a run is reproducible.
# Hybrid signatures (extensions/pq-signatures.md): the reference module's unit tests (its
# ML-DSA-65 against FIPS 204's ACVP vectors — keyGen, deterministic sigGen and sigVer —
# vendored in pq-conformance/acvp and pinned by SHA-256, and the composite against the
# draft's own vector, before anything is built on them), the synthesis reader's hybrid
# records, and tests/pq_signatures.rs (vectors.json regenerates byte for byte, every case
# reaches its verdict, §8 lists exactly the reference's codes, each given); then the
# corpus's second implementation, pq_verify.py, written from the extension's text and
# sharing no code with wai-rs, which verifies ML-DSA-65 from FIPS 204's text in pure
# Python (_mldsa.py), checks every ACVP verification vector and signature and the draft's
# vector, every case, the sizes §9 states and §8's table, requires every mutated case to be
# refused and the corpus to catch it with any one of its checks dropped; run isolated (-I).
# Last, the two give every case the same verdict.
- name: hybrid signatures · wai-rs and pq_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features pq_signatures --lib pq_sig::)
(cd wai-rs && cargo test --no-default-features --features synthesis,pq_signatures --lib synthesis::pq_tests)
(cd wai-rs && cargo test --no-default-features --features pq_signatures --test pq_signatures)
python3 -I pq-conformance/pq_verify.py pq-conformance
python3 -I pq-conformance/pq_verify.py verdicts pq-conformance/vectors.json > "$RUNNER_TEMP/pq-py.tsv"
(cd wai-rs && cargo run -q --no-default-features --features pq_signatures --bin wai_pq_vectors -- verdicts ../pq-conformance/vectors.json) > "$RUNNER_TEMP/pq-rs.tsv"
diff "$RUNNER_TEMP/pq-py.tsv" "$RUNNER_TEMP/pq-rs.tsv"
- name: claim_verify.py, differential.py, jwp_verify.py, chain_differential.py, chain_gap_differential.py, signer_verify.py
working-directory: wai
shell: bash

View file

@ -15,7 +15,8 @@ name: wai-ops-gpu integer operators on GPUs
# compiler. WAI_OPS_GPU_EXPECT declares the one adapter the host must offer, and
# WAI_OPS_GPU_REQUIRE makes an absent adapter a failure, never a skip; each step
# then requires the report lines with their counts, so a filtered or empty run
# fails too.
# fails too. The splat renderer's compositing (extensions/splat-exact.md) runs there
# too: every view of the splat corpus equal to the CPU's frame, and its mutants caught.
# - checks (`linux`, a container with no GPU): the crate and its tests build, the
# device tests print SKIPPED and pass, and the same tests under
# WAI_OPS_GPU_REQUIRE=1 fail: an absent adapter is not a pass. The browser module
@ -48,6 +49,15 @@ on:
- 'wai/wai-rs/src/exact_upscale/**'
- 'wai/wai-rs/tests/exact_upscale_gpu.rs'
- 'wai/live-conformance/upscale/priors/**'
- 'wai/wai-rs/src/dred_exact/**'
- 'wai/wai-rs/tests/dred_exact_gpu.rs'
- 'wai/live-conformance/dred/**'
# The splat renderer's compositing on the device (extensions/splat-exact.md), and the
# scenes it is held to.
- 'wai/wai-rs/src/splat_exact.rs'
- 'wai/wai-rs/src/splat_exact/**'
- 'wai/wai-rs/tests/splat_exact_gpu.rs'
- 'wai/live-conformance/splat/**'
- 'wai/wai-rs/tests/vectors/**'
- 'wai/int-payload-conformance/**'
- 'wai/neural-conformance/**'
@ -130,12 +140,16 @@ jobs:
- name: The browser module builds for wasm32-unknown-unknown
working-directory: wai/wai-ops-gpu/browser
run: cargo build --locked --release --target wasm32-unknown-unknown
- name: wai-rs builds with ops_gpu, and its GPU test target
- name: wai-rs builds with ops_gpu, and its GPU test targets
working-directory: wai/wai-rs
run: |
set -euo pipefail
cargo test --locked --no-default-features --features ops_gpu,video_int,audio_int,splat_int,world_int --test ops_gpu --no-run
cargo test --locked --no-default-features --features ops_gpu,exact_upscale --test exact_upscale_gpu --no-run
cargo test --locked --no-default-features --features splat_exact,ops_gpu --test splat_exact_gpu --no-run
- name: wai-rs builds the DRED profile's GPU test target
working-directory: wai/wai-rs
run: cargo test --locked --no-default-features --features dred_exact,ops_gpu --test dred_exact_gpu --no-run
- name: The bench tool builds
working-directory: wai/tools/ops-gpu-bench
run: cargo build --locked --release
@ -212,6 +226,42 @@ jobs:
grep -q '^test result: ok\. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out' "$log" || { echo "::error::the test did not run and pass"; exit 1; }
grep -qE "^exact-upscale gpu: key=gpu-metal-0 .* cases=[1-9][0-9]* .* cpu=0 .* differ=0 errors=0 equal$" "$rep" \
|| { echo "::error::no equal run on the GPU"; exit 1; }
# wai.audio.opus.dred.int (extensions/opus-dred.md §4.8): the corpus's payloads and its
# streams' reconstructions decoded with both graphs of dred-int/1 on the GPU at acc64, every graph also run on the
# interpreter and compared, and the decode's integers held to the CPU's. The weights file
# is fetched and checked against the draft's digest (live-conformance/dred/fetch.sh).
- name: The DRED profile, with its graphs on the GPU
shell: bash
run: |
set -euo pipefail
d="$RUNNER_TEMP/dred"
bash wai/live-conformance/dred/fetch.sh "$d"
log="$RUNNER_TEMP/dred-gpu.log"
rep="$RUNNER_TEMP/dred-gpu.report"
: > "$rep"
cd wai/wai-rs
WAI_OPS_GPU_REPORT="$rep" WAI_DRED_WEIGHTS="$d/dred_unquantized_weights.bin" \
nice -n 10 cargo test --locked --release --no-default-features --features dred_exact,ops_gpu \
--test dred_exact_gpu -- --nocapture 2>&1 | tee "$log"
grep -q '^test result: ok\. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out' "$log" || { echo "::error::the DRED GPU test did not run and pass"; exit 1; }
grep -qE "^dred-gpu: key=gpu-metal-0 payloads=[1-9][0-9]* streams=[1-9][0-9]* same=true graphs_on_gpu=[1-9][0-9]* .* on_cpu=0 compared=[1-9][0-9]* differed=0 errors=\[\]$" "$rep" \
|| { echo "::error::no equal DRED run on the GPU"; exit 1; }
# wai-splat-render:i1 (extensions/splat-exact.md §5.6-§5.7) with its compositing on the
# GPU: every canonical and own-pose view of every scene of live-conformance/splat/ equal to
# the CPU's frame byte for byte, and each edited kernel caught.
- name: The splat renderer's compositing on the GPU
shell: bash
working-directory: wai/wai-rs
run: |
set -euo pipefail
log="$RUNNER_TEMP/splat-gpu.log"
rep="$RUNNER_TEMP/splat-gpu.report"
: > "$rep"
WAI_OPS_GPU_REPORT="$rep" nice -n 10 cargo test --locked --release --no-default-features --features splat_exact,ops_gpu \
--test splat_exact_gpu -- --nocapture 2>&1 | tee "$log"
grep -q '^test result: ok\. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out' "$log" || { echo "::error::the splat GPU test did not run and pass"; exit 1; }
grep -qE '^splat-exact gpu: key=gpu-metal-0 views=[1-9][0-9]* differ=0 mutants_survived=0 ' "$rep" \
|| { echo "::error::no equal splat run on gpu-metal-0, or a mutant survived"; exit 1; }
- name: wasm-bindgen CLI 0.2.127, and the wasm32-unknown-unknown target
shell: bash
run: |

View file

@ -19,7 +19,8 @@
# Scope: the tracked files under wai/ with the extensions .md .rs .toml .py
# .sh .mjs .js .json .html .css .ttl .h .c .txt, and wai/'s .gitignore files;
# or, when files are given as arguments, those files (the self-test,
# scripts/test-public-text-checks.sh, uses this). Excluded:
# scripts/test-public-text-checks.sh, uses this), each a path relative to the
# directory the script is run from, or absolute. Excluded:
# - the settled OER/2 documents and corpus (wai/extensions/oer-receipts.md,
# wai/wai-rs/src/oer.rs, wai/oer-conformance/), which no change may edit.
#
@ -32,12 +33,16 @@
# function, not the owner.
#
# Exit status: 0 clean; 1 a hit; 2 WAI_NAME_DENYLIST unset or empty, a pattern
# grep cannot compile, or any other grep error. The check never reads an error
# grep cannot compile, a file given that is not a readable regular file (each
# such file is named), or any other grep error. The check never reads an error
# as "clean".
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# The files given as arguments are paths from the caller's directory: remember it
# before moving to the repository's root, where the default scope is listed.
CALLER_DIR="$(pwd)"
cd "$REPO_ROOT"
if [ -z "${WAI_NAME_DENYLIST:-}" ]; then
@ -67,7 +72,12 @@ fi
files=()
if [ $# -gt 0 ]; then
files=("$@")
for f in "$@"; do
case "$f" in
/*) files+=("$f") ;;
*) files+=("$CALLER_DIR/$f") ;;
esac
done
else
while IFS= read -r f; do
case "$f" in
@ -83,6 +93,20 @@ if [ ${#files[@]} -eq 0 ]; then
exit 2
fi
# A file grep cannot read makes it exit 2 with the whole list unchecked; name each
# such file instead of reporting a bare grep failure. File names are not private.
unreadable=0
for f in "${files[@]}"; do
if [ ! -f "$f" ] || [ ! -r "$f" ]; then
echo "::error::not a readable file: $f" >&2
unreadable=$((unreadable + 1))
fi
done
if [ $unreadable -gt 0 ]; then
echo "::error::$unreadable of ${#files[@]} files given cannot be read; nothing was checked" >&2
exit 2
fi
set +e
grep -HnE -f "$patterns" -- "${files[@]}" > "$out" 2>/dev/null
rc=$?

View file

@ -23,6 +23,18 @@ tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
failures=0
in_dir() { # in_dir <dir> <command...>: run a command from another directory
local d="$1"
shift
(cd "$d" && "$@")
}
names_file() { # names_file <file> <command...>: the command exits 2 and its output names <file>
local f="$1"
shift
"$@" >"$tmp/named" 2>&1
local got=$?
[ "$got" -eq 2 ] && grep -qF "$f" "$tmp/named"
}
expect() { # expect <status> <label> <command...>
local want="$1" label="$2"
shift 2
@ -52,6 +64,17 @@ expect 0 "names: a clean file is clean" env WAI_NAME_DENYLIST="$list" bash "$nam
expect 2 "names: a malformed pattern fails closed" env WAI_NAME_DENYLIST="$(printf 'Zyxwvut\n([unclosed')" bash "$names" "$tmp/clean.md"
expect 2 "names: an unset list fails closed" env -u WAI_NAME_DENYLIST bash "$names" "$tmp/clean.md"
expect 2 "names: a missing file fails closed" env WAI_NAME_DENYLIST="$list" bash "$names" "$tmp/no-such-file.md"
mkdir -p "$tmp/sub"
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30; do
printf 'Clean line %s.\n' "$i" > "$tmp/sub/clean-$i.md"
done
many=()
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30; do many+=("sub/clean-$i.md"); done
expect 1 "names: a path relative to the caller's directory is read from there" in_dir "$tmp" env WAI_NAME_DENYLIST="$list" bash "$names" bare.md
expect 0 "names: many clean files given relative to the caller's directory are clean" in_dir "$tmp" env WAI_NAME_DENYLIST="$list" bash "$names" "${many[@]}"
expect 1 "names: a hit among many relative paths is a hit" in_dir "$tmp" env WAI_NAME_DENYLIST="$list" bash "$names" "${many[@]}" bare.md
expect 0 "names: a missing file among many fails closed and is named" names_file "gone.md" in_dir "$tmp" env WAI_NAME_DENYLIST="$list" bash "$names" "${many[@]}" sub/gone.md
expect 0 "names: a directory given as a file fails closed and is named" names_file "/sub" in_dir "$tmp" env WAI_NAME_DENYLIST="$list" bash "$names" "${many[@]}" sub
printf 'Its reproducibility is the superiority claim.\n' > "$tmp/superiority.md"
printf 'About 8 kbps, well below Xcodec at the same quality.\n' > "$tmp/well-below.md"

3
wai/.gitattributes vendored
View file

@ -7,3 +7,6 @@ REGISTRY.md -text
*.wih1 -text
*.wia1 -text
*.wis1 -text
# The splat corpus (extensions/splat-exact.md §11): glTF assets, their buffers and their
# commitments, regenerated and compared byte for byte, so never converted.
live-conformance/splat/** -text

View file

@ -6,6 +6,279 @@ wire format may change and such changes are recorded here.
## v0.4.0 — current
### Hybrid signatures: receipts that stay verifiable after Ed25519 can be forged
- **One suite** ([pq-signatures](extensions/pq-signatures.md) §2): ML-DSA-65 (FIPS 204) beside
Ed25519, as the composite `id-MLDSA65-Ed25519-SHA512` of
`draft-ietf-lamps-pq-composite-sigs-19`. Both halves sign the composite's message
representative of the record's own signed bytes, the ML-DSA half with the suite's label as its
context, so the Ed25519 half of a hybrid record verifies over no classical record's bytes and
stripping the post-quantum half leaves nothing that verifies (§4.3). ML-DSA-65 rather than -44
for the margin of security category 3 over the decades a provenance or delivery record is asked
to prove something.
- **Where it goes** (§6): a key-log entry may hold an ML-DSA key and a revision a hybrid root,
committed to before it signs by `BLAKE3("wai:key-set-next\x02" ‖ K ‖ P)`; a group receipt is
signed over the labelled payload's third version, `moq-jwp:group-sign\x03`, with the key in
its payload and both signatures in its canonical bytes and link hash, its objects unchanged; a
claim, and every JSON record signed as `wai:<domain>\x01 ‖ JCS`, carries `pq_suite`, `pq_key`
and `pq_sig`, read and checked by one shared rule (wired into synthesis's records).
- **Policy and downgrade** (§5, §6.1): a verifier may require hybrid (`hybrid_required`); at
confirmation, a classical-only item under a hybrid entry is refused (`hybrid_downgrade`), an
item whose ML-DSA key is not its entry's is refused (`pq_key_mismatch`), and under a pinned
anchor that requires hybrid only hybrid-signed revisions descend from it and a classical item
is unconfirmed. A bad post-quantum half is `pq_signature_invalid`.
- **Measured** (§9): a hybrid group receipt is 5552 bytes against 291, the 5261 bytes of the key
and signature paid once per group and never per object, 42 kbit/s on a receipts track at one
group a second; hybrid verification takes 114–128 µs against Ed25519's 34–35 µs.
- **Checked**: the ML-DSA-65 implementation against FIPS 204's ACVP vectors (keyGen, deterministic
sigGen and sigVer, vendored in `pq-conformance/acvp/` and pinned by SHA-256) and the composite
against the draft's own vector, before anything else; a corpus of 46 cases,
`pq-conformance/vectors.json` (`wai_pq_vectors`), and its second implementation,
`pq_verify.py`, which verifies ML-DSA from FIPS 204's text in pure Python. Classical publishers'
bytes and every existing corpus are unchanged; the reference reads the hybrid forms under the
feature `pq_signatures`, whose one new dependency is a pure-Rust ML-DSA implementation.
### `wai.splat.exact`: Gaussian splats in glTF as an exact WAI object, and frames that are the same everywhere
- **Carriage** ([splat-exact](extensions/splat-exact.md) §3): a `wai.splat.int_codec` object travels
in a glTF 2.0 asset as the draft compression extension `EXT_gaussian_splatting_compression_wai`,
nested in a mesh primitive's `KHR_gaussian_splatting` object. A buffer view holds the object's
`WAI1` envelope; the extension states its content hash and its parameter set (carried in the
asset, or held by digest) and, in another buffer view, the origin's commitment as its JCS text.
The primitive's five accessors carry no data, so both extensions are required, and `POSITION`'s
`min` and `max` are the decode's own. The draft JSON Schema is
`extensions/gltf/EXT_gaussian_splatting_compression_wai.schema.json`. WAI submits nothing to the
glTF registry; the extension name is registered here as a proposed wire identifier, of a new
kind, `gltf-extension`.
- **Attributes** (§4): the 14 planes of `wai.splat.int_codec` dequantized at 2^16 from the
payload's binary32 ranges, rounded half up exactly, and their mapping onto the base extension's
`POSITION`, `ROTATION`, `SCALE`, `OPACITY` and `SH_DEGREE_0_COEF_0`.
- **The renderer `wai-splat-render:i1`** (§5): a fixed-point camera and projection (the elliptical
weighted average model, its 0.3 px² low pass and 1.3× Jacobian clamp), culling with stated
rules, an order by squared camera distance with the index breaking every tie, per-pixel alpha
compositing with every rounding stated (`exp_neg_q16` of integer-operators §2, the 3σ cut-off,
alpha within 1/255 and 0.99, a stop below 0.0001), and 16 × 16 tiles whose order does not change
the frame. Every value compositing reads fits 32 bits, and only `e1` and `e2` need 64.
- **Commitment and view statement** (§6, §7): the origin signs the object, its set, its attribute
digest and the frame digest at each canonical pose; a sink signs, under a session key, the frame
it presented at a pose, canonical or its own.
- **Provenance** (§8): a view is a `convert` of the splat set under synthesis §3.2, so its class
is the greater of `reconstructed` and the splat set's. Synthesis origin claims may now name
`media` `volumetric` ([synthesis](extensions/synthesis.md) §3.1).
- **Quality cost, measured** (§12): against a floating-point renderer of the same model in `f64`,
59.4 to 67.2 dB PSNR on the corpus's views, no byte off by more than 4; the same float renderer
in `f32` gives other bytes than in `f64` on some views at the corpus's sizes and on nearly all
at four times the side.
- **Reference and corpus**: the `splat_exact` module of `wai-rs` (feature `splat_exact`), the
bins `wai_splat_exact_vectors gen|verify` and `wai_splat_exact_measure`, and the corpus
`live-conformance/splat/`: the learned cloud of `tests/vectors/int_splat/`, two authored scenes
carried through a one-layer identity set, and refused cases for every code of §10, among them a
reordered sort, a frame that does not recompute, a commitment over other splats and a pose
outside the pinned set claimed canonical. Its second implementation,
`live-conformance/splat_exact_verify.py`, decodes with the repository's other second
implementations, renders with its own integer renderer, and catches every mutated corpus copy,
every dropped check and every changed renderer rule.
- **On a GPU**: `wai-ops-gpu` gains the compositing kernel `wgsl/splat.wgsl`; `splat_exact::gpu`
(features `splat_exact`, `ops_gpu`) gives the CPU's frame on every view of the corpus on Metal,
and its test catches three edited kernels. `wai-ops-gpu.yml` runs it on the `macos` runner.
### `wai.media.robustness`: robustness evidence anyone recomputes, claims held to it, and soft bindings over a span of a track
- **Span bindings** ([jwp-receipts](extensions/jwp-receipts.md) §2.6.4): a claim of class
`soft-binding-span` declares a soft-binding value computed over a span of one track: its
media time in milliseconds, both ends included, and, where the publisher states them, the
groups or the objects that carry it. Its subject is the span's first object, the anchor. It
maps onto a block of a C2PA soft-binding assertion whose scope is a `timespan` (C2PA 2.4
§18.10); a whole-object binding is the block with the empty scope. A recovery through a span
needs a verified delivery receipt within the span and attests the span — not which part of it
the object in hand came from, nothing outside it, and, for a span of media time alone, no
object but the anchor; a receipt outside it is `recovery_outside_span`. A recovery record may
name a span declaration. New reasons `span_malformed` and `span_inverted` (step 4) and
`recovery_outside_span` (step 6). `soft-binding` claims are unchanged, and every existing
claim vector is byte-identical; the span vectors are appended to `claim-conformance/`, and
`claim_verify.py` and `differential.py` read the class.
- **Robustness records** ([robustness-evidence](extensions/robustness-evidence.md)): a corpus
document names pictures or clips by the SHA-256 of their samples, and itself by the SHA-256 of
its JCS. An attack battery is a list of registered transforms (`wai-attack:*`), each an integer
function of the frames, its exact parameters and a seed: synthesis §7.5.7's battery with its
parameters free, and a gamma computed in integers. A signed record names the algorithm by term
and definition digest, the corpus, the battery and the harness (`wai-robustness-harness:1`),
and per attack the counts — items that survived out of the corpus, items read as another
value, negatives read as marked — with survival, false-positive and balanced-accuracy rates and
the true-positive rate at 1% false positives as exact fractions in lowest terms, never
floating point (`rate_not_exact`). A verifier holding the corpus reruns the battery and the
detector and gets the table bit for bit (`table_irreproducible`); one that does not states the
record.
- **Claims held to their evidence.** A robustness claim lists the attacks an algorithm claims
to survive, by media, transform and parameters, and cites records; it holds only where a cited
record shows every corpus item survived the attack and no negative read as marked
(`claim_unevidenced`, `claim_exceeds_evidence`), and, under a policy that asks, only over
reproduced records (`evidence_not_reproduced`).
- **`wai-mark:tent64`'s own evidence.** Records over the `spectral`, `leaves` and `clips`
measurement sets with synthesis §7.5.7's battery, whose tables equal the synthesis corpus's
`battery.json`, and a claim that is exactly synthesis §7.5.8's list and holds over them.
- **The proposed `robustnessEvidence` object** (*Robustness Evidence for C2PA Soft-Binding
Algorithms*, pinned by digest) is mapped field for field, informatively (§11).
- `wai-rs` module `robustness` (feature `robustness`), `wai_robustness_vectors`, the corpus
`live-conformance/robustness/` (a conformance record over three pictures the corpus holds, the
tent64 records and claim, and a case refused for each reason), and `robustness_verify.py`, the
second implementation, which reruns the conformance battery end to end with `_wai_mark.py` and
requires the same table. Registry: `wai.media.robustness` (record), the document kinds
`wai-robustness`, `wai-robustness-claim` and `wai-robustness-corpus`, and the schemes
`wai-attack:` and `wai-robustness-harness:1`.
### Exact tone mapping: `wai.meta.gainmap`, `wai.meta.st2094_50` and `wai.media.tonemap`
- **Two companions** ([SPEC](SPEC.md) §5, §7.1): `wai.meta.gainmap` carries an ISO 21496-1:2025
gain map (its binary metadata as written, and its gain map image as a PNG of 8-bit samples, in
a `WGM1` frame) as a companion of an image payload; `wai.meta.st2094_50` carries SMPTE ST
2094-50:2026-08 (Application #5) metadata sets in their Annex C encoding, each with the frames
it applies to, in a `WD50` frame, as a companion of a video payload. Rule 2 of §7.1 gains the
`image` media class for the gain map. Both are classified `patent-pool` (royalty status not
established) and `standard-unclassified`. ISO 21496-1 was not read: its text is sold; what the
extension states of it is what ST 2094-50 says of it and what public readers of its binary
metadata implement, marked where it is used.
- **An exact rendition at a display's headroom** ([exact-tonemap](extensions/exact-tonemap.md)
§3 to §5): `wai-tonemap:gainmap` and `wai-tonemap:st2094-50` compute the rendition from the
base's `RGB8` samples, the companion and a headroom (an integer in 1/10000 of a stop) with a
fixed-point `log2` (16 bits of fraction, bitwise from below) and `exp2` (sixteen Q30
constants made by integer square roots), an sRGB table, and one rounding rule; the gain map's
upsampling is a pinned centre-aligned bilinear; ST 2094-50's slopes come from a Q62 series for
`tan` or from PCHIP on exact rationals; every step maps onto a formula of the standard. The
rendition is `RGB16`, linear light relative to the display's peak, so every sink at a headroom
presents the same bytes. Against a binary64 evaluation of the same formulas, over the corpus,
the largest difference is 2 code values of 65535 for each derivation (§6).
- **The rendition record** (§7, §8): a sink signs, for the renditions it presented, the base, the
companion, each headroom and each rendition's digest; a verifier holding the envelope, and the
frames for a video, recomputes them. A rendition is a `convert` of synthesis's lattice: its
class is the greatest of `reconstructed` and its inputs'.
- **Corpus** `live-conformance/tonemap/`, from generated HDR scenes rendered by the reference's own
integer encoder and the `int_video` clip; its second implementation, `tonemap_verify.py`, agrees
on every case. `png_still` reads and writes 8-bit greyscale; `staged_verify.py` knows the two
companions' base classes.
### `wai.telemetry.aggregate`: quality of experience the service receives only as sums
- **Measures, aggregated under DAP** ([telemetry-aggregation](extensions/telemetry-aggregation.md)
§3 to §5): a sink casts each session's metrics (delivery-telemetry §7.2) as four measures, the
start outcomes and the durations (Prio3SumVec), the stalls (Prio3Sum) and the video start time
(Prio3Histogram), and reports each through the Distributed Aggregation Protocol of
`draft-ietf-ppm-dap-20`: secret-shared between a leader and a helper aggregator, each share
encrypted to its aggregator with HPKE. The aggregators check each measurement's range proof
(`draft-irtf-cfrg-vdaf-22`) without either seeing it, refuse an out-of-range one
(`vdaf_verify_error`), and neither learns a measurement as long as one of them follows the
protocol. Leader and helper are roles any party can run.
- **The task binds who aggregates.** A task's `task_info` names its measure, its scope (zero, or a
room id), a salt and the keys of the two aggregators and the collector; it enters the
authenticated data of every input share, so a report is bound at upload. The task id is SHA-256
over the configuration. A task's minimum batch size is at least fifty, delivery-telemetry §8.4's
floor, and each aggregator refuses to release a share of a smaller batch (`invalidBatchSize`):
the floor is enforced by the aggregators, not by the service's restraint.
- **Signed aggregates.** Each aggregator signs a statement of its aggregate share with the batch's
task, collection, interval, report count and checksum (`WQS1`), sealed to the collector; the
collector's aggregate receipt (`WQA1`) carries the task, both statements and the result. A reader
recomputes the result from the two shares and refuses a receipt with one aggregator, a batch below
the minimum, statements that disagree, or a batch whose reports were uploaded to another task
(§6 to §8; the reasons are §11's).
- **Where aggregation replaces suppression** (§9): for a figure a measure aggregates, the published
figure is the receipt's; delivery-telemetry §8.4 still applies to Request-mode reports, to
Event-mode reports consumed as they arrive, and to figures no measure aggregates. A room's
quality-of-experience cell ([live-metering](extensions/live-metering.md) §4.7, §6.5) is computed
from its `outcomes`, `stalls` and `durations` receipts, and equals the cell its logs give.
- **Key classes** ([delivery-telemetry](extensions/delivery-telemetry.md) §3.4, §4.3): every CMCD key
the mapping writes is `delivery` (what the serving host needs to serve the request) or
`measurement` (what is only aggregated afterwards), each with what it reveals and to whom; a
delivery-only Request mode carries the delivery class alone, and a reader refuses a
delivery-only report with any other key (`measurement_key_in_delivery`). §8.1 now states facts
and sets no consent requirement for the service's own mechanics; a lawful basis, where a regime
asks for one, is a `lawful-basis` claim (jwp-receipts §2.4.6).
- **Reference implementation** (`wai-rs`, feature `telemetry_aggregate`): Prio3Count, Prio3Sum,
Prio3SumVec and Prio3Histogram written from the VDAF draft (the fields, TurboSHAKE128 and its XOF,
the FLP in the Lagrange basis) and passing the draft's published test vectors, vendored under
`live-conformance/aggregate/vdaf-22/`; HPKE base mode (RFC 9180 A.1.1); DAP-20's messages and a
reference client, leader, helper and collector; the receipt verifier and the cell. New
dependencies, behind the feature: `keccak`, `aes-gcm`, `hkdf` (RustCrypto).
- **Corpus** `live-conformance/aggregate/` (`wai_telemetry_aggregate_vectors gen`), with an
independent verifier, `telemetry_aggregate_verify.py`, that evaluates Prio3, HPKE and DAP itself
and re-runs every flow from its reports byte for byte.
### `wai.audio.opus.dred` and `wai.audio.opus.dred.int`: Opus deep redundancy, decoded exactly
- **Registered** ([opus-dred](extensions/opus-dred.md), SPEC §5): the deep redundancy (DRED) of
draft-ietf-mlcodec-opus-dred-07, a neural latent of the recent speech carried in an Opus
packet's padding, from which a receiver rebuilds the features of lost packets. Both strings are
companion-only enhancement layers over `wai.audio.opus.packet`, carried embedded in the packet's
padding or as a `WAI2` companion; not refinements, since DRED corrects nothing the base decoded
and is read only where the base is missing (§2.2). `wai.audio.opus.dred` is the draft's decoding
within its §4.1 tolerances (`StandardTolerance`); `wai.audio.opus.dred.int` is the integer profile
(`NeuralIntegerExact`, one-file parameter set, `ops` lowering `dred-int/1`). Both `patent-pool`,
conservatively, while the royalty-free intent of the draft's IPR disclosure is conditional. The
working group's other documents are placed (§2.3): the extension format and the speech coding
enhancement register nothing, the scalable quality extension rides embedded in the base.
- **The integer profile `dred-int/1`** (§3–§4): DRED found in a packet (RFC 6716's framing, the
extension draft's iterator with its repeat mechanism), the payload's integers (RFC 6716's range
decoder, with a magnitude cap that bounds crafted payloads), and the draft's own decoder network
from its own weights file, pinned by SHA-256 and never committed, lowered to two `wai-ops/1`
graphs: weights at `2^24` from their float32 bits, activations at `2^15`, `tanh` and the sigmoid as
`lut16` tables of a stated integer computation, every layer a `conv`, `mul`, `add` or `rescale`
with its rounding stated. Both graphs meet `acc64` and use only `wai-ops/1-i32` operators.
- **Measured** (§6), on the draft's test vectors: the profile passes the draft's feature test
against its reference features on every vector, and lies at `total` 0.0021 (largest difference
0.0084) from the network in floating point. The reference features are not the network's: two
builds of the draft's reference decoder on one host give features about 0.13 apart, neither the
test vectors'.
- **A stream under loss** (§5): a seeded loss pattern, the slots each recovering packet's DRED
rebuilds, a reconstruction buffer and its digest, and the record a verifier checks
(`weights_digest_mismatch`, `loss_pattern_mismatch`, `reconstruction_mismatch`).
- **Receipts** (§7): a reconstruction from DRED is a `convert`; concealment beyond it a `generate`;
speech coding enhancement an `assist`. A player presents a reconstruction in synthesis's log, its
`output` the run's digest at `decode-equivalence` (`present_output_irreproducible` when it does
not recompute).
- **Reference and corpus**: the `dred_exact` module of wai-rs (feature `dred_exact`), the corpus
`live-conformance/dred/` (payloads, streams, cases, negative controls for every code: another
weights file, a loss list that is not the pattern, a moved row, a flipped digest, a
floating-point decode claimed and presented as exact, a broken log signature), its second
implementation `dred_verify.py`, the measurement test, and a GPU test that holds the device's
integers to the CPU's. The profile as a proposal to the working group is drafted, not filed, in
`proposals/dred-integer-profile.md`.
### `wai-mark:tent64s`: the second marking layer found again after crops, rotations and captures of a screen
- **The scheme** ([synthesis](extensions/synthesis.md) §7.9), a second registered term beside
`wai-mark:tent64`: the same tent pattern, code, amplitudes and margin, on a tiled layout. The
64 × 64 grid is cut into 2 × 2 tiles of 32 × 32 cells, each holding the same layout, so a bit
keeps 16 cells, four in every tile, and the mark repeats with half the frame's width and height.
The embedding is §7.5.4's under that layout, integer and recomputed by a verifier as `tent64`'s
is; nothing is added for synchronisation. A new term rather than a revision: the same frames and
payload give other marked frames, and a `tent64` marking commits to its own by digest.
- **Detection in two stages, integer throughout.** Stage 1 reads the grid in place, in the 8
quarter turns and mirrors. Stage 2, where stage 1 reads nothing: the exact autocorrelation of a
sign plane matched to the cell pattern; eight lattice candidates, each a pair of vectors at
right angles scored over four lattice points and refined to 1/64 of a sample; each folded onto
one tile, the cells' phase taken where the tiles agree most; the orientation and the tile's
offset where the four cells of every bit agree most; at most four words decoded. The
false-positive bound counts all 12 decodes, 2^−60.80, and is checked against the words both
stages read from unmarked pictures.
- **Measured.** The battery adds a crop of 25%, crops of 2%, 5%, 10% and 25% from each side, a
rotation of 5° and two simulated captures of a screen (a resampling, a small rotation, a
display's curve and noise). Both generated sets survive every attack of the table, resampling to
1/3 among them; the claims are what the photographs survived as well, among them every attack
`tent64` claims, crops of 1% to 5%, crops of 2% to 10% from the left, rotations of 0.5°, 1° and 5°
and one capture of a screen. One photograph of dense texture is not read in 14 of the crops and
rotations, nor another in the second capture, and those are not claimed. PSNR, SSIM and the floor
are `tent64`'s to within 0.4 dB and 0.002.
- **Verification**: §7.6 recomputes and reruns a marking or a detection of either registered
scheme; the C2PA statement, the signpost and the resolver of §7.7 serve both.
- **Reference and corpus**: `synthesis::mark::sync`; its files sit in
[`live-conformance/synthesis-mark/`](live-conformance/synthesis-mark/) beside `tent64`'s and share
its frames, and a vector names a crop, a rotation or a capture of stored frames, which every
implementation derives, rather than storing it. `synthesis_mark_verify.py` runs both stages
with an autocorrelation and a fold of its own and agrees with the reference on every vector,
stage 2's lattice, phase, offset and agreement among them.
- **`scripts/check-public-names.sh`** reads file arguments from the caller's directory, where it
read them from the repository's root, and names any argument it cannot read rather than exiting 2
on the whole list; its self-test covers both.
### `wai.live.coperformance`: a relay counts audience inputs in their chain's order
- **The rule** ([co-performance](extensions/co-performance.md) §7.3): a relay counts an

View file

@ -64,10 +64,11 @@ they serve ([jwp-receipts](extensions/jwp-receipts.md) §7),
[live-rooms](extensions/live-rooms.md), [capture-binding](extensions/capture-binding.md),
[live-compose](extensions/live-compose.md), [live-recording](extensions/live-recording.md),
[timed-text](extensions/timed-text.md), [ai-usage](extensions/ai-usage.md),
[exploration](extensions/exploration.md) and [browser-sink](extensions/browser-sink.md) put on
the wire outside a manifest — magic numbers, a media type, `codecs` prefixes, paths, playlist tags and
attributes, document kinds, catalog fields, MOQT Setup Options, HTTP fields and a member of a
decoded frame's metadata — each with its kind, the section that
[exploration](extensions/exploration.md), [browser-sink](extensions/browser-sink.md),
[robustness-evidence](extensions/robustness-evidence.md) and [splat-exact](extensions/splat-exact.md)
put on the wire outside a manifest — magic numbers, a media type, `codecs` prefixes, paths,
playlist tags and attributes, document kinds, catalog fields, MOQT Setup Options, HTTP fields, a
member of a decoded frame's metadata and glTF extension names — each with its kind, the section that
defines it, and whether it is defined, provisional (test material only until
registered) or proposed (not registered). A library test checks that each is written
in the section it names.
@ -170,6 +171,8 @@ and a role are fixed once registered.
| `wai.audio.ivas` | payload | registered | audio | standalone | patent-pool | standard-tolerance | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.audio.mpegh` | payload | registered | audio | standalone | patent-pool | standard-unclassified | — | §5 Broadcast and streaming codecs |
| `wai.audio.opus` | payload | registered | audio | standalone | royalty-free | standard-tolerance | recommended | §5 Recommended modern set |
| `wai.audio.opus.dred` | companion | registered | audio | enhancement | patent-pool | standard-tolerance | — | §5 Broadcast and streaming codecs |
| `wai.audio.opus.dred.int` | companion | registered | audio | enhancement | patent-pool | neural-int-exact | — | §5 Broadcast and streaming codecs |
| `wai.audio.opus.packet` | payload | registered | audio | standalone | royalty-free | standard-tolerance | — | §5 Broadcast and streaming codecs |
| `wai.audio.scene` | payload | registered | audio | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
| `wai.audio.score` | payload | registered | audio | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
@ -219,13 +222,17 @@ and a role are fixed once registered.
| `wai.media.direction` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.media.exploration` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.media.influence` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.media.robustness` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.media.synthesis` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.media.takedown` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.media.tonemap` | record | registered | — | — | — | — | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.media.upscale` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.mesh.draco` | payload | registered | volumetric | standalone | royalty-free | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.mesh.glb` | payload | registered | volumetric | standalone | royalty-free | standard-unclassified | — | §5 Interactive, temporal & computed content |
| `wai.meta.dovi` | companion | registered | metadata | companion | proprietary | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.meta.gainmap` | companion | registered | metadata | companion | patent-pool | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.meta.hdr10plus` | companion | registered | metadata | companion | royalty-free | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.meta.st2094_50` | companion | registered | metadata | companion | patent-pool | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.neural.bmshj2018` | payload | registered | image | standalone | royalty-free | neural-float | — | §5 Neural capabilities |
| `wai.neural.cmic` | payload | registered | image | standalone | royalty-free | neural-float | — | §5 Neural capabilities |
| `wai.neural.dac` | payload | registered | audio | standalone | royalty-free | neural-float | — | §5 Neural capabilities |
@ -255,10 +262,12 @@ and a role are fixed once registered.
| `wai.semantic.clip` | payload | registered | image | standalone | royalty-free | behavioral | — | §5 Neural capabilities |
| `wai.semantic.perco2` | payload | registered | image | standalone | non-commercial | behavioral | — | §5 Neural capabilities |
| `wai.splat.4d` | payload | registered | volumetric | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
| `wai.splat.exact` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.splat.int_codec` | payload | registered | volumetric | standalone | royalty-free | neural-int-exact | — | §5 Interactive, temporal & computed content |
| `wai.splat.int_refine` | refinement | registered | volumetric | refinement | royalty-free | standard-defined | — | §5 Refinement capabilities (staged delivery) |
| `wai.splat.sog` | payload | candidate | volumetric | standalone | patent-pool | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.splat.spz` | payload | registered | volumetric | standalone | royalty-free | standard-unclassified | — | §5 Interactive, temporal & computed content |
| `wai.telemetry.aggregate` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.tensor.nnc` | payload | candidate | binary | standalone | patent-pool | standard-unclassified | — | §5 Prior artifacts, general tensors and derivation operations |
| `wai.ternary.tt` | payload | registered | binary | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
| `wai.text.timed` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
@ -316,6 +325,7 @@ and a role are fixed once registered.
| `/.well-known/wai-key-status` | well-known | defined | http-delivery §8.4 |
| `/.well-known/wai-keys` | well-known | defined | jwp-receipts §7.1 |
| `/.well-known/wai-mark/` | well-known | proposed | synthesis §7.7 |
| `EXT_gaussian_splatting_compression_wai` | gltf-extension | proposed | splat-exact §3.2 |
| `GRANT_CHALLENGE` | setup-option | proposed | live-rooms §10.5.2 |
| `GRANT_PROOF` | setup-option | proposed | live-rooms §10.5.2 |
| `SECURE_OBJECT_KEY_ID` | catalog | defined | confidentiality §4.3 |
@ -335,9 +345,11 @@ and a role are fixed once registered.
| `WCL1` | magic | defined | live-recording §5.1 |
| `WCN1` | magic | defined | capture-binding §8.1 |
| `WCR1` | magic | defined | live-compose §8.1 |
| `WD50` | magic | defined | exact-tonemap §5.1 |
| `WDA1` | magic | defined | settlement §3.1 |
| `WEP1` | magic | defined | live-events §5 |
| `WEV1` | magic | defined | live-events §3.1 |
| `WGM1` | magic | defined | exact-tonemap §4.1 |
| `WHP1` | magic | defined | http-delivery §6.2 |
| `WJR1` | magic | defined | jwp-receipts §2.7.3 |
| `WMH1` | magic | defined | live-metering §3.1 |
@ -356,6 +368,8 @@ and a role are fixed once registered.
| `WPS1` | magic | defined | co-performance §7.7 |
| `WPT1` | magic | defined | co-performance §6.1 |
| `WPW1` | magic | defined | co-performance §7.2 |
| `WQA1` | magic | defined | telemetry-aggregation §7.1 |
| `WQS1` | magic | defined | telemetry-aggregation §6.1 |
| `WRD1` | magic | defined | live-rooms §3.1 |
| `WRE1` | magic | defined | confidentiality §3.1 |
| `WRG1` | magic | defined | live-rooms §4.1 |
@ -380,6 +394,7 @@ and a role are fixed once registered.
| `X-WAI-FLOOR` | playlist-attribute | defined | http-delivery §11.1 |
| `application/wai` | media-type | proposed | http-delivery §3 |
| `contentBinding` | frame-metadata | proposed | browser-sink §7.1 |
| `id-MLDSA65-Ed25519-SHA512` | scheme | defined | pq-signatures §2 |
| `mr/` | path | defined | http-delivery §8.6 |
| `rcpt/` | path | defined | http-delivery §8.1 |
| `science.transaction.wai.class` | data-id | defined | packaging §8 |
@ -401,6 +416,7 @@ and a role are fixed once registered.
| `wai-age-admissions` | document-kind | defined | age-assurance §7.1 |
| `wai-age-policy` | document-kind | defined | age-assurance §4.1 |
| `wai-archive` | document-kind | defined | exploration §5.3 |
| `wai-attack:` | scheme | defined | robustness-evidence §4 |
| `wai-attribution` | document-kind | defined | influence §5.3 |
| `wai-authorship-map` | document-kind | defined | contribution §7.3 |
| `wai-c2pa` | catalog | defined | live-provenance §10.2 |
@ -422,6 +438,7 @@ and a role are fixed once registered.
| `wai-label-policy` | document-kind | defined | synthesis §10.1 |
| `wai-mark:conformance` | scheme | defined | synthesis §7.4 |
| `wai-mark:tent64` | scheme | defined | synthesis §7.4 |
| `wai-mark:tent64s` | scheme | defined | synthesis §7.4 |
| `wai-marking` | document-kind | defined | synthesis §7.2 |
| `wai-membership` | document-kind | defined | contribution §3.2 |
| `wai-module-grant` | document-kind | defined | jwp-receipts §7.9 |
@ -435,10 +452,17 @@ and a role are fixed once registered.
| `wai-receipt-index` | document-kind | defined | http-delivery §8.2 |
| `wai-receipts` | catalog | defined | moq-streaming-format §4.1 |
| `wai-review` | document-kind | defined | synthesis §9.1 |
| `wai-robustness` | document-kind | defined | robustness-evidence §5 |
| `wai-robustness-claim` | document-kind | defined | robustness-evidence §8 |
| `wai-robustness-corpus` | document-kind | defined | robustness-evidence §3 |
| `wai-robustness-harness:1` | scheme | defined | robustness-evidence §6 |
| `wai-sequence` | document-kind | defined | direction §6 |
| `wai-session` | document-kind | defined | contribution §3.1 |
| `wai-signing` | document-kind | defined | access-services §6.1 |
| `wai-signing-review` | document-kind | defined | access-services §6.4 |
| `wai-splat-commitment` | document-kind | defined | splat-exact §6.1 |
| `wai-splat-render:i1` | scheme | defined | splat-exact §5 |
| `wai-splat-view` | document-kind | defined | splat-exact §7 |
| `wai-step` | document-kind | defined | contribution §4.1 |
| `wai-storyboard` | document-kind | defined | direction §4 |
| `wai-takedown` | document-kind | defined | takedown §5.3 |
@ -450,6 +474,7 @@ and a role are fixed once registered.
| `wai-takedown-purge` | document-kind | defined | takedown §5.5 |
| `wai-taste` | document-kind | defined | exploration §8.1 |
| `wai-terms` | document-kind | defined | influence §3.2 |
| `wai-tonemap` | document-kind | defined | exact-tonemap §7.1 |
| `wai-upscale` | document-kind | defined | exact-upscale §4.2 |
| `wai1` | codecs-prefix | defined | http-delivery §4.1 |
| `wai1` | fourcc | provisional | http-delivery Appendix B |

View file

@ -1206,8 +1206,12 @@ names, and a payload a conversion carries agrees with the conversion's claim by
attack battery of integer attacks (re-encoding with the crate's own codecs, rescaling, crops,
rotations, noise, brightness, contrast, a local blur) measures what it survives, and it claims no
more: no crop and no small rotation. The marking's C2PA statement and the mark itself are the
signposts to the detection solution, and a well-known path resolves the scheme's definition. A
room's AI participant,
signposts to the detection solution, and a well-known path resolves the scheme's definition.
A second registered watermark, `wai-mark:tent64s`, lays the same mark out in four tiles that each
hold the whole layout, embedded and recomputed alike; its detector, integer throughout, finds the
tile lattice again from the mark's own period and reads it after crops from every side, small
rotations and a simulated capture of a screen, with a false-positive bound of 2^−60.80 over all
its decodes, and the battery measures what it claims. A room's AI participant,
marked in its grant, states its machine origin in its chat, reactions and captions, and labels
every track it publishes. A review signed over one exact reconstruction is presented only by a
player whose decode path holds the review's tier and whose output is that reconstruction, so one
@ -1436,6 +1440,74 @@ A taste prior is an integer ranking model over the descriptors, a one-file param
aesthetic or reward model steered names it by digest or states `none`; a policy may require the
disclosure of every pick, a pick from an archive a prior steered names that prior, and no default
objective exists: [`extensions/exploration.md`](extensions/exploration.md).
And for **quality of experience the service receives only as sums** — `wai.telemetry.aggregate`:
a sink reports each session's measures, the session metrics of delivery telemetry cast as Prio3
measurements (`draft-irtf-cfrg-vdaf-22`: Prio3SumVec for the start outcomes and the durations,
Prio3Sum for the stalls, Prio3Histogram for the video start time), through the Distributed
Aggregation Protocol (`draft-ietf-ppm-dap-20`): each measurement is secret-shared between a leader
and a helper aggregator and each share encrypted to its aggregator, the two check its range proof
without either seeing it and refuse an out-of-range one, and neither learns a measurement as long
as one of them follows the protocol. A task's `task_info` names its measure, its scope (a room id
for a room's) and the keys of its two aggregators and its collector, so every report is bound at
upload to who aggregates it; a task's minimum batch size is at least fifty, and each aggregator
refuses to release a share of a smaller batch. Each aggregator signs a statement of its aggregate
share with the batch's task, count and checksum, `WQS1`; the collector's aggregate receipt, `WQA1`,
carries the task, both statements and the result, and a reader recomputes the result and refuses a
receipt with one aggregator, a batch below the minimum, statements that disagree, or a batch whose
reports were uploaded to another task. A room's quality-of-experience cell is computed from its
tasks' receipts. Delivery telemetry classes every CMCD key it writes as `delivery` or
`measurement`, with what each reveals, and a delivery-only Request mode carries the delivery
class alone: [`extensions/telemetry-aggregation.md`](extensions/telemetry-aggregation.md).
And for **robustness evidence** — what a soft binding survives, measured so anyone recomputes it —
`wai.media.robustness`: a corpus document names pictures or clips each by the SHA-256 of its
samples, and itself by the SHA-256 of its JCS; an attack battery is a list of registered transforms,
each an integer function of the frames with exact parameters and a seed (the battery of synthesis
§7.5.7 with its parameters free, and a gamma computed in integers); and a robustness record, signed
by the party that measured, names the algorithm by term and definition digest, the corpus, the
battery, the harness, and per attack the items that survived out of the corpus and the negatives
read as marked, with the survival, false-positive and balanced-accuracy rates and the true-positive
rate at 1% false positives as exact fractions in lowest terms, never floating point
(`rate_not_exact`). A verifier that holds the corpus reruns the battery and the detector and gets
the table bit for bit (`table_irreproducible` otherwise); one that does not states the record. A
robustness claim — what an algorithm claims to survive — holds only where a record it cites shows
every item of its corpus survived the attack and no negative read as marked; a claim with no record
(`claim_unevidenced`) or above one (`claim_exceeds_evidence`) is refused. `wai-mark:tent64` carries
records over its measurement sets and a claim that is exactly synthesis §7.5.8's list. A soft
binding may also cover a span of a track, its media time and the groups or objects that carry it,
a recovery through which attests the span and nothing outside it (jwp-receipts §2.6.4):
[`extensions/robustness-evidence.md`](extensions/robustness-evidence.md).
And for **Gaussian splats in glTF**, and frames that are the same everywhere — `wai.splat.exact`:
a `wai.splat.int_codec` object travels in a glTF 2.0 asset (ISO/IEC 12113:2022) as the draft
compression extension `EXT_gaussian_splatting_compression_wai`, nested in a mesh primitive's
`KHR_gaussian_splatting` object: a buffer view holds the object's `WAI1` envelope, and the
extension states its content hash and its parameter set, which the asset carries or a sink holds
by digest. The decode is integer, so the attribute planes are the same bytes on every machine, and
they map onto the base extension's attributes. The renderer `wai-splat-render:i1` is integer too:
a fixed-point camera and projection, an order by squared camera distance with the Gaussian's index
breaking ties, alpha compositing with every rounding stated, a 3σ cut-off, and 16 × 16 tiles whose
order does not change the frame. The origin signs a commitment to the object, its set, the digest
of its decoded attributes and the digest of the frame at each of its canonical poses, so a viewer
recomputes what the scene looks like from each of them bit for bit; a sink signs a view statement
for a frame it presented at a pose, under a session key. A view is a conversion of the splat set
under synthesis's class lattice, so it is never labelled lower than the splat set. Against a
floating-point renderer of the same model, the integer frames differ by a few levels of a byte,
at about 60 dB PSNR and above on the corpus's scenes:
[`extensions/splat-exact.md`](extensions/splat-exact.md).
And for **signatures that stay verifiable after Ed25519 can be forged** — hybrid signatures: a
record carries an ML-DSA-65 signature (FIPS 204) beside its Ed25519 one, the two combined as
the composite `id-MLDSA65-Ed25519-SHA512` of `draft-ietf-lamps-pq-composite-sigs-19`, so it
verifies only while both hold and stands on either. A group receipt is signed over the labelled
payload's third version, `moq-jwp:group-sign\x03`, which carries the publisher's ML-DSA key; a
claim, and every JSON record an extension signs as `wai:<domain>\x01 ‖ JCS`, carries `pq_suite`,
`pq_key` and `pq_sig`, checked by one shared rule. A key log lists an entry's ML-DSA key and may
have a hybrid root, committed to before it signs; a relying party may pin an anchor that
requires hybrid, under which only hybrid-signed revisions count. A verifier may require hybrid of
every item (`hybrid_required`), and refuses a classical-only item signed by a key its origin
lists as hybrid (`hybrid_downgrade`), so stripping the post-quantum half never yields a valid
classical record. A classical publisher's bytes are unchanged:
[`extensions/pq-signatures.md`](extensions/pq-signatures.md).
### Payloads of the WAI-native integer codecs
@ -1547,7 +1619,26 @@ named standard's canonical bytes.
| cinema mastering | `wai.image.jp2` · `wai.video.j2k` (JPEG 2000 / DCP, OpenJPEG) |
| volumetric / 3D | `wai.mesh.draco` (royalty-free) · `wai.pc.gpcc` (G-PCC, ISO/IEC 23090-9) · `wai.pc.vpcc` (V-PCC, ISO/IEC 23090-5) — MPEG point clouds · `wai.splat.sog` (Gaussian-splat compression; a **candidate**, no payload format pinned — *Candidate capabilities*, below) |
| haptics | `wai.haptic.mihs` (MPEG-I Haptics, ISO/IEC 23090-31; its 23090-33 ships bit-exact conformance vectors) |
| HDR dynamic metadata | `wai.meta.hdr10plus` (SMPTE ST 2094-40 dynamic metadata, royalty-free) · `wai.meta.dovi` (SMPTE ST 2094-10 dynamic metadata, proprietary) — **companion descriptors** to a video payload, not standalone media |
| HDR dynamic metadata | `wai.meta.hdr10plus` (SMPTE ST 2094-40 dynamic metadata, royalty-free) · `wai.meta.dovi` (SMPTE ST 2094-10 dynamic metadata, proprietary) · `wai.meta.st2094_50` (SMPTE ST 2094-50:2026-08 dynamic metadata, Application #5, patent-pool) — **companion descriptors** to a video payload, not standalone media |
| HDR gain maps | `wai.meta.gainmap` (an ISO 21496-1:2025 gain map: its metadata and its gain map image, patent-pool) — a **companion** to an image payload, not standalone media |
**HDR renditions at a display's headroom.** The payload of `wai.meta.gainmap` is a `WGM1`
frame: ISO 21496-1:2025's binary metadata as written, and the gain map image as a PNG of 8-bit
samples, one channel or three. The payload of `wai.meta.st2094_50` is a `WD50` frame: one or
more metadata sets in the binary encoding of SMPTE ST 2094-50:2026-08 Annex C, each with the
frames of its base it applies to. A sink makes from the base, the companion and its display's
headroom the rendition it presents. The standards state that computation in real numbers, and
two sinks that evaluate it in their own floating point present different pixels; the
derivations `wai-tonemap:gainmap` and `wai-tonemap:st2094-50` pin it in integer arithmetic (a
fixed-point `log2` and `exp2`, an sRGB table, one rounding rule), so every sink at a headroom,
an integer in units of 1/10000 of a stop, presents the same `RGB16` bytes, and a verifier
recomputes them. A rendition is a `convert` of its inputs under the synthesis extension's
lattice: it rebuilds what the base and the companion hold and generates nothing. And for the
**renditions a sink presents** — `wai.media.tonemap`: a rendition record names the base, the
companion, each headroom and the digest of each rendition, and a verifier holding the envelope
recomputes them:
[`extensions/exact-tonemap.md`](extensions/exact-tonemap.md). ISO 21496-1:2025 was not read for
this registration; what the extension states of it is marked there.
**Point clouds: what the two registrations name.** `wai.pc.gpcc` names G-PCC,
ISO/IEC 23090-9, and `wai.pc.vpcc` names V-PCC, ISO/IEC 23090-5; each payload is
@ -1633,6 +1724,8 @@ revision MAY add a base, which widens the capability (§8).
| `wai.audio.int_refine` | `wai.audio.int_codec`, `wai.audio.flac` |
| `wai.splat.int_refine` | `wai.splat.int_codec` |
| `wai.video.lcevc` | `wai.video.avc`, `wai.video.hevc`, `wai.video.vvc`, `wai.video.evc`, `wai.video.evc.baseline`, `wai.video.vp9`, `wai.video.av1`, `wai.video.av1.lossless` (*Enhancement layers (LCEVC)*, below) |
| `wai.audio.opus.dred` | `wai.audio.opus.packet` (*Opus deep redundancy*, below) |
| `wai.audio.opus.dred.int` | `wai.audio.opus.packet` (*Opus deep redundancy*, below) |
A refinement is admitted over a base when its `refines.base` names an envelope that
a sink decoded through one of these capabilities. The reference implementation
@ -1668,6 +1761,8 @@ re-frame it.
| `wai.audio.avs3` | AVS3 audio / Audio Vivid — AVS3-P3, T/AI 109.3-2023; GY/T 363-2023; GB/T 46271-2025 | AVS3-P3 elementary bitstream | SEP-pool |
| `wai.audio.aac` | AAC-LC, HE-AAC, HE-AAC v2 — ISO/IEC 14496-3 | ADTS stream (ISO/IEC 13818-7 / 14496-3); Extended HE-AAC is not this capability | SEP-pool |
| `wai.audio.opus.packet` | Opus — RFC 6716 | one Opus packet (RFC 6716 §3), its TOC byte first, with no container (*One Opus packet*, below) | royalty-free |
| `wai.audio.opus.dred` | Opus deep redundancy (DRED) — draft-ietf-mlcodec-opus-dred-07 | one DRED extension payload (draft §3), for the Opus packet it accompanies — **companion-only**, an enhancement layer (*Opus deep redundancy*, below) | patent-pool |
| `wai.audio.opus.dred.int` | DRED through its integer profile `dred-int/1` ([opus-dred](extensions/opus-dred.md)) | as `wai.audio.opus.dred` — **companion-only**, an enhancement layer (*Opus deep redundancy*, below) | patent-pool |
*SEP-pool* means the standard's essential patents are licensed for royalties —
through patent pools, a single standard-essential-patent licensor, or FRAND
@ -1715,6 +1810,28 @@ string. Like every entry of the table it is sink-supplied: the reference
implementation's native sink decodes `wai.audio.opus` and does not advertise
the packet form.
**Opus deep redundancy.** draft-ietf-mlcodec-opus-dred-07 carries, in an Opus packet's padding,
a compact neural latent of the speech before the packet, from which a receiver rebuilds the
acoustic features of packets that were lost. Its payload means nothing without the encode it was
made with, so both strings are companion-only **enhancement layers**, bound by the rule of
*Enhancement layers (LCEVC)* (below) to exactly one selectable rendition of their one base,
`wai.audio.opus.packet`,
where the envelope aligns the DRED payload with its packet. As LCEVC, DRED is carried embedded
(the extension in the base packet's padding, under the base capability, with no DRED component)
or separately (a `WAI2` companion whose payload is one DRED extension payload for frame 0 of the
packet in the same envelope). `wai.audio.opus.dred` is the draft's decoding, held to the draft's
conformance test, which admits features within its thresholds of the reference; it is
`StandardTolerance` (§7). `wai.audio.opus.dred.int` is the same decoding through the integer
profile of [opus-dred](extensions/opus-dred.md): the draft's network and its weights file, pinned
by SHA-256 as the capability's one-file parameter set, lowered to `wai-ops/1` graphs
([integer-operators](extensions/integer-operators.md)) whose feature sequence is the same
integers on every conforming sink; it is `NeuralIntegerExact`, its decoded output the feature
sequence (the draft leaves the vocoder to the implementation), and its `ops` member names the
lowering `dred-int/1`. Both are classed `patent-pool` until the royalty status the draft's IPR
disclosure states becomes established. Like every entry of the table they are sink-supplied: the
native sink advertises neither, and the reference implementation's `dred_exact` module (feature
`dred_exact`) is the reference for the integer profile's feature decode.
**Dispatch.** These dispatch exactly as §4 describes. Because none is a floor or
recommended capability, no sink can be assumed to hold one: an encoder
addressing sinks it does not control SHOULD ship such a payload in a `WAI2`
@ -1780,11 +1897,13 @@ unit stream without start code prefixes (for example with each NAL unit
preceded by its length) is not a `wai.video.lcevc` payload; carrying that form
would need its own capability string (§8).
**Companion-only capabilities.** `wai.video.lcevc` and the HDR dynamic-metadata
descriptors `wai.meta.hdr10plus` and `wai.meta.dovi` are **companion-only**:
their payload means nothing without the base it accompanies. An HDR descriptor
applies to a rendition whose payload is video (§7.1, rule 2), `wai.video.lcevc`
to one rendition of one of its base codecs (above). Every other registered
**Companion-only capabilities.** `wai.video.lcevc`, `wai.audio.opus.dred`,
`wai.audio.opus.dred.int` and the HDR dynamic-metadata descriptors
`wai.meta.hdr10plus` and `wai.meta.dovi` are **companion-only**: their payload
means nothing without the base it accompanies. An HDR descriptor applies to a
rendition whose payload is video (§7.1, rule 2), `wai.video.lcevc` to one
rendition of one of its base codecs (above), and the two DRED strings to one
`wai.audio.opus.packet` rendition (*Opus deep redundancy*, above). Every other registered
capability is **standalone media** and is never carried as a companion (§7.1).
A companion-only
capability MUST NOT be a v1.0 `capability` (a `WAI1` carries one payload, so
@ -2118,15 +2237,17 @@ registry as `codecs::capability_replicate_class(cap) -> ReplicateClass`:
synthesis all integer; `wai.neural.int_mlicpp` is the channel-autoregressive ×
checkerboard entropy model on integer networks, so the σ it re-derives before
each of its `2·K` passes is integer too; `wai.video.int_hyper`,
`wai.audio.int_codec` and `wai.splat.int_codec` are integer throughout as well.)
`wai.audio.int_codec` and `wai.splat.int_codec` are integer throughout as well;
`wai.audio.opus.dred.int` is the DRED feature decoder of
[opus-dred](extensions/opus-dred.md), whose decoded output is the feature sequence.)
A capability of this class whose networks decode through the integer operator set
names it in the registry, in its `ops` member
([integer-operators](extensions/integer-operators.md) §11): the lowering its sets
are lowered by, the profile every conforming set's certificate meets, and the modes
of its stage operators. A set whose certificate does not meet that profile is
refused. In this revision: `wai.neural.int_synth`, `wai.splat.int_codec`,
`wai.audio.int_codec`, `wai.neural.int_hyper`, `wai.video.int_hyper` and
`wai.neural.int_mlicpp`.
`wai.audio.int_codec`, `wai.neural.int_hyper`, `wai.video.int_hyper`,
`wai.neural.int_mlicpp` and `wai.audio.opus.dred.int`.
- **`NeuralEntropyExact`** — the entropy decode is integer by construction, so
the decoded symbols are byte-identical on every machine; later stages run float.
Registered at `entropy-consistency`. An encoder MUST NOT emit `intent =
@ -2226,6 +2347,7 @@ cited are the ones read; the evidence, and what was not read, is in
| | `wai.video.avc`, `wai.video.hevc`, `wai.video.vvc` | every sample of every cropped decoded picture a conforming decoder outputs equals the value the specified decoding process produces (ITU-T H.264 (V16, 06/2026) §C.4; H.265 (V11, 01/2026) §C.5.1; H.266 (V4, 01/2026) §C.5.1); processing an SEI message only signals, such as film grain synthesis, is outside that decoding process |
| | `wai.video.vp9` | output frames "identical in all respects", in the same order, to those of the specified decoding process (VP9 Bitstream & Decoding Process Specification v0.6 §8.1) |
| `StandardTolerance` | `wai.audio.opus`, `wai.audio.opus.packet` | output within `opus_compare`'s thresholds of the reference decoder, with the same final range-decoder state (RFC 6716 §6) |
| | `wai.audio.opus.dred` | decoded features within the draft's thresholds of its reference features (draft-ietf-mlcodec-opus-dred-07 §4.1: `total ≤ 0.5`, `max ≤ 0.15`, `pitch ≤ 0.02`); the vocoder that renders them is not normative (§4.2 there) |
| | `wai.image.jpeg` | decoding "with appropriate accuracy", the accuracy of dequantisation and IDCT specified in Part 2 (ITU-T T.81 §7, A.3.3); Part 2 (ITU-T T.83) was not read, so the bound is not stated here |
| | `wai.image.jxl` | decoded samples within per-test peak-error and RMSE thresholds of reference images (ISO/IEC 18181-3 §4.1–§4.3) |
| | `wai.image.jp2`, `wai.video.j2k` | decoded components compared with reference components by error metrics, and a reversible path its definitions describe as lossless (ISO/IEC 15444-4); only the table of contents and terms of its public preview were read, so the metrics and thresholds are not stated here |
@ -2476,6 +2598,13 @@ every conforming verifier accepts the same signatures.
OER/2 is the one exception: oer-receipts §5 settles its chain signature, which refuses
a key by steps 1 and 2 and checks `R` as RFC 8032 does.
A record **MAY** carry a second, post-quantum signature beside its Ed25519 one
([pq-signatures](extensions/pq-signatures.md)): ML-DSA-65 (FIPS 204) under the composite
`id-MLDSA65-Ed25519-SHA512`. Its Ed25519 half is verified by the rule above, over the
composite's message representative rather than over the record's bytes (pq-signatures §4.2), and
its ML-DSA half by FIPS 204 Algorithm 3; the record verifies only if both do. A record without
one is verified by the rule above alone, as before.
### Machine-checked totality (informative)
The cross-architecture matrix establishes byte-exactness by **sampling**: it
@ -2697,9 +2826,12 @@ selectable alternative of the same content — the default above).
instead of it**, naming the capability it binds to in `companion_of`. It
carries the payloads that are not standalone media — the capabilities §5
registers as **companion-only**: the HDR dynamic-metadata descriptors
`wai.meta.hdr10plus` / `wai.meta.dovi` (SMPTE ST 2094), which describe a video
payload, and the enhancement layer `wai.video.lcevc`, which adds residuals to
one. Carried as companions, the companion and its base ride in the **same
`wai.meta.hdr10plus` / `wai.meta.dovi` / `wai.meta.st2094_50` (SMPTE ST 2094),
which describe a video payload; the HDR gain map `wai.meta.gainmap` (ISO 21496-1),
which describes an image payload; the enhancement layer `wai.video.lcevc`, which
adds residuals to a video one; and the enhancement layers `wai.audio.opus.dred` and
`wai.audio.opus.dred.int`, which carry the redundancy that rebuilds the speech of one
Opus packet's lost predecessors. Carried as companions, the companion and its base ride in the **same
envelope**, so the binding is intrinsic — not a spoofable sidecar. This
revision registers no capability for immersive-audio mix metadata;
`wai.audio.iamf` carries its own audio substreams, so it is standalone media
@ -2733,11 +2865,18 @@ A component with `role = "companion"` conforms only if:
(§5, *Video:*), and the films `wai.film.linear` and `wai.film.reel`
([linear-film](extensions/linear-film.md) gives a linear film's `media` the
value `"video"`, and a reel is a film with cuts). A capability registered as
video in a later revision joins that class.
`wai.video.lcevc` applies to one of the base codecs §5 lists for it. No
companion applies to a companion-only capability. This revision constrains
video in a later revision joins that class. `wai.meta.st2094_50` is such a
descriptor. The gain map `wai.meta.gainmap`, registered as a companion to an
image payload, applies to a registered capability whose payload is an image:
the `image` media class (§3), as the capability's registration places it (the
registry's `media` column, [REGISTRY](REGISTRY.md)), every `wai.image.*`
capability that is not refinement-only, the neural and generative image codecs
and the semantic paths, which regenerate an image.
`wai.video.lcevc` applies to one of the base codecs §5 lists for it, and
`wai.audio.opus.dred` and `wai.audio.opus.dred.int` to `wai.audio.opus.packet`
(§5, *Base admission*). No companion applies to a companion-only capability. This revision constrains
no base for a companion whose capability it does not register, nor an HDR
descriptor's base whose capability it does not register;
descriptor's or a gain map's base whose capability it does not register;
3. a selectable rendition of that capability is present in the envelope — for
an **enhancement layer**, exactly one, the base encode its residuals were
produced against, and that rendition is the base of no other enhancement
@ -2846,8 +2985,11 @@ rules were stated:
- **a registration.** `wai.meta.hdr10plus` and `wai.meta.dovi` were registered
as companion descriptors to a video payload, not standalone media.
`wai.video.lcevc` was registered companion-only, with its base codecs, in the
same revision as these rules. Every other registered capability is standalone
media.
same revision as these rules. `wai.meta.st2094_50`, a descriptor of a video
payload, `wai.meta.gainmap`, a companion of an image payload, and the
enhancement layers `wai.audio.opus.dred` and `wai.audio.opus.dred.int`, each bound
to one `wai.audio.opus.packet` rendition, were registered companion-only after
these rules, under them. Every other registered capability is standalone media.
- **the definition of a companion.** When this section introduced
`role = "companion"`, it defined a companion as a component applied with the
chosen rendition and naming, in `companion_of`, the component it binds to.

View file

@ -2,7 +2,7 @@
Conformance for [typed receipt classes and the soft binding class](../extensions/jwp-receipts.md)
(§2.4.3–§2.4.12, §2.6, §3.1–§3.2): `claim` receipts of class `energy`,
`lawful-basis`, `log-inclusion`, `soft-binding`, `binding-recovery`, `measurement`,
`lawful-basis`, `log-inclusion`, `soft-binding`, `soft-binding-span`, `binding-recovery`, `measurement`,
`operating-point`, `stage`, `delivery-gap` and `reconstruct-session`, and recovery
through a soft binding under the ancestor rule.
@ -60,6 +60,16 @@ object in hand's `observed_hash` (or `null`). Both procedures report
`recover_signer_mismatch` and `binding_recovery_declaration_not_publishers` are the same
defect, in a recovery performed and in one recorded.
**Span bindings** (§2.6.4). A `soft-binding-span` declaration is context, for a recovery
(`recover`) and for a recovery record (`claim`), together with `receipt`, the delivery
receipt the verifier verified for an object of the span, given as it holds it:
`{signer, track_alias, group_id, object_id, content_hash}`, in place of `publisher`. A
`recover` vector with `receipt` runs §3.2 through a span and reports the anchor, the
declaration's subject, as the ancestor it names the span by; without `receipt` it runs the
whole-object procedure, under which a span declaration is `context_mismatch`, as it is for a
recovery record given a span declaration and a key alone. The span vectors are appended after
every other vector, which are unchanged.
Everything is synthetic. Keys are Ed25519 from fixed seeds (0x11 publisher, 0x22 meter,
0x33 operator, 0x44 sink, 0x55 resolver, 0x66 relay) and attest nothing; outputs,
parameter sets and envelope payloads are synthetic bytes; figures, uncertainties and

View file

@ -176,7 +176,7 @@ def parse_strict(text):
ENVELOPE = ["kind", "class", "subject_type", "subject", "seq", "issued_at", "body",
"signer_pubkey", "signer_id", "parent_receipt_hash", "sig"]
ADMITS = {"energy": {"object"}, "lawful-basis": {"object", "receipt"}, "log-inclusion": {"receipt"},
"soft-binding": {"object"}, "binding-recovery": {"object"},
"soft-binding": {"object"}, "soft-binding-span": {"object"}, "binding-recovery": {"object"},
"measurement": {"object", "receipt"}, "operating-point": {"object", "receipt"},
"stage": {"object"}, "delivery-gap": {"object"}, "reconstruct-session": {"object"},
"consumption": {"object"}, "transmission": {"receipt"}, "reconciliation": {"receipt"}}
@ -187,6 +187,8 @@ BODY = {
"energy_calibration_ref", "coverage", "grade", "method", "work_units", "work_unit", "oer_receipt"],
"log-inclusion": ["log", "profile", "entry", "log_receipt"],
"soft-binding": ["alg", "registry", "binding_type", "value", "resolution_endpoint"],
# §2.6.4: §2.6.2's members and the span.
"soft-binding-span": ["alg", "registry", "binding_type", "value", "resolution_endpoint", "span"],
"binding-recovery": ["alg", "binding_type", "value", "declaration", "resolution_endpoint", "observed", "attests"],
"measurement": FIGURE + ["bracket", "build", "power_reader"],
"operating-point": FIGURE + ["vocabulary", "op_requested", "op_committed", "op_delivered", "prediction"],
@ -357,6 +359,9 @@ def is_oer_id(s):
return isinstance(s, str) and re.fullmatch(r"(sha256|blake3):[0-9a-f]{64}", s) is not None
SPAN = ["track_alias", "start_ms", "end_ms", "first_group", "last_group", "first_object", "last_object"]
def members(obj, required, step):
if any(k not in obj for k in required):
raise Reject(step, "missing_required_field")
@ -527,12 +532,18 @@ def check_body(cls, b):
need(all(isinstance(b[k], str) for k in ("log", "profile", "entry")), 2)
need(is_hex(b["log_receipt"]), 2)
need(is_uri(b["log"]) and is_uri(b["profile"]) and is_token(b["entry"]), 2)
else: # soft-binding, binding-recovery
else: # soft-binding, soft-binding-span, binding-recovery
need(isinstance(b["alg"], str) and b["binding_type"] in ("watermark", "fingerprint"), 2)
need(is_hex(b["value"]) and isinstance(b["resolution_endpoint"], str), 2)
if cls == "soft-binding":
if cls in ("soft-binding", "soft-binding-span"):
need(isinstance(b["registry"], str), 2)
need(is_token(b["alg"]) and is_uri(b["registry"]) and is_uri(b["resolution_endpoint"]), 2)
if cls == "soft-binding-span":
# §2.6.4: the span, where the table reaches it: its members, then their types.
sp = b["span"]
nested(sp, SPAN)
need(all(is_int(sp[k]) for k in ("track_alias", "start_ms", "end_ms")), 2)
need(all(sp[k] is None or is_int(sp[k]) for k in SPAN[3:]), 2)
else:
need(is_hex(b["declaration"], 32), 2)
need(b["observed"] is None or is_hex(b["observed"], 32), 2)
@ -1466,10 +1477,12 @@ def class_rules(c):
need(any(bits), 4, bad)
elif cls == "log-inclusion":
need(b["log_receipt"] != "", 4, "log_inclusion_no_evidence")
elif cls in ("soft-binding", "binding-recovery"):
elif cls in ("soft-binding", "soft-binding-span", "binding-recovery"):
need(registry_form(b["alg"]), 4, "soft_binding_alg_not_registry_form")
need(b["value"] != "", 4, "soft_binding_empty_value")
need(is_https(b["resolution_endpoint"]), 4, "soft_binding_endpoint_not_https")
if cls == "soft-binding-span":
span_rules(b["span"])
if cls == "binding-recovery":
need(b["attests"] == "ancestor", 4, "recovery_not_ancestor")
need(b["observed"] != c["subject"], 4, "recovery_of_hard_bound_object")
@ -1478,6 +1491,43 @@ def class_rules(c):
# §2.4.14, §2.4.15: bearer-receipts §2's bearer classes.
BEARERS = ("bidirectional", "multicast", "unidirectional")
def span_rules(sp):
"""§2.6.4's rules: the groups, and the objects, both null or both integers, objects only
beside groups (span_malformed); each range in order, objects by group and then by
object (span_inverted)."""
g0, g1, o0, o1 = sp["first_group"], sp["last_group"], sp["first_object"], sp["last_object"]
need((g0 is None) == (g1 is None), 4, "span_malformed")
need((o0 is None) == (o1 is None), 4, "span_malformed")
need(o0 is None or g0 is not None, 4, "span_malformed")
need(sp["start_ms"] <= sp["end_ms"], 4, "span_inverted")
need(g0 is None or g0 <= g1, 4, "span_inverted")
need(o0 is None or (g0, o0) <= (g1, o1), 4, "span_inverted")
def within_span(d, r):
"""§2.6.4: whether the delivery receipt r — {signer, track_alias, group_id, object_id,
content_hash}, as the verifier holds it once verified — is within the span of the
declaration d."""
sp = d["body"]["span"]
if r["track_alias"] != sp["track_alias"] or r["signer"] != d["signer_pubkey"]:
return False
if sp["first_object"] is not None:
return (sp["first_group"], sp["first_object"]) <= (r["group_id"], r["object_id"]) <= (sp["last_group"], sp["last_object"])
if sp["first_group"] is not None:
return sp["first_group"] <= r["group_id"] <= sp["last_group"]
return r["content_hash"] == d["subject"]
def held_receipt(r):
"""A `receipt` context, checked for its shape: a malformed one is a malformed corpus."""
if not (isinstance(r, dict) and all(is_hex(r.get(k), 32) for k in ("signer", "content_hash"))
and all(isinstance(r.get(k), int) and not isinstance(r.get(k), bool) and 0 <= r[k] < 2 ** 64
for k in ("track_alias", "group_id", "object_id"))):
raise ValueError("bad receipt context")
return r
# §2.4.13: ai-usage §3, §6.2. The vocabularies, and the terms each defines.
CONSUMPTION_VOCABULARIES = ("aipref", "cawg", "tdmrep")
AIPREF_LABELS = ("train-ai", "ai-use", "search") # draft-ietf-aipref-vocab-08 §6.1
@ -1793,10 +1843,11 @@ def check_context(c, ctx):
recovery = c["class"] == "binding-recovery"
decision = c["class"] == "lawful-basis" and b["record"] == "decision"
# §2.6.3: the declaration is context only together with the publisher key of a
# verified delivery receipt for its subject. A corpus that gives one without the
# other is malformed, not a verdict.
if recovery and "publisher" not in ctx:
raise ValueError("a recovery record's declaration is context only with a publisher key")
# verified delivery receipt for its subject, or, for a span declaration, with a
# verified delivery receipt for an object of its span (`receipt`). A corpus that
# gives a declaration with neither is malformed, not a verdict.
if recovery and "publisher" not in ctx and "receipt" not in ctx:
raise ValueError("a recovery record's declaration is context only with a publisher key or a receipt")
need(recovery or decision, 6, "context_mismatch")
if not isinstance(ctx["declaration"], str):
raise TypeError("a declaration is given as its wire form")
@ -1806,11 +1857,21 @@ def check_context(c, ctx):
raise Reject(6, "context_invalid")
db = d["body"]
if recovery:
need(d["class"] == "soft-binding", 6, "context_mismatch")
# With a key, the declaration must state no span; with a receipt, it must state
# one: a key places no object in a span, and a whole-object declaration is
# checked against the key of a receipt for its subject.
span = "receipt" in ctx
need(d["class"] == ("soft-binding-span" if span else "soft-binding"), 6, "context_mismatch")
need(b["declaration"] == link_hash(d) and c["subject"] == d["subject"]
and b["alg"] == db["alg"] and b["binding_type"] == db["binding_type"],
6, "recovery_declaration_mismatch")
need(d["signer_pubkey"] == ctx["publisher"], 6, "recovery_signer_mismatch")
if span:
r = held_receipt(ctx["receipt"])
need(d["signer_pubkey"] == r["signer"], 6, "recovery_signer_mismatch")
need(within_span(d, r), 6, "recovery_outside_span")
need(b["observed"] != r["content_hash"], 6, "recovery_of_hard_bound_object")
else:
need(d["signer_pubkey"] == ctx["publisher"], 6, "recovery_signer_mismatch")
match(db["alg"], db["value"], b["value"], ctx.get("exact_match_algs", []))
else:
need(d["class"] == "lawful-basis" and db["record"] == "declaration", 6, "context_mismatch")
@ -1903,8 +1964,19 @@ def held_previous(ctx):
def recover(ctx):
"""§3.2. Returns the ancestor; raises Reject."""
"""§3.2. Returns the ancestor — for a recovery through a span, the anchor that names the
span; raises Reject."""
d = verify_claim(ctx["declaration"])
if "receipt" in ctx:
# Through a span: R, a verified delivery receipt for an object of the span, in place
# of the publisher key.
r = held_receipt(ctx["receipt"])
need(d["class"] == "soft-binding-span", 6, "context_mismatch")
need(d["signer_pubkey"] == r["signer"], 6, "recovery_signer_mismatch")
need(within_span(d, r), 6, "recovery_outside_span")
need(ctx.get("observed_hash") not in (d["subject"], r["content_hash"]), 6, "recovery_of_hard_bound_object")
match(d["body"]["alg"], d["body"]["value"], ctx["observed_value"], ctx.get("exact_match_algs", []))
return d["subject"]
need(d["class"] == "soft-binding", 6, "context_mismatch")
need(d["signer_pubkey"] == ctx["publisher"], 6, "recovery_signer_mismatch")
need(ctx.get("observed_hash") != d["subject"], 6, "recovery_of_hard_bound_object")

View file

@ -388,6 +388,20 @@ BODY_DEFECTS = {
(("resolution_endpoint",), [5, "x", "http://x/", "https://u@x/", DELETE]),
((EXTRA,), [1]),
]),
"soft_binding_span_objects_accept": ("PUBLISHER", [
(("alg",), [5, "", "bare", DELETE]),
(("value",), ["zz", "", DELETE]),
(("span",), ["x", [7], None, {}, DELETE]),
(("span", "track_alias"), ["7", None, DELETE]),
(("span", "start_ms"), ["1", None, 180000, DELETE]),
(("span", "end_ms"), [119999, "x", DELETE]),
(("span", "first_group"), [None, 45, "40", DELETE]),
(("span", "last_group"), [None, 39, DELETE]),
(("span", "first_object"), [None, 2, DELETE]),
(("span", "last_object"), [None, 0, DELETE]),
(("span", EXTRA), [1]),
((EXTRA,), [1]),
]),
"binding_recovery_accept": ("RESOLVER", [
(("alg",), [5, "", "bare", DELETE]),
(("binding_type",), [5, "hash", DELETE]),
@ -1995,6 +2009,38 @@ def contexts(ins):
"observed_hash": None, "exact_match_algs": [WM_ALG]}, procedure="recover")
def spans(ins, rng, n):
"""jwp-receipts §2.6.4 and §3.2 through a span: `n` span declarations with random ranges
near one another — media time, groups and objects each present or not, in order or
inverted, halves missing — each signed by the publisher and verified on its own, and,
for each, recoveries through it with delivery receipts on and around the edges of its
ranges, on another track, under another key, and of the anchor or another object, and a
recovery record naming it checked with the same receipts."""
decl = ins.receipt("soft_binding_span_groups_accept")
record = ins.receipt("binding_recovery_span_accept")
ppk, value, observed = pk(PUBLISHER), decl["body"]["value"], record["body"]["observed"]
anchor, other = decl["subject"], "ab" * 32 # the anchor, and an object of the track that is not it
near = lambda: rng.choice([0, 1, 2, 3, 40, 41, 42, 2 ** 53 - 1])
for i in range(n):
g = rng.choice([None, (near(), near()), (near(), None), (None, near())])
o = rng.choice([None, (near(), near()), (near(), None)])
t0 = rng.choice([0, 1, 120000, 179999])
t1 = rng.choice([t0, t0 + 1, max(t0 - 1, 0), 179999])
sp = {"track_alias": 7, "start_ms": t0, "end_ms": t1,
"first_group": g[0] if g else None, "last_group": g[1] if g else None,
"first_object": o[0] if o else None, "last_object": o[1] if o else None}
d = sign(dict(decl, body=dict(decl["body"], span=sp)), PUBLISHER)
ins.add(f"span_{i}", CV.jcs(d))
rec = sign(dict(record, body=dict(record["body"], declaration=CV.link_hash(d))), RESOLVER)
for j in range(6):
r = {"signer": ppk if rng.random() < 0.9 else pk(RESOLVER), "track_alias": 7 if rng.random() < 0.9 else 8,
"group_id": near(), "object_id": near(), "content_hash": rng.choice([anchor, other])}
hand = rng.choice([None, observed, r["content_hash"], anchor])
ins.add(f"span_{i}_recover_{j}", None, {"declaration": CV.jcs(d), "receipt": r, "observed_value": value,
"observed_hash": hand, "exact_match_algs": [WM_ALG]}, procedure="recover")
ins.add(f"span_{i}_record_{j}", CV.jcs(rec), {"declaration": CV.jcs(d), "receipt": r, "exact_match_algs": [WM_ALG]})
# ------------------------------------------------------------------ run and compare
def run_raw(cmd):
@ -2053,6 +2099,7 @@ def main(argv):
session_classical_sweep(ins)
session_roles_sweep(ins)
session_encrypted(ins, random.Random(f"session encrypted {a.seed}"), a.random) # its own stream, as classes()
spans(ins, random.Random(f"spans {a.seed}"), a.random) # its own stream, as classes()
doc = text_of({"about": "differential inputs; no outcome is declared", "vectors": ins.out})
with tempfile.NamedTemporaryFile("w", suffix=".json", delete=False, encoding="utf-8") as f:
f.write(doc)

View file

@ -23534,6 +23534,888 @@
"step": 4,
"reason": "session_switch_invalid"
}
},
{
"name": "soft_binding_span_time_accept",
"about": "a span binding over a minute of a track's media time, stated by media time alone",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":null,\"first_object\":null,\"last_group\":null,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"460f82b202934d1e7725fe7fdafd1a06cc761dffd742c9844567e597ba6dd551aafbc953504ee7536685566e4979b4a97c5a81b26e42c02f30358abce8461602\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "accept",
"link_hash": "d97b2c58797b300f975ec027fb6724213bfa3c9bd834622ff88bd158f5766a89"
}
},
{
"name": "soft_binding_span_groups_accept",
"about": "the same minute, stated with the groups that carry it",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "accept",
"link_hash": "b71484b3359afaf290e25aaacea763e2b879646794c03ea4c31967f9f169a3a5"
}
},
{
"name": "soft_binding_span_objects_accept",
"about": "the same minute, stated from an object of its first group to an object of its last",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":3,\"last_group\":44,\"last_object\":1,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5780f8a2e9efd0f98dbc779901e1653cbeae996fef6adc329e1970af500d4beeefefe641d1438c14cc042811eb9bb69fa4b0ba940e56e05de19c3d978a4bd606\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "accept",
"link_hash": "85fc55f008a38611485a30fb514dd497c6cd3468cc17fe67c124d6f92d774fc5"
}
},
{
"name": "soft_binding_span_one_instant_accept",
"about": "a span of one millisecond, one group and one object: each range may start where it ends",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":150000,\"first_group\":42,\"first_object\":5,\"last_group\":42,\"last_object\":5,\"start_ms\":150000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"7bde1a6c0b942353a14ffcc733503f2a6c1b4f3739293123bb5593cc052a26e50dad43ad0ca1e8a6edabee4f76a58a1210149b34508a0983132fbc0c3e1dd704\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "accept",
"link_hash": "1f786a52dd740d2690b469567dea96485f6a9eb872a7d7dce001d624ee981d9f"
}
},
{
"name": "soft_binding_span_objects_across_groups_accept",
"about": "objects are ordered by group and then by object: object 9 of group 40 comes before object 0 of group 41",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":121000,\"first_group\":40,\"first_object\":9,\"last_group\":41,\"last_object\":0,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"e890dcdd9448cdad51f8977542885368802a0635e8df6c8e1b6ddc12af7926fc46a5e9a9464c155789d84ddc7b7978d88e60a6f2e87024d16730d99ae362c50a\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "accept",
"link_hash": "c1da169af02cf04cb589bd50e2005e844a424f1a03acf7b349a6204d4db127c2"
}
},
{
"name": "soft_binding_span_time_inverted",
"about": "a span that ends a millisecond before it starts",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":null,\"first_object\":null,\"last_group\":null,\"last_object\":null,\"start_ms\":180000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"22fc93fedd8166eed34895b5987c3d8e6eacf527722eab803eb29665a40e06e1793c2eb07f939f4ee1ce590c4997b2c888d3cdae1bec0df5906f1632bf528703\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 4,
"reason": "span_inverted"
}
},
{
"name": "soft_binding_span_groups_inverted",
"about": "a span whose first group is after its last",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":44,\"first_object\":null,\"last_group\":40,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"38be212ee48cb855c16af23c262d05969956719793b0d5752bb85371d0dc502917ffbb091f68b5060574a2f4ef73cf38365d58809dceba3ef3ce745922f9d806\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 4,
"reason": "span_inverted"
}
},
{
"name": "soft_binding_span_objects_inverted",
"about": "within one group, a first object after the last",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":150000,\"first_group\":42,\"first_object\":5,\"last_group\":42,\"last_object\":4,\"start_ms\":150000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"8f529fded59231d23da28ff68b640ba480624538e2387c83a2f708fc2f5d4d538a4a5d0ce71ab2420d20a787c20148c72e3ba5ffb5f729c2d4a574a37e8bd602\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 4,
"reason": "span_inverted"
}
},
{
"name": "soft_binding_span_half_groups",
"about": "a first group with no last group",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":null,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"c1d0107a4ffa46edd6544073326a3a22d8deae58413da99d42e2bd1fc28416a3ee2d5c935607da3802bc240128ca51dd2e0bceaf28e68456809756f2e597840d\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 4,
"reason": "span_malformed"
}
},
{
"name": "soft_binding_span_half_objects",
"about": "a last object with no first object",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":1,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"c05780de7f5cb37a642364386cbb30dda1c1a284acaf836a02a2a799250ff11fc48dfc363c652fac607218eb20cad91e585432b7e7c4453676e10ff8c8bd3601\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 4,
"reason": "span_malformed"
}
},
{
"name": "soft_binding_span_objects_without_groups",
"about": "objects are object_ids within groups, so they are stated only beside groups",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":null,\"first_object\":3,\"last_group\":null,\"last_object\":1,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"384ea0cfadaebed7755199e995daccf6010c68fd44fd3fea8a5e2af0cfd4a695095db3d3683a753e1c965bbec3406a67c867909c915cef6b3167fbac2bf9a103\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 4,
"reason": "span_malformed"
}
},
{
"name": "soft_binding_span_soft_binding_rules_first",
"about": "an algorithm not in registry form and an inverted span: 2.6.2's rules run before the span's",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"SomeMark\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":null,\"first_object\":null,\"last_group\":null,\"last_object\":null,\"start_ms\":180000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"90d5b361e0995f23f6777ff675f934670ba3b1d70eaa2af2fcd64d3bfff72b44a74f845b2ea692de030d7301bcd634d96dc00549c1b8d1ad0573b8a286b6f808\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 4,
"reason": "soft_binding_alg_not_registry_form"
}
},
{
"name": "soft_binding_span_missing_span",
"about": "a span binding with no span",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"d495df100ba5c5877b70a2bb3b40d8c0dff13b68f1ea29dfc7e8a4a91044f41946b1aa3bf4ce6dd2af19c452b71551ba6ad1b60d9fc14cbaa3b214a0d427d30e\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 2,
"reason": "missing_required_field"
}
},
{
"name": "soft_binding_span_missing_end",
"about": "a span with no end",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"0ce832fea609baa49aa49a49b33adfe0e0d83e8509700fdbd2d187059d7c57dc487f501ae37bd602608082bcf9def49df46702223472e4fcca5df36795bda502\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 2,
"reason": "missing_required_field"
}
},
{
"name": "soft_binding_span_region",
"about": "a span has no region: a member it does not define is refused, not ignored",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"region\":{},\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"8d1d59bcfea88826e6a57c46edd27355017ff7242f5ac841408d32a83aaaae7ba8bcfb1e53786ad01d31475285f4f7556de38b772556f53b1201eb4fa660d30b\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 2,
"reason": "unknown_member"
}
},
{
"name": "soft_binding_span_fractional_ms",
"about": "media time is an integer of milliseconds: 120000.5 is not one",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000.5,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 2,
"reason": "field_type"
}
},
{
"name": "soft_binding_span_track_not_integer",
"about": "a track alias written as a string",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":\"7\"},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 2,
"reason": "field_type"
}
},
{
"name": "soft_binding_span_alg_before_span",
"about": "an algorithm that is not a term and a span with no end: the algorithm's type is read before the span is reached",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"28d9fd4227560b8306f1161279ae62b080ee8817b83ed702ea9ce4f7c3d7ec8087bc068d8c2e877fffb58016a6ea30906b2bceb7381f5ed07d1071ee8c23e906\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 2,
"reason": "field_type"
}
},
{
"name": "soft_binding_span_not_an_object",
"about": "a span given as a list of its numbers",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":[7,120000,179999],\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"e437dbdbb765a531ef2f34235b82edd37e06ad19ee9ffb5c53be38b0e43738aa1a57fc44cfae5edc955e3e3c3ba02a89ca8273b80ab6b6efbc311131bb21840d\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 2,
"reason": "field_type"
}
},
{
"name": "soft_binding_with_span",
"about": "a whole-object soft binding carrying a span: the class is unchanged, and a span is its own class",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"0a1003b673b83506c1f0b2e6a9316ff9d69ae9b6b8cee5c73ea3fc6e45feb388449bac6f17c255a600e684a71db10f23c459a709a194c56835b83f354403890b\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"5bb20a10b980be8c6d95915394f6e89cd49c16d0f5e94cd87c0ec6ce37bcfc5e\",\"subject_type\":\"object\"}",
"expected": {
"outcome": "reject",
"step": 2,
"reason": "unknown_member"
}
},
{
"name": "soft_binding_span_about_a_receipt",
"about": "a span binding's subject is its anchor object, never a receipt",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"f6beec25e985ae9c83a1ab45fe81297a873e0ddc00c62a482426be0800878b988421b7e8918630800725f2dd25555d7d18afe6f4d19b8b84c1da18ce4c35100d\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"000b73b044437005c34711736a91e1d99fb9513d4052378e43f947c75d3b5261\",\"subject_type\":\"receipt\"}",
"expected": {
"outcome": "reject",
"step": 1,
"reason": "subject_type_not_admitted"
}
},
{
"name": "recover_span_group_inside",
"about": "a receipt of a group inside the span: the recovery attests the span, named by its anchor",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"attests": "ancestor",
"ancestor": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
}
},
{
"name": "recover_span_first_group",
"about": "the span's first group, its object 0",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 40,
"object_id": 0,
"content_hash": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"attests": "ancestor",
"ancestor": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
}
},
{
"name": "recover_span_last_group",
"about": "the span's last group, any object of it",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 44,
"object_id": 1000,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"attests": "ancestor",
"ancestor": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
}
},
{
"name": "recover_span_group_before",
"about": "the group before the span: the declaration says nothing about it",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 39,
"object_id": 0,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_outside_span"
}
},
{
"name": "recover_span_group_after",
"about": "the group after the span",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 45,
"object_id": 0,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_outside_span"
}
},
{
"name": "recover_span_first_object",
"about": "the span's first object",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":3,\"last_group\":44,\"last_object\":1,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5780f8a2e9efd0f98dbc779901e1653cbeae996fef6adc329e1970af500d4beeefefe641d1438c14cc042811eb9bb69fa4b0ba940e56e05de19c3d978a4bd606\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 40,
"object_id": 3,
"content_hash": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"attests": "ancestor",
"ancestor": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
}
},
{
"name": "recover_span_object_before_first",
"about": "the object before the span's first, in its first group",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":3,\"last_group\":44,\"last_object\":1,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5780f8a2e9efd0f98dbc779901e1653cbeae996fef6adc329e1970af500d4beeefefe641d1438c14cc042811eb9bb69fa4b0ba940e56e05de19c3d978a4bd606\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 40,
"object_id": 2,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_outside_span"
}
},
{
"name": "recover_span_last_object",
"about": "the span's last object",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":3,\"last_group\":44,\"last_object\":1,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5780f8a2e9efd0f98dbc779901e1653cbeae996fef6adc329e1970af500d4beeefefe641d1438c14cc042811eb9bb69fa4b0ba940e56e05de19c3d978a4bd606\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 44,
"object_id": 1,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"attests": "ancestor",
"ancestor": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
}
},
{
"name": "recover_span_object_after_last",
"about": "the object after the span's last, in its last group",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":3,\"last_group\":44,\"last_object\":1,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5780f8a2e9efd0f98dbc779901e1653cbeae996fef6adc329e1970af500d4beeefefe641d1438c14cc042811eb9bb69fa4b0ba940e56e05de19c3d978a4bd606\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 44,
"object_id": 2,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_outside_span"
}
},
{
"name": "recover_span_middle_group_any_object",
"about": "any object of a group strictly inside an object range",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":3,\"last_group\":44,\"last_object\":1,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5780f8a2e9efd0f98dbc779901e1653cbeae996fef6adc329e1970af500d4beeefefe641d1438c14cc042811eb9bb69fa4b0ba940e56e05de19c3d978a4bd606\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 9000,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"attests": "ancestor",
"ancestor": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
}
},
{
"name": "recover_span_other_track",
"about": "a receipt of another track of the same publisher, at coordinates inside the range",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 8,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_outside_span"
}
},
{
"name": "recover_span_other_signer",
"about": "a receipt signed by another key: the declaration is not that publisher's",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "c6822637c7d310ec57627be00ba259d253749f4aaf644470cffbe53a35f73242",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_signer_mismatch"
}
},
{
"name": "recover_span_time_anchor",
"about": "a span of media time alone, with the anchor's receipt: the one object it places",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":null,\"first_object\":null,\"last_group\":null,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"460f82b202934d1e7725fe7fdafd1a06cc761dffd742c9844567e597ba6dd551aafbc953504ee7536685566e4979b4a97c5a81b26e42c02f30358abce8461602\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 40,
"object_id": 3,
"content_hash": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"attests": "ancestor",
"ancestor": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
}
},
{
"name": "recover_span_time_other_object",
"about": "a span of media time alone places no object but the anchor: delivery receipts carry no media time",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":null,\"first_object\":null,\"last_group\":null,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"460f82b202934d1e7725fe7fdafd1a06cc761dffd742c9844567e597ba6dd551aafbc953504ee7536685566e4979b4a97c5a81b26e42c02f30358abce8461602\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_outside_span"
}
},
{
"name": "recover_span_hard_bound_receipt",
"about": "the object in hand hashes to the receipt's object: its hard binding holds",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_of_hard_bound_object"
}
},
{
"name": "recover_span_hard_bound_anchor",
"about": "the object in hand hashes to the anchor",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_of_hard_bound_object"
}
},
{
"name": "recover_span_not_an_envelope",
"about": "the object in hand is no longer a WAI envelope; the match still attests only the span",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": null,
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"attests": "ancestor",
"ancestor": "ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200"
}
},
{
"name": "recover_span_value_mismatch",
"about": "another payload does not recover",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "616e6f74686572207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_value_mismatch"
}
},
{
"name": "recover_span_through_whole_object_declaration",
"about": "a receipt for an object of a span, and a declaration that states no span",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"1910f9511d560f9b30a03956ba02aa9ba8b5708138fe76ec307ccd8c671d3bd412f9139d0fa39ce23e5a4e4e8aa73eaceed625a331457e7d321a1e8a10e84c03\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"5bb20a10b980be8c6d95915394f6e89cd49c16d0f5e94cd87c0ec6ce37bcfc5e\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "context_mismatch"
}
},
{
"name": "recover_span_declaration_invalid",
"about": "a span declaration that fails 3.1 is not recovered from; its own rejection is reported",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179998,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 3,
"reason": "signature_verify_failed"
}
},
{
"name": "recover_span_declaration_with_a_key_alone",
"about": "the whole-object procedure takes a key, which places no object in a span",
"procedure": "recover",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"publisher": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"observed_value": "636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164",
"observed_hash": "4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "context_mismatch"
}
},
{
"name": "binding_recovery_span_accept",
"about": "a recovery record naming a span declaration, checked with a receipt of an object inside the span",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"attests\":\"ancestor\",\"binding_type\":\"watermark\",\"declaration\":\"b71484b3359afaf290e25aaacea763e2b879646794c03ea4c31967f9f169a3a5\",\"observed\":\"4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"binding-recovery\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5f4ed83d35d546436538b5e5272637c2d798b264ed967839d89c0de894f32b2779c53a5e2d1ac95265b68e68e2141a4bd3707f3994beb1334f33e24c847f8e0c\",\"signer_id\":\"did:example:resolver\",\"signer_pubkey\":\"c6822637c7d310ec57627be00ba259d253749f4aaf644470cffbe53a35f73242\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "accept",
"link_hash": "5361a60f837e370c9e6f12345bebb60fac7cc9ea1c52254fd8554935467c1cdc"
}
},
{
"name": "binding_recovery_span_outside",
"about": "the same record, checked with a receipt of a group after the span",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"attests\":\"ancestor\",\"binding_type\":\"watermark\",\"declaration\":\"b71484b3359afaf290e25aaacea763e2b879646794c03ea4c31967f9f169a3a5\",\"observed\":\"4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"binding-recovery\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5f4ed83d35d546436538b5e5272637c2d798b264ed967839d89c0de894f32b2779c53a5e2d1ac95265b68e68e2141a4bd3707f3994beb1334f33e24c847f8e0c\",\"signer_id\":\"did:example:resolver\",\"signer_pubkey\":\"c6822637c7d310ec57627be00ba259d253749f4aaf644470cffbe53a35f73242\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 45,
"object_id": 0,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_outside_span"
}
},
{
"name": "binding_recovery_span_hard_bound",
"about": "a record whose object in hand is the receipt's own object",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"attests\":\"ancestor\",\"binding_type\":\"watermark\",\"declaration\":\"b71484b3359afaf290e25aaacea763e2b879646794c03ea4c31967f9f169a3a5\",\"observed\":\"7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"binding-recovery\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"1f25a33659a22410978bc9edcd214b1b3b7b1858c82267d34253cc46b09a5c2ea2ca57d466d529b9bcad86b6ed0ca74ad001bb4039c85e35fe0b577f087de704\",\"signer_id\":\"did:example:resolver\",\"signer_pubkey\":\"c6822637c7d310ec57627be00ba259d253749f4aaf644470cffbe53a35f73242\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_of_hard_bound_object"
}
},
{
"name": "binding_recovery_span_other_signer",
"about": "a record checked with a receipt another key signed",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"attests\":\"ancestor\",\"binding_type\":\"watermark\",\"declaration\":\"b71484b3359afaf290e25aaacea763e2b879646794c03ea4c31967f9f169a3a5\",\"observed\":\"4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"binding-recovery\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5f4ed83d35d546436538b5e5272637c2d798b264ed967839d89c0de894f32b2779c53a5e2d1ac95265b68e68e2141a4bd3707f3994beb1334f33e24c847f8e0c\",\"signer_id\":\"did:example:resolver\",\"signer_pubkey\":\"c6822637c7d310ec57627be00ba259d253749f4aaf644470cffbe53a35f73242\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "c6822637c7d310ec57627be00ba259d253749f4aaf644470cffbe53a35f73242",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "recovery_signer_mismatch"
}
},
{
"name": "binding_recovery_span_key_alone",
"about": "a span declaration given with a publisher key and no receipt: a key places no object in the span",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"attests\":\"ancestor\",\"binding_type\":\"watermark\",\"declaration\":\"b71484b3359afaf290e25aaacea763e2b879646794c03ea4c31967f9f169a3a5\",\"observed\":\"4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"binding-recovery\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"5f4ed83d35d546436538b5e5272637c2d798b264ed967839d89c0de894f32b2779c53a5e2d1ac95265b68e68e2141a4bd3707f3994beb1334f33e24c847f8e0c\",\"signer_id\":\"did:example:resolver\",\"signer_pubkey\":\"c6822637c7d310ec57627be00ba259d253749f4aaf644470cffbe53a35f73242\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"span\":{\"end_ms\":179999,\"first_group\":40,\"first_object\":null,\"last_group\":44,\"last_object\":null,\"start_ms\":120000,\"track_alias\":7},\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding-span\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"b80821ac85b7e716d52a31aa9d64717832ec1d8024dd30da2188d73dcbb607745655c6c6f44f7df9afd31243949cc152f2b6a1e964292df9101d781d3e50030c\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"publisher": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "context_mismatch"
}
},
{
"name": "binding_recovery_whole_object_with_receipt",
"about": "a record naming a whole-object declaration, given a receipt in place of a key",
"procedure": "claim",
"receipt": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"attests\":\"ancestor\",\"binding_type\":\"watermark\",\"declaration\":\"dd748e836a7d04f32681ddd68316f50b856816100c7e5623bef87ea85e310176\",\"observed\":\"4067f884c1e93c4c86ef0ef3c1a22b2c7bdd405c5e2e51681bb644ac749d7e15\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"binding-recovery\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"1548d1d838c9e46d53e403e0571cfc1bfcc1eaeb2387ae489e4a4b902dcd8c6dbe87ee8a8950e47cd6d1fb28903f4580ebfea650545bf0da6a6a187cc296e10d\",\"signer_id\":\"did:example:resolver\",\"signer_pubkey\":\"c6822637c7d310ec57627be00ba259d253749f4aaf644470cffbe53a35f73242\",\"subject\":\"ef6ee6301d1a396bcf64d647ccec8bca57185a7b5af983e49dc77c408a31b200\",\"subject_type\":\"object\"}",
"context": {
"declaration": "{\"body\":{\"alg\":\"org.example.watermark.1\",\"binding_type\":\"watermark\",\"registry\":\"https://registry.example.org/soft-binding-algorithms\",\"resolution_endpoint\":\"https://resolver.example.org/matches\",\"value\":\"636c61696d2d636f6e666f726d616e63652077617465726d61726b207061796c6f6164\"},\"class\":\"soft-binding\",\"issued_at\":\"2026-09-27T12:00:00Z\",\"kind\":\"claim\",\"parent_receipt_hash\":null,\"seq\":0,\"sig\":\"1910f9511d560f9b30a03956ba02aa9ba8b5708138fe76ec307ccd8c671d3bd412f9139d0fa39ce23e5a4e4e8aa73eaceed625a331457e7d321a1e8a10e84c03\",\"signer_id\":\"did:example:publisher\",\"signer_pubkey\":\"d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737\",\"subject\":\"5bb20a10b980be8c6d95915394f6e89cd49c16d0f5e94cd87c0ec6ce37bcfc5e\",\"subject_type\":\"object\"}",
"receipt": {
"signer": "d04ab232742bb4ab3a1368bd4615e4e6d0224ab71a016baf8520a332c9778737",
"track_alias": 7,
"group_id": 42,
"object_id": 6,
"content_hash": "7fffdef0c67dcfdda23d9b3031c4715fc509ee5b6c1299cb9a6a6c17ddf3a773"
},
"exact_match_algs": [
"org.example.watermark.1"
]
},
"expected": {
"outcome": "reject",
"step": 6,
"reason": "context_mismatch"
}
}
]
}

View file

@ -2,8 +2,10 @@
> Status: Draft. An **unsigned, advisory** observation about WAI delivery that a sink,
> edge or origin emits; its mapping onto the keys of CMCD version 2 (CTA-5004-B) and
> CMSD (CTA-5006), written as RFC 9651 Structured Field Values; and the session
> metrics a log of observations gives. Reference impl: `wai-rs` —
> CMSD (CTA-5006), written as RFC 9651 Structured Field Values, with each key's class and
> what it reveals (§3.4); and the session metrics a log of observations gives, which
> [telemetry-aggregation](telemetry-aggregation.md) aggregates without the service holding
> any session's. Reference impl: `wai-rs` —
> `telemetry::{sf, observation, cmcd, cmsd, qoe}`; the `wai_telemetry` tool; the corpus
> [`telemetry-conformance/`](../telemetry-conformance/), with a differential against an
> independent open-source CMCD and CMSD library. Keywords **MUST**, **MUST NOT**,
@ -114,6 +116,53 @@ Every report carries `v=2`, `sid`, `sn`, `st` and `sf`, and `cid` where it is no
written in bytewise order and without optional whitespace, and a key is written only
when its value is not `null`. The corpus fixes the output byte for byte.
§3.4 **Key classes.** Each key this mapping writes has a class:
- `delivery`: what the host serving the request needs to serve it;
- `measurement`: what is only aggregated afterwards.
A class informs what a deployment does with a key (§4.3,
[telemetry-aggregation](telemetry-aggregation.md) §9); it is not a permission, and no key
is conditional on anything but the observation's members. A Request-mode report goes to the
host that serves the object, an Event-mode report to the content's own service (§8.3).
| key | class | what it reveals | reported in |
|---|---|---|---|
| `v` | delivery | the CMCD version the report is written in | every report |
| `st` | delivery | whether the session plays on demand, live or low-latency live, which a host may serve differently | every report |
| `ot` | delivery | the kind of object requested, which a host may schedule or cache by | Request mode |
| `d` | delivery | the requested object's playback duration, which a host may prefetch by | Request mode |
| `dl` | delivery | the time until the sink's buffer runs out: its buffer level | Request mode |
| `science.transaction.wai-ch` | delivery | the exact object, by content hash, which a content-addressed host serves by | Request mode, `e=rr` |
| `science.transaction.wai-lc` | delivery | the layer cap the request asks the host to apply: the sink's quality ceiling | Request mode, `wai-layer-change` |
| `sid` | measurement | that reports belong to one session; it is fresh per session (§8.1), so nothing across sessions | every report |
| `sn` | measurement | the report's place in its session, so how many came before it | every report |
| `cid` | measurement | the content the session plays | every report |
| `sf` | measurement | the delivery format: WAI objects, or a WAI rendition through HLS or DASH | every report |
| `msd` | measurement | the session's media start delay | any report |
| `bsa`, `bsda` | measurement | the session's buffer starvations and their duration so far: its network conditions | any report |
| `dfa` | measurement | the frames dropped so far: the device's decode performance | any report |
| `ts` | measurement | when the event happened | Event mode |
| `e`, `sta` | measurement | the event and the player's state | Event mode |
| `rc`, `ttfb`, `ttlb` | measurement | a response's status and timing: the sink's throughput and network latency | Event mode |
| `url` | measurement | the address of a response's object | Event mode |
| `cen` | measurement | which of this mapping's custom events occurred | Event mode |
| `science.transaction.wai-b`, `science.transaction.wai-tx` | measurement | the bytes counted and transferred for an object | Request mode, `e=rr` |
| `science.transaction.wai-cap` | measurement | a capability the sink decodes: device-identifying | Request mode, `e=rr` |
| `science.transaction.wai-ri` | measurement | the rendition chosen: the sink's bandwidth and device class | Request mode, `e=rr` |
| `science.transaction.wai-l`, `science.transaction.wai-lt` | measurement | how far into a stage set the sink fetches | Request mode, `e=rr` |
| `science.transaction.wai-p` | measurement | whether the sink fell back to the classical rendition | Request mode, `e=rr`, `wai-switch` |
| `science.transaction.wai-rcpt` | measurement | a receipt the sink holds, which links the request to its receipt chain | Request mode, `e=rr` |
| `science.transaction.wai-lcf` | measurement | the previous layer cap | `wai-layer-change` |
| `science.transaction.wai-coh` | measurement | the experiment arm of the session | every report |
| `science.transaction.wai-u` | measurement | a unit presented or switched | `sta=p`, `wai-switch` |
| `science.transaction.wai-pl`, `science.transaction.wai-late`, `science.transaction.wai-dec` | measurement | the layers presented, lateness and decode time: device performance, device-identifying | `sta=p` |
| `science.transaction.wai-sw` | measurement | why the sink switched | `wai-switch` |
| `science.transaction.wai-co`, `science.transaction.wai-cr`, `science.transaction.wai-cf` | measurement | the dispatch outcome and the platform's classical-floor answer: device-identifying | `wai-capable` |
| `science.transaction.wai-clm` | measurement | the session's sealed claim, which links the session to its signed claim | `sta=e` |
A key this mapping does not write has no class here.
## 4. Custom keys
§4.1 Custom keys have the form `science.transaction.wai-<x>`: a lowercase first letter,
@ -147,6 +196,15 @@ CTA-5004-B assigns it (`v`, `sid`, `cid`, `st`, `sf` and `msd` to `CMCD-Session`
`CMCD-Status`), and each custom key to the shard of §4.1. Each shard is a Dictionary
written as §3.3 writes a report; a shard with no key is not sent.
§4.3 **Delivery-only Request mode.** A sink **MAY** report Request mode delivery-only: a
Request-mode report then carries the members of its observation whose keys are of the
delivery class (§3.4) and no other, written as §3.3 writes a report, in the header shards of
§4.2 when it goes in shards. The measurement-class members are not sent to the host; the
sink reports them to the content's own service in Event mode, or as the measures of
[telemetry-aggregation](telemetry-aggregation.md) §3. A reader that checks a report it is
told is delivery-only refuses one that carries a key not of the delivery class,
`measurement_key_in_delivery`, naming the first such key in bytewise order.
## 5. Switch reasons
§5.1 A switch reason is one of:
@ -206,9 +264,15 @@ increasing, timestamps never decreasing, and nothing after `end` or `abandon`.
## 8. Privacy
§8.1 `sid` is fresh per session. An emitter **MUST NOT** add a persistent identifier, or
send telemetry to a party other than the content's own service, without the person's
agreement.
§8.1 `sid` is fresh per session, and an emitter adds no persistent identifier. Telemetry
goes to the host that serves an object (Request mode) and to the content's own service
(Event mode), and, for a measure of [telemetry-aggregation](telemetry-aggregation.md) §3, to
its task's two aggregators as secret shares, each of which alone reveals nothing about the
measurement. This extension sets no consent requirement for the service's own mechanics:
using a distributor's WAI service is the person's agreement to how that service works. Where
a regime asks for a lawful basis for processing telemetry, the service records it in a
`lawful-basis` claim ([jwp-receipts](jwp-receipts.md) §2.4.6). What each key reveals, and to
whom, is §3.4's.
§8.2 Neither a URL's query nor a signed URL's token enters an observation. A reader
refuses an `object.url` that holds a `?`, a `#`, a `@` or a `\`: a query, a fragment,
@ -224,7 +288,11 @@ in `cid`, and reports the content hash where it has no identifier free of them.
and to no other party. Event-mode reports go to the content's own service (§8.1).
§8.4 A published aggregate covers at least 50 sessions per cell. A cell with fewer is
suppressed, not rounded.
suppressed, not rounded. Where the figures are aggregated under
[telemetry-aggregation](telemetry-aggregation.md), the service never holds a session's
figures, and the floor is each aggregator's: a task's minimum batch size is at least 50, and
an aggregator refuses to release a share of a smaller batch (§4.3, §5.2 there). This
suppression still applies to what that extension does not aggregate (§9.1 there).
## 9. Conformance
@ -246,3 +314,7 @@ with an independent open-source CMCD and CMSD library at the versions
expected strings back as a dictionary, as a query string and as header shards, and
requires the report's members; and validates every report, and the Event-mode reports
together, with no error.
§9.4 The delivery-only reports of §4.3, with reports a reader refuses, and the key classes
of §3.4, are checked in the corpus of
[telemetry-aggregation](telemetry-aggregation.md) §12.

View file

@ -261,6 +261,14 @@ integer function of the decoded samples and its pinned parameters, so a sink tha
output holds the tier of the decode it ran on, and states the derivation, and its prior, with the
output (synthesis §9.2, exact-upscale §6).
HDR display adaptation is such processing: a sink makes, from the decoded picture, a gain map
or dynamic metadata and its display's headroom, the rendition it presents, and the standards
that define it state the computation in real numbers, so the presented pixels differ from sink
to sink. The derivations of [exact-tonemap](exact-tonemap.md) §4 and §5 pin it in integer
arithmetic: a rendition is a pure function of the decoded samples, the companion's bytes and
the headroom, so a sink that presents one holds the tier of the decode it ran on, and states the
headroom and the rendition's digest in its rendition record (exact-tonemap §7).
## 3. Declaring and using a tier
- **Declaring.** A capability's registration (SPEC §5) states its tier via its
@ -370,7 +378,9 @@ tier costs them.
| `wai.splat.int_codec` | attribute tensor | integer synthesis over a factorized rANS latent |
| `wai.neural.int_mlicpp` | RGB | integer hyper-decoder; an integer entropy network re-run before each of the `2·K` channel-slice × checkerboard passes, integer scale → distribution step; integer synthesis. Stream values an exact decode cannot hold are refused, not wrapped |
These six are integer throughout, are the capabilities the registry classifies as
| `wai.audio.opus.dred.int` | the feature sequence (i32 at `2^16`) | the draft's DRED feature decoder as the `wai-ops/1` graphs of `dred-int/1`, over the draft's own weights file pinned by SHA-256: weights quantized from their float32 bits, integer activations, `tanh` and the sigmoid as integer tables ([opus-dred](opus-dred.md) §4). The vocoder that renders the features is the sink's and outside the claim |
These seven are integer throughout, are the capabilities the registry classifies as
`NeuralIntegerExact`, and are the neural capabilities that back `replicate`.
### `entropy-consistency`: `wai.image.jpegai`, and its exact decoder's pinned reconstruction
@ -601,6 +611,7 @@ task list has no Windows task after that day. The Windows results below are hist
| `wai.image.jpegai` scope: the reference codestream is accepted; copies with β, `model_id`, the colour transform or an LSBS flag changed are refused; a flush-to-zero or round-toward-zero environment is detected. The float ONNX path calls the same check | library unit tests over a committed copy of the reference codestream, which never skip and fall under the library-test step of the conformance workflow (`neural_int`); the environment test runs on arm64 only. Run on the four platforms above, on the source of the change that added the cross-platform row (the environment test on macOS arm64 and Linux arm64). The float path's refusal (β and `model_id` edits) is tested only with its ONNX bundle supplied (`jpegai_scope_ort.rs`, skips otherwise) | `wai-rs/src/jpegai_decode.rs` tests, `wai-rs/tests/vectors/jpegai/` |
| SPEC §7's replicate rule: the registry class decides first, so an integer-declared prior over `wai.image.jpegai` or a float codec is refused; `wai.image.jpegai` is the only `NeuralEntropyExact` capability; the standard codecs sit in the classes SPEC §7 lists, and the tolerance and unclassified ones are not refused; an encoder that pins no prior (`wai wrap`) writes `replicate` only over the standard classes, for the capability and for any declared fallback, or, in the `WAI2` companion form, for the base payload's capability and each companion's | library unit tests (`codecs`, `container`) that never skip and fall under the same library-test step. The strict-decode test in `tests/neural_native_decode.rs` needs the `neural` feature; `wai-neural-gates.yml` runs it on the Linux runner, in an Ubuntu 24.04 image because the `neural` test binary does not link in that runner's default 22.04 image. Its strict-decode job ran on the forge and passed on every run from 2026-09-28; before that the job passed under `forgejo-runner exec` on the Linux runner's host (Linux x86_64, 2026-09-27). The pin-aware tests since added to that workflow (its longer exact list of `neural_native_decode` tests, the step of model-free `neural` library tests, and the neural C ABI step, `tests/ffi_neural_pin.rs`) have no recorded forge run yet. The `wai` binary no longer needs the `codecs` feature, so the tests that run `wai wrap` (`cli_wrap_intent.rs`, and `cli_registry.rs` for the candidate refusal and the registry export) run in the conformance workflow's carriage step on every leg; this row records no forge run of them yet. The C envelope packers emit through `Wai::to_emit_bytes` and `WaiMulti::to_emit_bytes`, whose candidate refusal a library test checks with no feature (`the_emit_path_refuses_a_candidate`, in the library-test step); the C wrappers themselves build under the codec-free `ffi` feature, and `tests/ffi_envelope.rs` (`envelope_pack_refuses_a_candidate`, `envelope_select_never_picks_a_candidate`) runs in the conformance workflow's C ABI envelope step on every leg; this row records no forge run of that step yet. The browser writers' refusal runs in `wai-web-wasm.yml` (`verify_pack.mjs`) | `wai-rs/src/codecs/mod.rs`, `container.rs` tests; `wai-rs/tests/neural_native_decode.rs`, `cli_wrap_intent.rs`, `cli_registry.rs`; `wai-web/demo/verify_pack.mjs` |
| `wai.neural.int_hyper` and `wai.video.int_hyper` at full model scale (the pretrained `mbt2018_mean`, exported to integers): the Rust decode reproduces the export tool's integer reference byte for byte (synthesis, hyper-decoder, the whole conditional bitstream, an eight-frame clip), and costs at most 1 dB against the same model's float decode on one pinned photograph | `wai-sota-vectors.yml` regenerates the vectors on the runner from pinned inputs (the photograph's pixels and the checkpoint's bytes by SHA-256, the Python stack by version) and runs both tests with `WAI_REQUIRE_SOTA_VECTORS=1`, under which a missing vector fails instead of skipping. The job also fails on any skip banner in the test log, and runs `require_vectors_rule.rs`, which checks that without the switch a variable naming absent or incomplete inputs fails as well. Rust is checked against the export of the same run on the same machine: the vectors come from float computation, and some of them differed between machines and between runs, so none of their hashes is pinned and none is compared across machines. The workflow has run on the forge's Linux runner (x86_64 hardware) and passed on every run since 2026-09-28 | `wai-rs/tests/int_hyper_synth.rs`, `int_video_sota_keyframe.rs`, `require_vectors_rule.rs`; `.github/workflows/wai-sota-vectors.yml` |
| `wai.audio.opus.dred.int`: the profile's features are an exact integer function of the payload and the pinned weights, the same on the CPU and on a GPU, and within the draft's tolerance of its reference features | the corpus `live-conformance/dred/` regenerates byte for byte, and its second implementation (`dred_verify.py`, standard-library Python written from the extension) recomputes every digest and row; the two graphs on the GPU at `acc64` give the interpreter's integers graph by graph and the CPU decode's bytes; on the draft's eight test vectors the features pass the draft's feature test and lie at `total` 0.0021 from the network in floating point (opus-dred §6) | measured 2026-10-22 with rustc 1.98.0 on macOS arm64 (the build host: the wai-rs tests in release, the GPU test on its Metal adapter `gpu-metal-0`) and the Python verifier on a second macOS arm64 host. Not measured: x86_64, Linux, Windows, wasm. CI runs the corpus, the measurement and the verifier on the forge's Linux arm64 runner (`wai-conformance.yml`) and the GPU test on the `macos` runner (`wai-ops-gpu.yml`), with no forge run recorded yet. The weights are fetched by digest, not committed | `wai-rs/tests/dred_exact.rs`, `wai-rs/tests/dred_exact_measure.rs`, `wai-rs/tests/dred_exact_gpu.rs`, `live-conformance/dred_verify.py` |
| `wai.audio.int_codec`, `wai.splat.int_codec` | committed vectors that never skip. Their frozen hashes are the output of an independent Python integer reference, computed when the vectors were exported (`tools/wai_int_audio_export.py`, `tools/wai_int_splat_export.py`); no Python runs in CI. The conformance workflow's fast-kernel steps enable `audio_int` and `splat_int` and, in debug and release builds, decode both vectors against those hashes under the reference kernels and every fast-kernel policy (`tests/int_kernels_vectors.rs`); that passed on the forge's Linux x86_64, Linux arm64 and macOS arm64 runners for the landing chain's head `7cfcecfa` (run 745, 2026-09-30). The same steps also name `tests/int_audio.rs` and `tests/int_splat.rs`, which check each vector against the same hash and against its own metadata (sample count; attribute count, tensor size and grid side); Cargo declares each with its feature as a required feature, so a step that names it without that feature fails instead of running nothing. This row records no forge run of those two | `wai-rs/tests/int_audio.rs`, `int_splat.rs`, `int_kernels_vectors.rs`; `.github/workflows/wai-conformance.yml` |
| `wai.neural.int_mlicpp` on its committed vector (synthetic seeded weights; a 64×64 image, 8 latent channels in 4 slices): the decode reproduces the export tool's independent integer reference byte for byte — the RGB, and every scale bucket and symbol of the latent stream in coding order (512 symbols over all 16 buckets of the scale table, 47 of the symbols coded by the rANS escape) — under the reference kernels and under the fast kernels on 1, 2, 3, 5 and all available threads; one integer unit changed in each of four chosen parameters, one on each path that feeds a value (a hyper-decoder weight, an entropy-network weight, a mean-head bias, a synthesis weight), changes the image; a header whose shapes the model cannot produce, or on which a network would form a buffer over the cap, is refused before anything is allocated (`tests/int_mlicpp_preflight.rs`, which counts allocations); damaged payloads are refused or decode, and never panic in an overflow-checked build | measured 2026-09-29 with rustc 1.98.0 on the source of the change that added this row: macOS arm64 native (the wai-rs tests, with overflow checks on and off; the `byte-exact-conformance` golden, release) and wasm32-wasip2 under wasmtime 49.0.1 (the same tests and golden, release; on wasm the fast kernels run single-threaded as portable scalar code, and `usize` is 32-bit). All pinned hashes matched on both. Not measured: x86_64 — the development machine has no x86_64 translation layer installed, and an x86_64-apple-darwin build of the golden compiles but cannot execute there — nor Linux or Windows. The golden runs on every leg of the byte-exact matrix (`wai-conformance.yml`, `wai-byte-equality.yml`) and `tests/int_mlicpp.rs` on every leg of `wai-conformance.yml` in both profiles. Both passed on the forge's Linux x86_64, Linux arm64 and macOS arm64 runners for the landing chain's head `7cfcecfa` (run 745, 2026-09-30); there is no Windows leg. The dispatch through `decode_envelope_strict` (the prior pinning the one-file model bundle, the strict gate) runs in `wai-neural-gates.yml`. The weights are synthetic, so nothing here measures compression quality | `wai-rs/tests/int_mlicpp.rs`, `wai-rs/tests/int_mlicpp_preflight.rs`, `byte-exact-conformance/src/int_mlicpp_golden.rs`, `wai-rs/tests/neural_native_decode.rs`; `tools/wai_int_mlicpp_export.py` |
| `wai-ops/1-i32` graphs on GPUs (`wai/wai-ops-gpu`, §5): each device's arithmetic agrees with 128-bit host arithmetic on every probe case; every graph vector of `ops-conformance/` that the subset covers gives the interpreter's outputs or refusal code, at `acc32` and at `acc64`; the integer decoders, with their graphs on the device, give the CPU decode's bytes or refusal codes on every committed vector and refusal fixture, and every graph the device runs gives the interpreter's outputs | measured 2026-10-20 and 2026-10-21 with rustc 1.98.0 and wgpu 30.0.1, release builds, on the source of the change that added this row, on the adapters §5 lists: Metal on macOS 27.0.1 (arm64); headless Chromium 148, and a Chromium-based browser at 155, on that GPU; Vulkan on Linux x86_64 with the 0x10de and 0x8086 adapters (driver 595.84, Mesa 25.2.8) and, on another host, with the 0x1002 adapter (Mesa 26.0.8); and llvmpipe on both Linux hosts. On each, the probe (`tests/arith.rs`) agreed on every word of 1,051,757 cases, and the corpus (`tests/corpus.rs`) ran 813 vectors (1,104 decodes) on the 32-bit kernels and 1,426 (1,921 decodes) on the 64-bit ones, 212 of the decodes refusals, with no difference; 209 graphs use an operator outside the subset and ran on the CPU, and 95 vectors are refused at load. Run on the 32-bit kernels, 330 of the 613 graphs whose certificate does not meet `acc32` gave other results, so the width a graph runs at is the certificate's. Eighteen edits of one kernel expression each (a rounding shift or its addend off by one, a tie rule, a clamp bound moved by one, a dropped carry or cross term, a sign rule, a post bias, an index rule; `tests/mutants.rs`) were each caught by the corpus on every adapter, and an edited product by the probe. `wai-rs/tests/ops_gpu.rs` decoded the committed vectors and refusal fixtures of the six capabilities §5 names, the world renderer's two vectors and `wai.image.jpegai`'s `jpegai/v1` codestream, comparing every graph the device ran with the interpreter as well as each decode's bytes; none differed. The browser leg ran the corpus, not the decoders. `wai-ops-gpu.yml` runs the Metal and browser legs on the `macos` runner, where an absent adapter fails; this row records no forge run of it yet. No other workflow runs a GPU leg of these tests | `wai-ops-gpu/tests/`, `wai-ops-gpu/browser/`, `wai-rs/tests/ops_gpu.rs`; `.github/workflows/wai-ops-gpu.yml` |

View file

@ -0,0 +1,656 @@
# WAI Extension: Exact Tone Mapping
> Status: Draft. Registers two companions and a record. `wai.meta.gainmap` carries a gain map of
> ISO 21496-1:2025 (its metadata and its gain map image) as a companion of an image payload, and
> `wai.meta.st2094_50` carries the dynamic metadata of SMPTE ST 2094-50:2026-08 (Application #5)
> as a companion of a video payload. A sink presents the picture it decoded at its display's
> **headroom**, the ratio of its peak to the luminance of HDR reference white, as a `log2` value.
> Both standards state the computation from the base, the companion and the headroom in real
> numbers, so two sinks at one headroom compute it in their own floating point and present
> different pixels. This extension pins it in integer arithmetic: `wai-tonemap:gainmap` and
> `wai-tonemap:st2094-50` map the base's `RGB8` samples, the companion's bytes and a headroom,
> an integer in units of 1/10000 of a stop, to one `RGB16` rendition, with a stated
> fixed-point `log2`, a stated fixed-point `exp2`, and a stated rounding at every step. Every
> sink at a headroom presents the same bytes, and a verifier holding the base and the companion
> recomputes them. A sink that presents a rendition signs a **rendition record** naming the
> base, the companion, each headroom and the digest of each rendition. The derivation is a
> `convert` step of [synthesis](synthesis.md): it rebuilds what the base and the companion hold
> and generates nothing. No new transport. The reference implementation is the `exact_tonemap`
> module of `wai-rs` (feature `exact_tonemap`); the corpus is
> [`live-conformance/tonemap/`](../live-conformance/tonemap/), and its second implementation is
> `live-conformance/tonemap_verify.py`.
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
>
> Texts read for this revision: SMPTE ST 2094-50:2026-08, *Dynamic Metadata for Color Volume
> Transform — Application #5*, approved 2026-08-24, in its published text, every clause and
> annex (its figures were not read); the WAI texts this one cites; RFC 8032 and RFC 8785.
> **ISO 21496-1:2025** (first edition, *Digital photography — Gain map metadata for image
> conversion — Part 1: Dynamic range conversion*) **was not read**: its text is sold, and no
> part of it was obtained for this revision. What this extension states of it is what
> ST 2094-50:2026-08 says of it (its terms 3.1 to 3.11 cite ISO 21496-1:2025 clauses 3.1, 3.2,
> 3.4, 3.6, 5.2.6, 5.2.7 and 6.3) and what public, open-source readers of its binary metadata
> implement: the field list of §4.2 and the computation of §4.5. Each is marked where it is
> used. A revision that reads the standard confirms each against its text or corrects it.
## 1. Scope
In scope: the payloads of the two companions (§4.1, §5.1) and how their metadata reads (§4.2,
§5.2); the integer arithmetic the derivations share (§3); the two derivations (§4.4, §5.3 to
§5.6), each step mapped onto the standard's own computation (§4.5, §5.7); their error against
a floating-point evaluation of the same formulas (§6); the rendition record and its place in
synthesis's class lattice (§7); verification (§8).
Out of scope: a transport; how a sink measures its own headroom; a base in another transfer than
sRGB, a gain application colour space whose primaries differ from the base's, and the HDR
reference white's luminance in candelas, each of which this revision does not compute (§4.2,
§5.2); how a gain map is made from an HDR original, which is not part of the derivation (the
corpus's encoder is the reference's own, §10); the presentation of a rendition on a panel, which
takes the rendition's code values as linear drive values relative to the display's peak (§3.5)
and does with them what the panel does.
Relationship to the core spec: `wai.meta.gainmap` and `wai.meta.st2094_50` are
**companion-only** capabilities ([SPEC](../SPEC.md) §5, §7.1): each is applied with the rendition
it binds to and never decoded on its own. `wai.meta.gainmap` applies to a payload of the `image`
media class, `wai.meta.st2094_50` to one of the `video` media class, as SPEC §7.1's rule 2
states. `wai.media.tonemap` is a **record** ([SPEC](../SPEC.md) §5): a signed record a WAI tool
emits and verifies, which names no payload format and is not dispatchable. The two derivations
are terms of this extension, not `wai.derive.*` strings: the registry's derivation kind is the
operations of ISO/IEC 23001-16 ([derived-tracks](derived-tracks.md)), and a tone map is none of
them.
Relationship to [synthesis](synthesis.md): a rendition is a `convert` of its inputs (synthesis
§3.2): it rebuilds, at the display's headroom, what the base and the companion together hold,
names no model and generates nothing; its class is the greatest of `reconstructed` and its
inputs' classes, so a rendition of a synthesized picture is synthesized (§7.2).
Relationship to [determinism-tiers](determinism-tiers.md): display adaptation changes the
decoded medium, so a tier covers a rendition only if its computation is pinned (determinism-tiers
§2, *What a tier covers*). The derivations are integer throughout, so a rendition is a pure
function of the base's samples, the companion's bytes and the headroom, and a sink that presents
it holds the tier of the decode it ran on.
## 2. Records and buffers
The record of this extension (§7) is a JSON object under the encodings of
[synthesis](synthesis.md) §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](jwp-receipts.md) §2.4.3 defines them, no member named twice, at most 32 levels of
nesting, exactly the members §7.1 lists at every level, and a `kind` naming the record; one that
does not is `record_malformed`. It carries `signer_pubkey` (32 bytes) and `sig` (64 bytes):
```
sig = Ed25519(signer_key, "wai:tonemap\x01" || JCS(record without "sig"))
link_hash = BLAKE3("wai:tonemap-link\x01" || JCS(record))
```
JCS is RFC 8785. 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 **base** picture is an `RGB8` buffer (rows top to bottom, pixels left to right, three bytes a
pixel, R, G, B, no padding), read as sRGB-coded (IEC 61966-2-1, as ST 2094-50:2026-08 Formula
(A.2) restates it). A **rendition** is an `RGB16` buffer: the same order, three unsigned 16-bit
samples a pixel, each written little-endian. A buffer's **digest** is SHA-256 (FIPS 180-4) over
it. An envelope's **content hash** is [jwp-receipts](jwp-receipts.md) §2.1's.
## 3. Integer arithmetic
### 3.1 Notation
Every value is an integer. ⌊*a* / *b*⌋, for *b* > 0, is the floor of the quotient, also for a
negative *a*. rnd(*a*, *b*) = ⌊(*a* + ⌊*b* / 2⌋) / *b*⌋ for *b* > 0: the integer nearest *a* / *b*,
halves upward, for either sign of *a*. clamp(*v*, *lo*, *hi*) = min(max(*v*, *lo*), *hi*).
A value in **Q*n*** stands for itself divided by 2^*n*: a `log2` value in Q16 is in units of
1/65536 of a stop, a linear light value in Q30 is in units of 2^−30 of HDR reference white. No
intermediate value of this section or of §4 and §5 needs more than 127 bits and a sign; an
implementation computes each exactly.
### 3.2 `L2`: a fixed-point `log2`
For an integer *v* ≥ 1, L2(*v*) is a Q16 approximation of log2(*v*) from below:
1. *n* is the bit length of *v* less 1, so 2^*n* ≤ *v* < 2^(*n*+1).
2. *m* = *v* · 2^(30 − *n*) where *n* ≤ 30, and ⌊*v* / 2^(*n* − 30)⌋ otherwise: the mantissa in
Q30, 2^30 ≤ *m* < 2^31.
3. *f* = 0; for *i* = 1 to 16 in turn: *m* = ⌊*m*² / 2^30⌋; where *m* ≥ 2^31, *m* = ⌊*m* / 2⌋
and *f* = *f* + 2^(16 − *i*).
4. L2(*v*) = *n* · 2^16 + *f*.
Step 3 is the bitwise logarithm: each squaring doubles the fractional part, and a mantissa past
2 gives the next bit. Every squaring truncates.
### 3.3 `E2`: a fixed-point `exp2`, and scaling by it
For a Q16 integer *y*, E2(*y*) is a pair (*p*, *e*) with 2^(*y* / 2^16) ≈ *p* · 2^(*e* − 30):
1. *e* = ⌊*y* / 2^16⌋ and *f* = *y* − 2^16 · *e*, 0 ≤ *f* < 2^16.
2. *p* = 2^30; for *i* = 1 to 16 in turn, where bit 16 − *i* of *f* is 1, *p* = rnd(*p* ·
*K*ᵢ, 2^30).
*K*ᵢ is 2^(2^−*i*) in Q30, made by integer square roots: *R*₀ = 2^61, *R*ᵢ = ⌊√(*R*ᵢ₋₁ ·
2^60)⌋ (each a Q60 value, the integer square root rounded down), and *K*ᵢ = rnd(*R*ᵢ, 2^30):
| *i* | *K*ᵢ | *i* | *K*ᵢ | *i* | *K*ᵢ | *i* | *K*ᵢ |
|---|---|---|---|---|---|---|---|
| 1 | 1518500250 | 5 | 1097253708 | 9 | 1075196443 | 13 | 1073832680 |
| 2 | 1276901417 | 6 | 1085434106 | 10 | 1074468888 | 14 | 1073787251 |
| 3 | 1170923762 | 7 | 1079572136 | 11 | 1074105294 | 15 | 1073764537 |
| 4 | 1121280436 | 8 | 1076653033 | 12 | 1073923544 | 16 | 1073753181 |
`scale`(*X*, *y*, *F*), for an integer *X* and a Q16 *y*, is *X* · 2^(*y* / 2^16) / 2^*F* as an
integer: with (*p*, *e*) = E2(*y*) and *t* = *e* − 30 − *F*, it is *X* · *p* · 2^*t* where *t* ≥ 0,
and rnd(*X* · *p*, 2^−*t*) otherwise.
Since both functions are functions of one integer, an implementation MAY tabulate them, or
compute them any other way that gives the same integers: a table of E2 over the 2^16 values of
*f* is the same function.
### 3.4 `S`: the base's samples in linear light
S[*k*], for each sample value *k* from 0 to 255, is the sRGB decode of *k* / 255 in Q30, with
HDR reference white at 2^30 (an sRGB-coded sample of 255 is reference white, ST 2094-50:2026-08
Note 4 to Formula (A.1)):
- for *k* ≤ 10: S[*k*] = rnd(*k* · 100 · 2^30, 255 · 1292), the linear segment *k* / 255 / 12.92
(*k* / 255 ≤ 0.04045 exactly when *k* ≤ 10);
- for *k* ≥ 11: with λ = L2(1000 · *k* + 14025) − L2(269025), the Q16 `log2` of
(*k* / 255 + 0.055) / 1.055, S[*k*] = `scale`(2^30, rnd(12 · λ, 5), 0): that value to the
power 2.4.
S[255] = 2^30 exactly.
### 3.5 The rendition's code values
A sink presents a rendition to a display of headroom *h*, an integer from 0 to 60000 in units of
1/10000 of a stop (the unit ST 2094-50:2026-08 Annex C encodes headrooms in): the display's
peak is 2^(*h* / 10000) times HDR reference white. *H*ₜ = rnd(*h* · 2^16, 10000) is *h* in Q16.
A rendition's code value is linear light relative to the display's peak, at 16 bits: a
linear value *T* (Q30, relative to reference white) is presented as
code(*T*) = clamp(`scale`(*T* · 65535, −*H*ₜ, 30), 0, 65535),
so the display's peak is 65535 and a value past it is clamped, the projection of
ST 2094-50:2026-08 Clause A.4, Note. Each derivation forms its value and its exponent together
and rounds once (§4.4 step 7, §5.6).
## 4. Gain maps: `wai.meta.gainmap` and `wai-tonemap:gainmap`
### 4.1 The payload: `WGM1`
A `wai.meta.gainmap` payload is a `WGM1` frame. WAI's own fields are little-endian.
| off | size | field | rule |
|---|---|---|---|
| 0 | 4 | magic `WGM1` | |
| 4 | 1 | version | `1` |
| 5 | 1 | reserved | `0` |
| 6 | 2 | `md_len` | 1 to 4096: the metadata's length |
| 8 | `md_len` | metadata | ISO 21496-1:2025 metadata in its binary form (§4.2), as written |
| 8 + `md_len` | the rest | gain map image | one PNG file (W3C PNG, Third Edition) of 8-bit samples, colour type 0 (one channel) or 2 (three), no interlace |
A frame that breaks a rule of this table, or whose image is not such a PNG, or does not decode,
is `companion_malformed`. Nothing follows the PNG's `IEND` chunk.
### 4.2 The metadata
The metadata is ISO 21496-1:2025's binary form. **This revision did not read ISO 21496-1**; the
fields below are the ones public, open-source readers of the form read, in their order, with
the names they give. Its multi-byte fields are big-endian.
| size | field | type |
|---|---|---|
| 2 | `minimum_version` | unsigned |
| 2 | `writer_version` | unsigned |
| 1 | `is_multichannel` (bit 7), `use_base_colour_space` (bit 6), six reserved bits | |
| 4 + 4 | `base_hdr_headroom` numerator, denominator | unsigned, unsigned |
| 4 + 4 | `alternate_hdr_headroom` numerator, denominator | unsigned, unsigned |
| per channel, 1 or 3 times (3 where `is_multichannel` is 1) | | |
| 4 + 4 | `gain_map_min` numerator, denominator | signed, unsigned |
| 4 + 4 | `gain_map_max` numerator, denominator | signed, unsigned |
| 4 + 4 | `gamma` numerator, denominator | unsigned, unsigned |
| 4 + 4 | `base_offset` numerator, denominator | signed, unsigned |
| 4 + 4 | `alternate_offset` numerator, denominator | signed, unsigned |
Each pair is the rational numerator / denominator. Headrooms, `gain_map_min` and `gain_map_max`
are `log2` values. A reader, in this order:
1. refuses metadata whose `minimum_version` is not 0 with `metadata_unsupported`: a reader does
not apply metadata whose minimum version it does not know;
2. refuses metadata shorter than its fields, or whose `writer_version` is below its
`minimum_version`, or, with a `writer_version` of 0, longer than its fields, with
`metadata_malformed`; bytes after the fields of metadata of a later `writer_version` are read
past, and the reserved bits are not read;
3. refuses with `metadata_out_of_range` metadata outside the range this revision computes: a
denominator of 0; a headroom past 6 (the range of ST 2094-50:2026-08 §6.2.2); two equal
headrooms, between which no weight is defined; a `gain_map_min` or `gain_map_max` past 16 in
magnitude, or a `gain_map_min` greater than its `gain_map_max`; a `gamma` of 0 or outside
1/64 to 64; a `base_offset` or `alternate_offset` past 1 in magnitude;
4. refuses metadata whose `use_base_colour_space` is 0 with `gain_space_unsupported`: its gain is
applied in the alternate image's colour space, which a conversion of primaries reaches, and
this revision computes none.
Then, for each channel *j*: min*ⱼ* and max*ⱼ* in Q16 are rnd(*n* · 2^16, *d*) of `gain_map_min`
and `gain_map_max`; *bo*ⱼ and *ao*ⱼ in Q30 are rnd(*n* · 2^30, *d*) of `base_offset` and
`alternate_offset`; γⱼ is the rational `gamma` itself. A single-channel map applies its one set
to all three channels.
### 4.3 The gain map image
The PNG's colour type is 0 for metadata whose `is_multichannel` is 0, and 2 where it is 1
(`map_channels_mismatch`). Its size is *g*w × *g*h, and the base's *w* × *h*: *s* = *w* / *g*w is
an integer of 1, 2, 4 or 8, and *h* = *s* · *g*h (`map_dimensions_mismatch`). *g*(*x*, *y*) is
its sample at column *x* and row *y*, of channel *j*.
### 4.4 `wai-tonemap:gainmap`
`wai-tonemap:gainmap` maps a base of *w* × *h*, a `wai.meta.gainmap` payload that reads
(§4.1 to §4.3) and a headroom *h*ᵈ (§3.5) to a rendition of *w* × *h*. With *H*b =
`base_hdr_headroom` = *b*n / *b*d, *H*a = `alternate_hdr_headroom` = *a*n / *a*d and *H*ₜ =
rnd(*h*ᵈ · 2^16, 10000):
1. **Weight.** *A* = *h*ᵈ · *b*d · *a*d − 10000 · *b*n · *a*d and *D* = 10000 · (*a*n · *b*d −
*b*n · *a*d), so *A* / *D* = (*h*ᵈ / 10000 − *H*b) / (*H*a − *H*b). Where *D* > 0, *W* =
clamp(rnd(*A* · 2^16, *D*), 0, 2^16); where *D* < 0, *W* = −clamp(rnd(−*A* · 2^16, −*D*), 0,
2^16). *W* is in Q16, and is negative where the alternate's headroom is below the base's.
For each pixel (*x*, *y*) and each of its channels *c*, with *j* = *c* for a three-channel map and
*j* = 0 for a single-channel one:
2. **Base.** *B* = S[base(*x*, *y*)[*c*]].
3. **The map's sample at the pixel.** *X* = max(0, 2*x* + 1 − *s*), *x*₀ = ⌊*X* / 2*s*⌋,
*ax* = *X* − 2*s* · *x*₀ and *x*₁ = min(*x*₀ + 1, *g*w − 1); *Y*, *y*₀, *ay* and *y*₁ the same
from *y* and *g*h. Then *N* = *g*(*x*₀, *y*₀) · (2*s* − *ax*) · (2*s* − *ay*) + *g*(*x*₁, *y*₀) ·
*ax* · (2*s* − *ay*) + *g*(*x*₀, *y*₁) · (2*s* − *ax*) · *ay* + *g*(*x*₁, *y*₁) · *ax* · *ay*, and
*Q* = 255 · 4*s*²: the map's normalised sample is *N* / *Q*, a centre-aligned bilinear
interpolation of its codes, the edges repeated. With *s* = 1 it is the sample itself.
4. **Recovery.** *v* (Q30) = rnd(*N* · 2^30, *Q*) where γⱼ = 1; 0 where *N* = 0; otherwise, with
γⱼ = *γ*n / *γ*d, λ = L2(*N*) − L2(*Q*) and *v* = `scale`(2^30, rnd(λ · *γ*d, *γ*n), 0): the
sample raised to 1/γⱼ.
5. **Log gain.** *L* (Q16) = rnd(minⱼ · (2^30 − *v*) + maxⱼ · *v*, 2^30).
6. **Weighted gain.** *G* (Q16) = rnd(*L* · *W*, 2^16).
7. **Output.** *P* = `scale`((*B* + *bo*ⱼ) · 65535, *G* − *H*ₜ, 0) − `scale`(*ao*ⱼ · 65535, −*H*ₜ,
0), and the rendition's sample is clamp(rnd(*P*, 2^30), 0, 65535): code((*B* + *bo*) ·
2^(*L* · *W*) − *ao*) of §3.5, both terms in Q30 of a code value and rounded once.
The rendition at a headroom at or past the alternate's is the alternate image the map was made
from, within the error of §6; at the base's headroom (*W* = 0) it is the base, offsets
cancelling where they are equal.
### 4.5 Against ISO 21496-1's computation
The computation the integer steps reproduce is the one the public readers of §4.2 implement:
with the base's linear value *B*, the map's sample *g* in [0, 1] at the pixel, and the weight
*W* = clamp((*H*ₜ − *H*b) / (*H*a − *H*b), 0, 1), negated where *H*a < *H*b,
*L* = min + (max − min) · *g*^(1/γ), *T* = (*B* + *bo*) · 2^(*L* · *W*) − *ao*.
ST 2094-50:2026-08 term 3.7 names ISO 21496-1:2025 clause 6.3 as the algorithm that produces an
image at a targeted HDR headroom from per-pixel metadata; this revision did not read that clause
(header note). Step by step:
| step | real-number form | integer form (§4.4) | what is pinned |
|---|---|---|---|
| base to linear | sRGB decode of *k* / 255 | S[*k*] (§3.4) | `L2`, `E2`, one rounding each |
| the map at the pixel | upsampled by a filter each implementation chooses | step 3: bilinear, centre-aligned, edges repeated, exact | the filter itself |
| recovery | *g*^(1/γ) | step 4 | Q30, through Q16 `log2` |
| log gain | min + (max − min) · *g*^(1/γ) | step 5 | Q16 |
| weight | clamp of a ratio of headrooms | step 1, exact rational, rounded once | Q16 |
| gain and offsets | (*B* + *bo*) · 2^(*L* · *W*) − *ao* | step 7 | Q30, through Q16 `exp2` |
| presentation | *T* / 2^*H*ₜ at the display's peak | §3.5 | 16-bit code values |
The upsampling filter is where two floating-point sinks differ most, and the standard, as far
as this revision knows it, leaves it to the implementation. The derivation fixes it.
## 5. ST 2094-50: `wai.meta.st2094_50` and `wai-tonemap:st2094-50`
### 5.1 The payload: `WD50`
A `wai.meta.st2094_50` payload is a `WD50` frame: the metadata sets of a video, each with the
frames it applies to. ST 2094-50:2026-08 carries one metadata set with the frames it applies to
by ITU-T T.35 messages in a codec or a container (its §7.3), and its Annex C encoding holds no
time; the frame gives each set its frames, the TimeInterval of its §7.1, in frames of the base.
WAI's own fields are little-endian.
| off | size | field | rule |
|---|---|---|---|
| 0 | 4 | magic `WD50` | |
| 4 | 1 | version | `1` |
| 5 | 1 | reserved | `0` |
| 6 | 2 | `n_sets` | 1 to 256 |
| 8 | … | the sets | `n_sets` sets, one after another; nothing follows the last |
A set:
| size | field | rule |
|---|---|---|
| 4 | `first_frame` | the index of its first frame, frames counted from 0 |
| 4 | `frame_count` | 1 or more |
| 2 | `len` | 1 to 4096 |
| `len` | the set | one `smpte_st_2094_50_application_info()` of ST 2094-50:2026-08 Annex C, as written |
Each set's `first_frame` is at least the end of the set before it (its `first_frame` plus its
`frame_count`), and no end passes 2^32 − 1. A frame that breaks a rule of these tables is
`companion_malformed`.
### 5.2 Reading a metadata set
A set reads as ST 2094-50:2026-08 Annex C has it: each syntax element of type u(N) an N-bit
unsigned integer, most significant bit first, and the structures of its Tables C.1 to C.5 in
order. The reader, in this order:
1. refuses a set whose `minimum_application_version` is not 0 with `metadata_unsupported`: Annex
C.2.1 has a parser ignore the whole bitstream;
2. refuses a set that ends inside a structure, or holds a `reserved_zero` element that is not 0
(Annex C.1), with `metadata_malformed`. Bytes after the last element are padding and are not
read (Annex C.2.1);
3. assigns the metadata items as Annex C.3 does: HDR reference white, 203 or clamp(·, 1,
50000) / 5 (C.3.3); headrooms min(·, 60000) / 10000 (C.3.4); `NumAlternateImages`
min(·, 4); component mixing (C.3.6); gain curves, with the sign *s* of C.3.7, *x* = min(·,
64000) / 1000 and *y* = *s* · min(·, 60000) / 10000, and each slope from its angle or by
C.3.9 (§5.4);
4. refuses with `metadata_out_of_range` a set that breaks a constraint of ST 2094-50:2026-08
§6.2.2, §6.4.2 or §6.5.2 (an alternate headroom equal to the baseline's, alternate headrooms
not increasing, mixing weights that sum to 0, control points whose *x* decreases, or two of one
*x* with different *y*), or whose gain curve's last control point has *x* = 0, beyond which
Formula (12) is not finite;
5. refuses with `gain_space_unsupported` a set whose `use_reference_white_tone_mapping_flag` is
1, whose gain application colour space C.3.8 sets to the primaries of ITU-R BT.2020, or whose
`gain_application_space_chromaticities_mode` is not 0, the primaries and white point of ITU-R
BT.709: this revision applies gains in the base's primaries, those of sRGB, and converts none.
The recommended constraints of §6.2.3 are not checked: §6.2.3 lets an implementation adjust
metadata to meet them, and the derivation applies the metadata as it reads.
For a base read as sRGB-coded (§2), the conversion of ST 2094-50:2026-08 Formula (A.3)
divides the luminance of Formula (A.2) by the HDR reference white it was formed with, so the
value in the gain application colour space is S[*k*] of §3.4 and the reference white's value in
candelas does not enter. A set with no headroom-adaptive tone map (`has_adaptive_tone_map_flag`
0) leaves the choice to the output system (its Clause A.3); the derivation then applies none,
as a set with no alternate images does (its Clause B.4): the rendition is the base, projected
(§3.5).
### 5.3 The parameters as integers
- **Headrooms** *H* in units of 1/10000 of a stop: the Annex C values, min(·, 60000).
- **Mixing weights** in units of 1/150000: type 0, *k*max = 150000; type 1, *k*component =
150000; type 2, *k*red = *k*green = *k*blue = 25000 and *k*max = 75000; type 3, each
coefficient 3 · min(·, 50000); every other weight 0. *k*sum is their sum.
- **Control points**: *X*ᵢ = min(·, 64000), *x* in units of 1/1000; *Y*ᵢ = *s* · min(·,
60000), *y* in units of 1/10000; slopes *m*ᵢ in Q30 (§5.4).
### 5.4 Slopes
**From an angle** (C.3.7, `gain_curve_use_pchip_slope_flag` 0): *m* = tan((clamp(θ, 1, 35999) −
18000) · π / 36000). With *d* = clamp(θ, 1, 35999) − 18000, *P* = ⌊π · 2^62⌋ =
14488038916154245684 and the angle in Q62 *a* = rnd(*d* · *P*, 36000), and *a*² in Q62 *q* =
rnd(*a* · *a*, 2^62):
- sine: *t* = *a*, *σ* = *a*; for *k* = 1 to 15 in turn, *t* = rnd(−*t* · *q*, 2^62 · 2*k* ·
(2*k* + 1)) and *σ* = *σ* + *t*;
- cosine: *t* = 2^62, *κ* = 2^62; for *k* = 1 to 15 in turn, *t* = rnd(−*t* · *q*, 2^62 · (2*k* −
1) · 2*k*) and *κ* = *κ* + *t*;
- *m* = rnd(*σ* · 2^30, *κ*).
The angle is within π/2 of 0, so *κ* > 0, and fifteen terms of each series leave a remainder below
2^−62.
**By PCHIP** (C.3.9, flag 1): each slope of C.3.9 is a rational function of the control points,
computed exactly, and rounded once to Q30. With *h*ᵢ = *X*ᵢ₊₁ − *X*ᵢ and Δᵢ = *Y*ᵢ₊₁ − *Y*ᵢ, the
slope of interval *i* is *s*ᵢ = Δᵢ / (10 · *h*ᵢ) stops per unit of *x*, and 0 where *h*ᵢ = 0
(Formula (C.7)). The interior rule (C.8), the endpoint rules (C.9, C.10) with their sign tests
and their cap at 3 · |*s*|, and the degenerate case are C.3.9's, each comparison made on the exact
rationals; the slope chosen, a rational, is *m* = rnd(numerator · 2^30, denominator) with a
positive denominator.
### 5.5 Component mixing and the gain curve
**Mixing** (Formulas (9), (10)): for a colour *C* = (*c*r, *c*g, *c*b) in Q30,
*M*ⱼ = rnd(*c*ⱼ · *k*component + *k*red · *c*r + *k*green · *c*g + *k*blue · *c*b + *k*max ·
max(*C*) + *k*min · min(*C*), *k*sum), in Q30.
**The gain curve** (Formulas (11), (12)) at *M* in Q30, against 1000 · *M* and *X*ᵢ · 2^30, its
value *G* in Q16:
- 1000 · *M* < *X*₀ · 2^30: *G* = rnd(*Y*₀ · 2^16, 10000);
- 1000 · *M* = *X*ᵢ · 2^30 for some *i*: *G* = rnd(*Y*ᵢ · 2^16, 10000);
- *X*ᵢ · 2^30 < 1000 · *M* < *X*ᵢ₊₁ · 2^30: the cubic of Formula (11). With *t* = rnd(1000 · *M*
− *X*ᵢ · 2^30, *h*ᵢ) (Q30), *Y*′ᵢ = rnd(*Y*ᵢ · 2^30, 10000) (Q30) and *m̂*ᵢ = rnd(*h*ᵢ · *m*ᵢ,
1000) (Q30), the coefficients *c*₃ = 2*Y*′ᵢ + *m̂*ᵢ − 2*Y*′ᵢ₊₁ + *m̂*ᵢ₊₁, *c*₂ = −3*Y*′ᵢ +
3*Y*′ᵢ₊₁ − 2*m̂*ᵢ − *m̂*ᵢ₊₁, *c*₁ = *m̂*ᵢ and *c*₀ = *Y*′ᵢ are evaluated by Horner's rule, *u* =
rnd(*c*₃ · *t*, 2^30) + *c*₂, then *u* = rnd(*u* · *t*, 2^30) + *c*₁, then *u* = rnd(*u* · *t*,
2^30) + *c*₀, and *G* = rnd(*u*, 2^14);
- 1000 · *M* > *X*ₙ₋₁ · 2^30, past the last control point: *G* = rnd(*Y*ₙ₋₁ · 2^16, 10000) +
L2(*X*ₙ₋₁ · 2^30) − L2(1000 · *M*), the term log2(*x*ₙ₋₁ / *x*) that holds the tone curve
*x* · 2^*G* level.
The colour gain function of an alternate image is the curve at each of *M*'s three components
(Formula (7)); the zero function's is 0 (Formula (8)).
### 5.6 `wai-tonemap:st2094-50`
`wai-tonemap:st2094-50` maps a frame of a base of *w* × *h*, a `wai.meta.st2094_50` payload
that reads (§5.1, §5.2), the set whose frames include the frame's index (`frame_uncovered`
where none does), and a headroom *h*ᵈ (§3.5) to a rendition of *w* × *h*. Following §6.2.5:
the baseline headroom is placed among the alternates' in sorted position, *H*₀ < … < *H*ₙ₋₁,
with the zero gain function at its place; *h*c = clamp(*h*ᵈ, *H*₀, *H*ₙ₋₁). For each pixel, *C*
= (S[*r*], S[*g*], S[*b*]) of its samples, and the gain *G* of each component (Q16) is:
- Gainᵢ(*C*) where *h*c = *H*ᵢ (Formula (2));
- otherwise, for the one *i* with *H*ᵢ < *h*c < *H*ᵢ₊₁, rnd(Gainᵢ(*C*) · (*H*ᵢ₊₁ − *h*c) +
Gainᵢ₊₁(*C*) · (*h*c − *H*ᵢ), *H*ᵢ₊₁ − *H*ᵢ) (Formulas (3), (4), exact in the weights and
rounded once).
Each component of the rendition is clamp(`scale`(*c* · 65535, *G* − *H*ₜ, 30), 0, 65535) with
*H*ₜ = rnd(*h*ᵈ · 2^16, 10000): code(*C* · 2^*G*) of §3.5 (Formula (5)), rounded once.
### 5.7 Against ST 2094-50's computation
| ST 2094-50:2026-08 | real-number form | integer form | what is pinned |
|---|---|---|---|
| Formula (A.2), (A.3) | sRGB decode, over reference white | S[*k*] (§3.4) | `L2`, `E2` |
| C.3.7 | *m* = tan of the angle | §5.4, series in Q62, *m* in Q30 | the series and its rounding |
| C.3.9 | PCHIP slopes | §5.4, exact rationals, rounded once | Q30 |
| (9), (10) | weighted mix over *k*sum | §5.5, rounded once | Q30 |
| (11) | cubic Hermite in *t* | §5.5, Horner in Q30 | each product's rounding |
| (12) | *y* + log2(*x*ₙ₋₁ / *x*) | `L2` difference | Q16 |
| (2) to (4) | weights of headrooms | §5.6, exact, rounded once | Q16 |
| (5) and A.4 | *C* · 2^*G*, projected at the display | §5.6 and §3.5 | 16-bit code values |
Every formula of §6 of ST 2094-50:2026-08 has an integer step above, and every value in it is
the one Annex C assigns from the bits.
## 6. Error against floating point
The derivations round where the standards compute in real numbers, so a rendition differs from
a floating-point evaluation of the same formulas by a little. The reference measures it over
every rendition of the corpus: the same steps in IEEE 754 binary64 (sRGB decoding by
`pow`, `log2`, `exp2` and `tan` of the platform library, the same bilinear weights, the PCHIP
slopes in binary64), each code value rounded to nearest and clamped as §3.5 has it, against the
integer rendition's:
| derivation | renditions | samples | largest difference | mean difference |
|---|---|---|---|---|
| `wai-tonemap:gainmap` | 10 | 41472 | 2 | 0.1269 |
| `wai-tonemap:st2094-50` | 25 | 172800 | 2 | 0.1642 |
in code values of 65535. The corpus states the same figures (`measurement`), and its test
fails when they change. A difference is the integer derivation's distance from that one
floating-point evaluation; another floating-point implementation differs from it as well, by
its own rounding and its own upsampling filter, and it is that spread which the derivation
removes.
## 7. The rendition record
### 7.1 The record
A sink that presents renditions signs a **rendition record**, `kind` `"wai-tonemap"`, for them,
under a key of its session or of its own (the record names no viewer). A party that publishes a
rendition signs one for what it published.
| member | type | meaning |
|---|---|---|
| `kind` | string | `"wai-tonemap"` |
| `derivation` | term | `wai-tonemap:gainmap` or `wai-tonemap:st2094-50` |
| `base` | object | `{"object", "rendition", "width", "height"}`: the content hash of the envelope that carries the base and the companion; the index of the base's entry among its `renditions` (0 for a `WAI1`); and the base's size, each 1 to 4096 |
| `companion` | object | `{"index", "sha256"}`: the index of the companion's entry, and the SHA-256 of its payload |
| `pictures` | array | 1 to 256 entries, each `{"frame", "headroom", "input", "output"}`: the frame's index (0 for a still), the headroom (§3.5, 0 to 60000), the digest of the base frame's `RGB8` samples, and the digest of the rendition's `RGB16` samples; no two entries with the same frame and headroom, and entries in increasing order of frame, then of headroom |
| `class` | string | the class of the renditions (§7.2) |
| `inputs` | array | 1 to 16 entries, each `{"content_hash", "origin", "class"}`: an object the derivation read, the link hash of its origin claim ([synthesis](synthesis.md) §3.1) or `null`, and that claim's class, restated; one of them is `base.object`, and no content hash appears twice |
| `issued_at` | date-time | when it signed it |
| `signer_pubkey`, `sig` | | §2 |
A `wai-tonemap:gainmap` record's pictures are all of frame 0. `class` and an input's `class` are
one of `captured`, `reconstructed`, `assistive` and `synthesized`. A record that breaks a rule of
this table is `record_malformed`; one whose headroom passes 60000 is `headroom_out_of_range`.
### 7.2 Provenance
A rendition is a `convert` step of [synthesis](synthesis.md) §3.2. It rebuilds what its inputs
hold: the base's samples, and, at a headroom, the alternate rendering the companion states of
them. It names no model, asserts no source of its own and makes no evidence claim: there is no
edit to check, only a computation to repeat, and §8 repeats it. Its class is the greatest of
`reconstructed` and its inputs' classes, so a rendition never stands lower than what it was made
from: a rendition of a captured photograph is `reconstructed`, and one of a synthesized picture
is `synthesized`. A record whose `class` is another is `class_mismatch`.
Where a rendition is published as an object, its origin claim is a `convert` claim whose inputs
are the inputs of its record (synthesis §3.4, the row for a decoder's reconstruction), and its
record is the claim's `record`.
## 8. Verification
### 8.1 Inputs
A verifier is given, each in a list: rendition records; the envelopes it holds, each named by its
content hash; the decoded frames it holds, each the `RGB8` samples of one frame of the base of an
envelope, named by the envelope's content hash and the frame's index (a verifier that decodes a
base itself holds its frames; the base of a `wai.image.png` entry is decoded by its PNG); and a
**policy**:
| member | values | default | meaning |
|---|---|---|---|
| `tonemap` | `accept-unrecomputed`, `require-proof` | `accept-unrecomputed` | `require-proof`: a picture the verifier does not recompute is refused (step 6) |
### 8.2 Steps
The verifier runs these steps over each record in order and stops at the first refusal, which it
reports with the reason and where: the record by its index (`["record", i]`), a picture of it by
both (`["record", i, "picture", j]`).
1. **Reading.** In this order: the record reads (§2, §7.1, `record_malformed`), its signature
verifies (`bad_key`, `bad_signature`), and no picture's headroom passes 60000
(`headroom_out_of_range`).
2. **Class.** The record's `class` is §7.2's: `class_mismatch`.
3. **The envelope**, where the verifier holds the one `base.object` names:
1. it parses ([SPEC](../SPEC.md) §2, §7.1) and every component conforms to SPEC §7.1's rules
and to the role SPEC §5 gives its capability (the reference
`WaiMulti::check_component_roles`): otherwise `envelope_nonconforming`;
2. entry `base.rendition` is a selectable rendition, entry `companion.index` a companion bound
to it (SPEC §7.1, *Companion components*) whose capability is the derivation's
(`wai.meta.gainmap` for `wai-tonemap:gainmap`, `wai.meta.st2094_50` for
`wai-tonemap:st2094-50`), and the SHA-256 of the companion's payload is `companion.sha256`:
otherwise `companion_mismatch`;
3. the companion reads: §4.1 to §4.3, or §5.1 and §5.2, in their order, each with its reason.
4. **Each picture**, in order, where the verifier holds its frame:
1. for `wai-tonemap:st2094-50`, a set of the companion covers the frame (`frame_uncovered`);
2. the frame's samples are `width` · `height` · 3 bytes and their digest is `input`
(`input_samples_mismatch`); for `wai-tonemap:gainmap`, the map's size fits the base's
(§4.3, `map_dimensions_mismatch`);
3. the derivation of §4.4 or §5.6 at the picture's headroom gives a rendition whose digest is
`output` (`rendition_mismatch`). The picture is then **proved**.
A picture whose frame or companion the verifier does not hold is **not recomputed**.
5. Nothing else is read: a picture's output is never compared with anything but its
recomputation.
6. Under `tonemap` `require-proof`, a picture that is not proved: `rendition_not_proved`.
### 8.3 What an accepted case states
For each record, in order: its link hash, its class, and for each picture, in order, `proved` or
`not-recomputed`.
## 9. Reasons
The codes this extension adds, each with where it is raised:
| reason | raised at |
|---|---|
| `record_malformed` | §2, §7.1, §8.2 step 1 |
| `bad_key` | §2 |
| `bad_signature` | §2 |
| `headroom_out_of_range` | §7.1, §8.2 step 1 |
| `class_mismatch` | §7.2, §8.2 step 2 |
| `envelope_nonconforming` | §8.2 step 3.1 |
| `companion_mismatch` | §8.2 step 3.2 |
| `companion_malformed` | §4.1, §5.1 |
| `metadata_unsupported` | §4.2 step 1, §5.2 step 1 |
| `metadata_malformed` | §4.2 step 2, §5.2 step 2 |
| `metadata_out_of_range` | §4.2 step 3, §5.2 step 4 |
| `gain_space_unsupported` | §4.2 step 4, §5.2 step 5 |
| `map_channels_mismatch` | §4.3 |
| `frame_uncovered` | §5.6, §8.2 step 4.1 |
| `input_samples_mismatch` | §8.2 step 4.2 |
| `map_dimensions_mismatch` | §4.3, §8.2 step 4.2 |
| `rendition_mismatch` | §8.2 step 4.3 |
| `rendition_not_proved` | §8.2 step 6 |
A sink that is given an envelope which breaks SPEC §7.1's component rules reports SPEC's own code
for the break (`companion-only-as-capability`, `companion-only-as-rendition`,
`incompatible-base`, …); a verifier reports the record over it as `envelope_nonconforming`.
## 10. Conformance
[`live-conformance/tonemap/`](../live-conformance/tonemap/) holds the corpus, written by
`wai_tonemap_vectors gen` from fixed seeds and from the integer video corpus: `vectors.json`
(with the arithmetic of §3 and §5.4 at stated points and over whole ranges: `L2`, `E2`, the
table S, `tan` of every angle and the slopes of the video's curves, which a rendition of the
corpus would not always expose), the envelopes it names in `envelopes/`, and `frames.rgb8`, the five frames of the `int_video` clip
of `wai-rs/tests/vectors/int_video/` as `wai.video.int_motion` decodes them (their digests are
that clip's sidecar's). Its stills are generated: an HDR scene made from integer formulas,
rendered to an sRGB base and a gain map by the reference's own encoder, which is integer
throughout and pinned by its code, not by this text. It has:
- **Accepted**: a single-channel map at a quarter of the base's size and a three-channel map at
full size with a `gamma` of 2, each at several headrooms from the base's to past the
alternate's; a map whose alternate's headroom is below the base's (a negative weight); and the
int_video clip under two metadata sets, one with slopes from angles and two alternates, one
with PCHIP slopes, component mixing of types 2 and 3, at headrooms between, on and past the
alternates'; a record whose base is a synthesized picture, `synthesized`; and the envelopes
that carry each, which conform.
- **Refused**: each reason of §9 at least once, each a control of one defect: among them a
rendition at another headroom than the one stated (`rendition_mismatch`), a headroom past 6
stops (`headroom_out_of_range`), a map whose size does not divide the base's
(`map_dimensions_mismatch`), metadata out of range in each companion
(`metadata_out_of_range`), a rendition one sample of which was changed (`rendition_mismatch`),
and a gain map carried as a rendition rather than a companion (`envelope_nonconforming`); and
envelopes that break SPEC §7.1, each with SPEC's code: a gain map as a `WAI1`'s capability, a
gain map as a selectable rendition, a gain map bound to a video, ST 2094-50 metadata bound to an
image.
A conforming verifier gives every case the outcome, the reason, the place and the statements the
corpus states. `wai_tonemap_vectors verify` and the test `tests/exact_tonemap.rs` check that the
corpus regenerates byte for byte, that `wai-rs` gives every case its outcome, that §9 lists
exactly the reference's codes, that §6's figures are the corpus's, and that `frames.rgb8` is the
decode of the `int_video` clip. `live-conformance/tonemap_verify.py` is the second
implementation, written from this text: it shares no code with `wai-rs`; it computes both
derivations in integer arithmetic of its own, reads PNG, the envelopes and both companions
itself, recomputes §6's figures within one code value of the largest and 0.01 of the mean, reads
§9's codes from this text, mutates copies of the corpus and requires every copy to be refused, and
drops each of its own checks in turn and requires the corpus to catch the weakened verifier.
## 11. Security and privacy considerations
- A rendition is a function of the base, the companion and the headroom. A proved record says
that the sink presented that function at that headroom; it does not say the companion is the
one the content's owner made. Who may supply a companion is the envelope's: a companion rides
in the envelope of its base, bound by SPEC §7.1, so a third party cannot attach one without
changing the envelope's content hash.
- A record names the display's headroom. Headroom is a property of the display and its settings
at the time, and a sequence of records from one key can show how a viewer's display was
adjusted. A sink that signs records under a session key reveals no more than the session's.
- A companion's metadata can drive the gain to 16 stops and the offsets to ±1. The derivation is
defined over all of it, and §3.5 clamps every code value to the display's range, so no value it
reads makes a sink present past its peak.
- The readers of §4.2 and §5.2 bound every count and length before they read, and a set or a frame
outside them is refused before anything sized from it is allocated.

View file

@ -0,0 +1,50 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "mesh.primitive.KHR_gaussian_splatting.EXT_gaussian_splatting_compression_wai.schema.json",
"title": "EXT_gaussian_splatting_compression_wai extension of KHR_gaussian_splatting",
"type": "object",
"description": "A Gaussian splat set carried as a WAI object (capability wai.splat.int_codec): a WAI1 envelope in a buffer view, its content hash, its parameter set and, optionally, the origin's commitment. Draft of extensions/splat-exact.md section 3.2; the rules that need the envelope, the set or the decode are that section's.",
"allOf": [ { "$ref": "glTFProperty.schema.json" } ],
"properties": {
"bufferView": {
"allOf": [ { "$ref": "glTFid.schema.json" } ],
"description": "The index of the buffer view that holds the object's WAI1 envelope, and nothing else."
},
"capability": {
"type": "string",
"description": "The envelope's capability.",
"anyOf": [
{ "const": "wai.splat.int_codec", "description": "The integer Gaussian-splat attribute codec (payload WIS1)." },
{ "type": "string" }
]
},
"object": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "The envelope's content hash: BLAKE3 over moq-jwp:object\\x01 and the envelope's bytes, as 64 lowercase hexadecimal digits."
},
"set": {
"type": "object",
"description": "The parameter set the envelope pins.",
"properties": {
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "The SHA-256 of the set's one file, as the envelope's pin names it."
},
"bufferView": {
"allOf": [ { "$ref": "glTFid.schema.json" } ],
"description": "The index of the buffer view that holds the set's one file, where the asset carries it."
}
},
"required": [ "sha256" ]
},
"commitment": {
"allOf": [ { "$ref": "glTFid.schema.json" } ],
"description": "The index of the buffer view that holds the text of the origin's commitment (kind wai-splat-commitment)."
},
"extensions": { },
"extras": { }
},
"required": [ "bufferView", "capability", "object", "set" ]
}

View file

@ -5,7 +5,9 @@
> The verifier of the reference implementation is in
> https://git.transaction.science/Transaction-Science/open-standards/src/branch/main/wai/wai-rs:
> `claim_receipt`, `jwp_delivery`, and for §7 `signer_id` and `key_log` (feature
> `key_discovery`).
> `key_discovery`). A post-quantum signature beside each record's Ed25519 one — a hybrid
> group, claim, key entry or key-log root — is [pq-signatures](pq-signatures.md)'s (feature
> `pq_signatures`); a record without one is read and verified as this text says.
Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY**, **REQUIRED**,
**OPTIONAL** are RFC 2119 / RFC 8174.
@ -61,9 +63,11 @@ In scope:
read from its objects (§3).
- **A second binding class** (§2.6): a soft binding, declared by the
publisher with a registry-named algorithm and a resolution endpoint,
for objects whose bytes changed in normal distribution — and the
for objects whose bytes changed in normal distribution, over one
object or over a span of a track (§2.6.4) — and the
**ancestor rule** (§3.2): a receipt reached through it attests the
object the one in hand was derived from, never the object in hand.
object, or the span, the one in hand was derived from, never the
object in hand.
- **Key discovery and signing authority** (§7): a form of `signer_id`
that names the web origin a signer publishes its keys under; a signed,
chained **key log** the origin publishes at a well-known location,
@ -205,6 +209,13 @@ verifier or relay that predates the labelled payload computes the legacy one
and refuses a labelled group at §3 step 2; every group signed over the legacy
payload verifies as before.
A group signed by a hybrid key is signed over the labelled payload's third version,
`"moq-jwp:group-sign\x03"` ([pq-signatures](pq-signatures.md) §6.2): the labelled
payload's fields after its domain, then the publisher's ML-DSA-65 key, signed by both halves
of the key, and its canonical bytes (§3 step 3) end with both signatures. A verifier that
predates it refuses it as `malformed`: in the JSON form for the members it does not define,
in the binary form for the signing domain (§2.7.4).
### 2.4. Receipt envelope (typed)
Three receipt kinds are defined: `group` (one per group), `object`
@ -241,7 +252,7 @@ its own adds these members and is signed over the labelled payload (§2.3):
| field | type | meaning |
|---|---|---|
| `sign_version` | integer | `2`. Absent (or `null`), the group is in the legacy form; any other value is refused (`group_label_invalid`). |
| `sign_version` | integer | `2`. Absent (or `null`), the group is in the legacy form; any other value is refused (`group_label_invalid`), but `3` beside the hybrid members of [pq-signatures](pq-signatures.md) §6.2 (`pq_key`, `pq_sig`), which a verifier that implements that extension reads. |
| `energy_provenance`, `energy_uncertainty`, `energy_counter_filtering`, `energy_calibration_ref` | as energy-measurement §2.7 | The total's class and its evidence; all absent for the unmetered marker beside a zero total. |
| `energy_coverage` | string | `Whole` or `Partial`; absent with the unmetered marker. |
@ -314,7 +325,9 @@ signed by someone other than the publisher. A `claim` receipt carries
one such statement — a class-scoped `body` under a `class`
discriminator — on one envelope.
Required members. A claim has no optional members: a nullable member
Required members. A claim has no optional members but the three hybrid members of
[pq-signatures](pq-signatures.md) §3.1 (`pq_suite`, `pq_key`, `pq_sig`), carried all or none;
a verifier that does not implement that extension refuses them as `unknown_member`. A nullable member
is present and `null`, so one claim has one canonical form.
| field | type | meaning |
@ -391,6 +404,7 @@ key.
| `lawful-basis` | `claim` | `object` or `receipt` | §2.4.6 | the service operator (a declaration); the party recording it (a decision) |
| `log-inclusion` | `claim` | `receipt` | §2.4.7 | whoever attaches the log's evidence |
| `soft-binding` | `claim` | `object` | §2.6.2 | the object's publisher |
| `soft-binding-span` | `claim` | `object` (the span's anchor) | §2.6.4 | the track's publisher |
| `binding-recovery` | `claim` | `object` (the ancestor) | §2.6.3 | the party that performed the recovery |
| `measurement` | `claim` | `object` or `receipt`, as its figure profile fixes | §2.4.8 | the key that signed the figure: the group's publisher for `moq-jwp:object`, the receipt's signer for every other profile |
| `operating-point` | `claim` | `object` or `receipt`, as its figure profile fixes | §2.4.9 | the party that records the request, the commitment and the delivery |
@ -1459,7 +1473,9 @@ Its `link_hash` is
### 2.6. Binding classes
A receipt binds to an object in one of two ways.
A receipt binds to an object in one of two ways. The second, a soft
binding, is declared over one object (§2.6.2) or over a span of a track
(§2.6.4).
#### 2.6.1. Hard binding
@ -1510,8 +1526,9 @@ list's identifier in `alg`. WAI defines no soft-binding algorithm, no
resolution service and no transport for one: `resolution_endpoint` is
a locator, referenced the way the carrier protocol is, and a verifier
here checks that `alg` has registry form, not that it is listed. A
soft binding here covers the whole object; a binding scoped to a
region or a time range is not expressible.
soft binding of this class covers the whole object, and §2.6.4 leaves
it unchanged; a binding over a span of a track is §2.6.4's class. A
binding scoped to a region of a picture is not expressible.
#### 2.6.3. Recovery record (`class: "binding-recovery"`)
@ -1540,7 +1557,10 @@ downgrade a hard binding to a soft one.
declaration **together with** the publisher key *P* of a delivery
receipt for the declaration's subject that the verifier has verified
under §3 — *P* taken from that receipt, never from the declaration or
from the record, as in §3.2 step 3. A verifier that holds the
from the record, as in §3.2 step 3. For a declaration of class
`soft-binding-span` (§2.6.4) that receipt is *R*, a delivery receipt
for an object of the declaration's span, verified under §3, and *P* is
*R*'s signer. A verifier that holds the
declaration but no such receipt holds no context for the record, and
**MUST NOT** report the record as checked against its declaration.
The checks, in order:
@ -1549,14 +1569,18 @@ The checks, in order:
members, `signer_pubkey` among them, are its signer's only once its
signature is checked: a declaration that was only parsed can carry
the publisher's key over anyone's signature;
2. the declaration is a `soft-binding` claim (`context_mismatch`);
2. the declaration is a `soft-binding` or a `soft-binding-span` claim
(`context_mismatch`);
3. `declaration` is its `link_hash`, and `subject`, `alg` and
`binding_type` equal the declaration's
(`recovery_declaration_mismatch`);
4. the declaration's `signer_pubkey` is *P*
(`recovery_signer_mismatch`) — §3.2 step 3's check, without which a
record could carry a recovery that §3.2 itself refuses;
5. `value` matches the declaration's `value` under the algorithm's own
5. for a `soft-binding-span` declaration: *R* is within its span
(§2.6.4, `recovery_outside_span`), and `observed` is not *R*'s
`content_hash` (`recovery_of_hard_bound_object`);
6. `value` matches the declaration's `value` under the algorithm's own
rule (`recovery_no_matcher`, `recovery_value_mismatch`).
**What an accepted record establishes.** Checked against that context:
@ -1568,6 +1592,90 @@ what a match is worth apply unchanged. Accepted without that context
about who made the declaration it names or whether the value matches
it.
#### 2.6.4. Span binding (`class: "soft-binding-span"`)
A soft binding whose value was computed over a **span** of one track
rather than over one object: a stretch of the track's media timeline,
and, where the publisher states them, the groups or the objects that
carry it. A watermark embedded in every frame of a minute of a live
track, or a fingerprint computed over that minute, binds the minute; a
clip cut from it and re-encoded carries the value, and a recovery
through the declaration reaches the publisher's receipts for that
minute and for nothing outside it (§3.2).
The track's publisher declares it with a `claim` of class
`soft-binding-span`. Its `subject` is the **anchor**: the §2.1 content
hash of the span's first object, in group and object order. Its body
is §2.6.2's members and `span`:
| member | type | meaning |
|---|---|---|
| `alg`, `registry`, `binding_type`, `value`, `resolution_endpoint` | as §2.6.2 | As §2.6.2's, `value` being what the algorithm produced over the span. |
| `span` | object | The span, below. |
`span` is an object of exactly these members:
| member | type | meaning |
|---|---|---|
| `track_alias` | integer | The track, as its group receipts name it (§2.4.1), under the declaration's `signer_pubkey`. |
| `start_ms` | integer | The span's first instant of media time, in milliseconds from the track's media time 0. |
| `end_ms` | integer | Its last, in the same units; both ends are in the span. |
| `first_group` | integer or `null` | The first group that carries the span, or `null` where the declaration states no groups. |
| `last_group` | integer or `null` | The last such group, or `null` with `first_group`. |
| `first_object` | integer or `null` | With groups, the span's first object, an `object_id` in `first_group`; `null` where the span is stated by whole groups. |
| `last_object` | integer or `null` | Its last object, an `object_id` in `last_group`; `null` with `first_object`. |
Rules (§3.1 step 4), after §2.6.2's rules on `alg`, `value` and
`resolution_endpoint`: `first_group` and `last_group` are both `null`
or both integers, `first_object` and `last_object` likewise, and the
objects are integers only beside integer groups (`span_malformed`);
`start_ms` ≤ `end_ms`, `first_group` ≤ `last_group`, and
(`first_group`, `first_object`) ≤ (`last_group`, `last_object`),
compared by group and then by object (`span_inverted`).
An object receipt is **within** the span when its `track_alias` is the
span's and its signer is the declaration's, and: with objects stated,
its (`group_id`, `object_id`) is from (`first_group`, `first_object`)
to (`last_group`, `last_object`), compared as above; with groups alone,
its `group_id` is from `first_group` to `last_group`; with media time
alone, its `content_hash` is the anchor. Delivery receipts carry no
media time, so a span stated by media time alone places no object but
the anchor; groups or objects are how a publisher lets a recovery
reach the rest of the span's receipts.
**Whole-object bindings are unchanged.** This class adds no member to
`soft-binding`: a `soft-binding` claim that carries `span` is
`unknown_member` (§3.1 step 2), and every `soft-binding` claim, and
every recovery through one, verifies byte for byte as before. A span
is a class of its own rather than an optional member of
`soft-binding` because a claim has no optional members (§2.4.3): one
claim, one canonical form.
**The C2PA mapping.** A declaration of either class is one block of a
C2PA soft-binding assertion (C2PA 2.4 §18.10), `{"scope": S, "value":
V}` with `V` its `value`, the assertion's `alg` its `alg`. For
`soft-binding`, `S` is `{}`: no `timespan` and no `region`, the whole
asset. For `soft-binding-span`, `S` is `{"timespan": {"start":
start_ms, "end": end_ms}}`. C2PA's `start` and `end` are unsigned
integers, the time range in milliseconds from the start of the media
over which the value was computed (C2PA 2.4 §18.10.2); C2PA states no
reading of the range's end, and its example's adjacent blocks end at
133016 and start at 133017, which is the reading of both ends included
that this class states. The groups and the objects have no C2PA field:
they are the coordinates a recovery checks receipts against, and stay
on the WAI side. C2PA matches a soft binding by `alg` and `value`
(C2PA 2.4 §18.10.5.1), and the scope says what the value was computed
over without taking part in the match; a recovery here matches the
same way and uses the span to bound what the match reaches.
**Why a span.** A live track has no single object a soft binding can
be computed over that survives a cut: an object holds a fraction of a
second, a clip taken from the track spans many objects, and a
watermark whose payload repeats in every frame is read from any of
them. Declaring the value once per span, with the coordinates that
carry it, lets one declaration cover the stream, and keeps what a
recovery attests no wider than what the publisher declared.
### 2.7. Binary form
Group and object receipts have, beside their JSON form, a **binary form**:
@ -1596,7 +1704,9 @@ form it was signed in, then its 64-byte `sig`. The labelled payload signs the
parent link and carries it; the legacy one does not, so a legacy group adds it:
`1` and `parent_receipt_hash`, or `0` and 32 zero bytes. The first 19 bytes, the
signing domain, give the form: `moq-jwp:group-sign\x01` the legacy form,
`moq-jwp:group-sign\x02` the labelled form (`"sign_version": 2`).
`moq-jwp:group-sign\x02` the labelled form (`"sign_version": 2`), and, for a verifier that
implements [pq-signatures](pq-signatures.md), `moq-jwp:group-sign\x03` the hybrid form
(§6.2 there: the labelled form's fields, the 1952-byte key, `sig`, the 3309-byte `pq_sig`).
Read in that order, each field's length is known: the strings are
length-prefixed, and a class is a tag byte and the evidence that tag carries
@ -1696,7 +1806,10 @@ match the algorithm style of WAI SPEC.md §4 (numbered, terminating).
(`group_label_invalid`). After this step, the verifier holds a
**verified root**: the receipt's `root_hash` field, now bound to
`signer_pubkey` under signature, and for a labelled group the total's
class.
class. A hybrid group ([pq-signatures](pq-signatures.md) §6.2) is verified at this
step by both its halves, in the order of pq-signatures §4.2, and under a policy that
requires hybrid (§5 there) a group with a classical signature only is refused here
(`hybrid_required`) before its signature is examined.
3. **Check parent linkage.** Receipt chains are kept per
(`signer_pubkey`, `track_alias`): one chain for each publisher key and
@ -1960,7 +2073,7 @@ order listed.
`oer_receipt`; or an operating point whose member names are not terms
or whose values are not integers of §2.4.3. A member's type and encoding are checked together,
before the next member is read. An object a class fixes the members
of — a lawful-basis purpose, an `energy_uncertainty` — is checked
of — a lawful-basis purpose, an `energy_uncertainty`, a span — is checked
the same way, its members and then their types, where the table
reaches it, and the entries of an array in the array's order. Of a
member's value, this step checks the type column and nothing else.
@ -1971,7 +2084,8 @@ order listed.
zero; an empty `purposes`; an empty `basis`, which is why its type
is `term or ""`; an empty `log_receipt` or `value`; an `alg` that is
a term but not in registry form; a `resolution_endpoint` that is an
absolute URI but not an `https` URI with a host and no userinfo; an
absolute URI but not an `https` URI with a host and no userinfo; how
a span's members pair and order; an
`attests` other than `"ancestor"`; a figure profile, an index or a
group that does not fit the profile; a hardware figure's report that
names no power reader; a bracket with fewer than two
@ -1997,7 +2111,10 @@ order listed.
the one encoding of its point, or its point is of small order — and
`sig` is `signature_verify_failed` if it fails steps 3 to 5. The key
checks run first, so a key under which a signature needs no private
key is refused before its signature is examined.
key is refused before its signature is examined. A hybrid claim's two halves are
verified in the order of [pq-signatures](pq-signatures.md) §4.2 (`hybrid_required`
under its policy, `pq_signature_invalid`), and its hybrid members are read at step 1,
after the subject type is admitted (`pq_malformed`, `pq_suite_unknown`).
4. **Class rules**, per §2.4.5–§2.4.15 and §2.6, each with its own
reason (below). They run after the signature because a rule about
what a signer said only means something once it is established who
@ -2024,7 +2141,8 @@ order listed.
declaration (§2.4.6);
a recovery record against its declaration together with the
publisher key of a verified delivery receipt for the declaration's
subject (§2.6.3), and never against the declaration alone; a
subject, or for a span declaration a verified delivery receipt for an
object of its span (§2.6.3), and never against the declaration alone; a
`delivery-gap` claim against the object receipt at its coordinates,
verified by inclusion at least (§2.4.11); a `reconstruct-session` claim
against its outputs, the objects it received, the `WAI2` envelopes it received
@ -2043,8 +2161,9 @@ order listed.
`signer_pubkey` among them, are its signer's only once its signature
is checked. For a decision or a recovery record the order is: the
claim is of a class that names a declaration (`context_mismatch`),
the declaration passes steps 1–4 (`context_invalid`), it is of the
class the claim names (`context_mismatch`), then the class's own
the declaration passes steps 1–4 (`context_invalid`), it is of a
class the claim names — for a recovery record, `soft-binding` or
`soft-binding-span` (`context_mismatch`), then the class's own
checks. A context receipt of another class is `context_mismatch`.
For an `energy` claim, an `object` receipt about another subject,
and an OER receipt other than the one named or about another
@ -2081,6 +2200,8 @@ and never folds it in: confirmation changes the outcome of no step here.
| 4 | `soft_binding_alg_not_registry_form` | `alg` is not in registry form |
| 4 | `soft_binding_empty_value` | `value` is empty |
| 4 | `soft_binding_endpoint_not_https` | `resolution_endpoint` is not an `https` URI with a host and no userinfo |
| 4 | `span_malformed` | a span's groups, or its objects, are one `null` and one integer, or its objects are integers beside `null` groups (§2.6.4) |
| 4 | `span_inverted` | a span's `start_ms` is after its `end_ms`, its first group after its last, or its first object after its last (§2.6.4) |
| 4 | `recovery_not_ancestor` | `attests` is not `"ancestor"` |
| 4 | `recovery_of_hard_bound_object` | `observed` equals `subject` |
| 4 | `figure_unknown_profile` | `figure_profile` names no profile of energy-measurement §6.1 for the claim's `subject_type` |
@ -2140,9 +2261,10 @@ and never folds it in: confirmation changes the outcome of no step here.
| 6 | `decision_declaration_mismatch` | a decision does not match the declaration it names |
| 6 | `decision_purpose_not_declared` | a decision is about a purpose its declaration does not list |
| 6 | `recovery_declaration_mismatch` | a recovery record does not match the declaration it names |
| 6 | `recovery_signer_mismatch` | the declaration a recovery record names (§2.6.3), or a recovery runs through (§3.2), is not signed by the publisher of a verified delivery receipt for its subject |
| 6 | `recovery_signer_mismatch` | the declaration a recovery record names (§2.6.3), or a recovery runs through (§3.2), is not signed by the publisher of a verified delivery receipt for its subject, or, for a span declaration, for an object of its span |
| 6 | `recovery_value_mismatch` | the value does not match under the algorithm's rule |
| 6 | `recovery_no_matcher` | the verifier has no matcher for the algorithm |
| 6 | `recovery_outside_span` | the delivery receipt a recovery through a span declaration, or a recovery record naming one, is checked with is not within the span (§2.6.4): another track or signer, a group or an object outside its range, or, for a span stated by media time alone, an object other than the anchor |
| 6 | `gap_subject_mismatch` | the object receipt at a `delivery-gap` claim's coordinates names another object |
| 6 | `session_output_mismatch` | a session's presentations are not `leaf_count`, repeat a (unit, layers), or give another `output_root` |
| 6 | `session_output_inconsistent` | the presentations name an entry that does not exist or a `layers` of 0, or give another `units`, another entry's `leaves`, another first-use order, other `primary_units` or `fallback_units`, or no presentation for a `missed_units` entry |
@ -2204,6 +2326,41 @@ if it is still a WAI envelope; and a matcher for *D*'s algorithm.
Steps 2–5 report at step 6. On success the result is a **recovery**,
and it attests *D*'s subject: the ancestor.
**Through a span.** *D* may instead be a `soft-binding-span` claim
(§2.6.4). The verifier then needs, in place of a delivery receipt for
*D*'s subject, *R*: a delivery receipt for an object of *D*'s span that
it has verified under §3, *P* being *R*'s signer. Step 2 admits the
class; after step 3, *R* **MUST** be within *D*'s span (§2.6.4,
`recovery_outside_span`); and step 4 also refuses an *H* equal to
*R*'s `content_hash`. The steps are otherwise those above. The
recovery attests the **span**: the track (*P*, `track_alias`), its
media time, its groups or objects where *D* states them, and the
anchor. Of the publisher's receipts, the ancestor's are those within
the span: *R*, and any other object receipt of the track the verifier
holds whose coordinates are within it.
What a recovery through a span does not attest:
- which objects of the span the object in hand was derived from, or
how much of the span it holds. A value computed over the span matches
content cut from any part of it: a watermark that repeats its payload
in every frame is read from one frame;
- anything outside the span. An object of the track before or after
it, or of another track, is not reached through *D*: a receipt
outside the span is refused (`recovery_outside_span`), never reported
as the ancestor's, and the same publisher's binding over another span
is another declaration, recovered on its own;
- for a span stated by media time alone, any object but the anchor:
delivery receipts carry no media time, so none places an object
inside the interval;
- the energy of the object in hand: the figures of the span's objects
cover producing them, and the ancestor rule below applies to the span
as a whole.
A verifier **MUST** report a recovery through a span with its span,
and **MUST NOT** report one object of the span, the anchor or *R*, as
what the object in hand was derived from.
**The ancestor rule (REQUIRED).** A receipt reached through a soft
binding attests the ancestor the object in hand was derived from, not
the object in hand. A verifier **MUST** report a recovery as such,
@ -2219,16 +2376,24 @@ hard binding is worse than no recovery, because it launders a
transformation nobody attested.
**What a match is worth.** A soft-binding match is evidence at the
algorithm's own error rates, which WAI does not state. A watermark can
be copied onto other content, and unrelated content can share a
fingerprint. A recovery says the object in hand matched the
algorithm's own error rates, which a declaration does not state. A
watermark can be copied onto other content, and unrelated content can
share a fingerprint. A recovery says the object in hand matched the
publisher's declared binding under the named algorithm — nothing about
how it was derived, by whom, or with what changes.
how it was derived, by whom, or with what changes. An algorithm's
error rates under named transformations are measured, reproducibly,
by the robustness records of
[robustness-evidence](robustness-evidence.md), and what it claims to
survive holds only where such a record shows it (robustness-evidence
§8). A verifier **MAY** report beside a recovery the accepted claims
and records it holds for the declaration's algorithm; they change no
step here.
A recovery **MAY** be recorded as a `binding-recovery` claim (§2.6.3).
The reference implementation (`wai-rs`, feature `receipt_claims`,
`claim_receipt::recover`) returns a value whose only attestation is the
ancestor; there is no path from it to a statement about the object in
`claim_receipt::recover`, and `claim_receipt::recover_span` through a
span) returns a value whose only attestation is the ancestor, or the
span; there is no path from it to a statement about the object in
hand.
### 3.3. Delivery reasons
@ -2240,6 +2405,7 @@ hand.
| §3 step 1 | `bad_signer_key` | `signer_pubkey` does not decode under RFC 8032 §5.1.3, or is of small order |
| §3 step 1, 2 | `group_label_invalid` | a group's labelled members appear without `"sign_version": 2`, its `sign_version` is not `2`, or its labelled members cannot be read (step 1), or its class breaks §2.4.1 with the group alone (step 2) |
| §3 step 2 | `signature_verify_failed` | the group signature fails §3.1 step 3's rule over the payload of the group's form |
| §3 step 1, 2 | `pq_malformed`, `pq_suite_unknown`, `pq_signature_invalid`, `hybrid_required` | as [pq-signatures](pq-signatures.md) §8, for a hybrid group or under the policy that requires one |
| §3 step 3 | `chain_break` | within the chain of the group's (`signer_pubkey`, `track_alias`), whose head the verifier holds: a `null` parent (a second chain head), or a parent that is another group of the chain the verifier holds (a fork) |
| §3 step 3 | `parent_not_held` | a non-null parent that names no group of the chain the verifier holds: requested, never accepted silently |
| §3 step 3 | `parent_not_recovered` | a group held for its parent past the verifier's stated bound: held live, refused when its chain re-anchors; held as history, refused alone |
@ -2484,7 +2650,13 @@ in two steps, facts that describe no sequence), and the declaration a
sealing path computes from unrounded samples, which the rule refuses. That
arithmetic is pinned against values `claim_verify.py` computes with
Python's integers. It covers an `energy` claim checked against an object
whose leaf is labelled.
whose leaf is labelled. It covers span bindings (§2.6.4): declarations
stated by media time, by groups and by objects, each rule of a span from
both sides, a `soft-binding` claim carrying a span, recoveries through a
span with a delivery receipt at each edge of its range and one past it,
of another track or signer, and of an object other than the anchor
under a span of media time alone, and recovery records naming span
declarations.
The generator and the verifier in `wai-rs` are one implementation, so
two checks are made against code that shares nothing with it. A
@ -2965,6 +3137,14 @@ telemetry carries only its `link_hash`
recovered (§3.2 step 4; for a recovery record, `observed` ≠
`subject`), so a soft binding cannot stand in for a hard one that
still verifies.
- **A span wider than its value.** A span is its publisher's
statement of what its value was computed over (§2.6.4). A publisher
that declares a span wider than the content that carries the value
makes a recovery reach receipts of objects the content in hand may
not come from; the declaration carries its signer's authority and no
more, as every claim does. A resolution endpoint cannot widen a span,
which is signed, and a receipt outside it is refused rather than
reported (`recovery_outside_span`).
## 7. Key discovery and signing authority
@ -3080,7 +3260,9 @@ is a JSON object with exactly these members, under §2.4.3's encodings:
| `status_max_age_s` | integer | How long, in seconds, a key status stays fresh: at least 1 and at most §7.9's ceiling. |
| `sig` | 64 B hex | `root`'s signature, below. |
A key entry has exactly these members:
A key entry has exactly these members (a hybrid entry adds `pq_suite` and `pq_key`, and a
revision with a hybrid root adds `pq_suite`, `root_pq_key` and `pq_sig`, each with what
[pq-signatures](pq-signatures.md) §6.1 adds to rules 1, 3, 5 and 6 and to the commitment):
| member | type | meaning |
|---|---|---|
@ -3276,6 +3458,13 @@ first that fails, as a level and a reason (§7.7):
that set (`origin_not_expected`). An empty set expects no origin the
item can have.
A verifier that implements [pq-signatures](pq-signatures.md) runs its step 4a after step 4:
a hybrid entry and an item with a classical signature only is refused (`hybrid_downgrade`),
an item whose ML-DSA key is not its hybrid entry's, or that is hybrid under a classical entry,
is refused (`pq_key_mismatch`), and under an anchor that requires hybrid an item with a
classical signature only is unconfirmed (`hybrid_required`); under such an anchor step 3
follows only hybrid-signed revisions.
Steps 1–3 and 6a fail as unconfirmed and steps 4–7 as refused, except
step 1's `signer_id_names_another_key`, which is refused. Step 6a is
unconfirmed, not refused: nothing contradicts the item; the verifier
@ -3320,7 +3509,7 @@ A confirmation needs every one of them:
| item | authorities |
|---|---|
| a `group` receipt, and the `object` receipts under it | `delivery`; and `energy/<class>` for each acquisition class an `object` receipt under it labels, where its leaf binds a label (§2.2), and for the class a labelled group payload signs for the group's total (§2.3) |
| a `claim` | its class's authority: `energy/` followed by its `energy_provenance` for `energy`, for example `energy/OnChipCounter`; `lawful-basis/declaration` or `lawful-basis/decision` by its `record`; its class name for every other class — `log-inclusion`, `soft-binding`, `binding-recovery`, `measurement`, `operating-point`, `stage`, `delivery-gap`, `reconstruct-session`, `consumption`, `transmission` and `reconciliation`. And `energy/` followed by its `energy_provenance` whenever its body carries that member, whatever its class |
| a `claim` | its class's authority: `energy/` followed by its `energy_provenance` for `energy`, for example `energy/OnChipCounter`; `lawful-basis/declaration` or `lawful-basis/decision` by its `record`; its class name for every other class — `log-inclusion`, `soft-binding`, `soft-binding-span`, `binding-recovery`, `measurement`, `operating-point`, `stage`, `delivery-gap`, `reconstruct-session`, `consumption`, `transmission` and `reconciliation`. And `energy/` followed by its `energy_provenance` whenever its body carries that member, whatever its class |
| the energy figure of a `reconstruct-session` claim whose `energy` is not `null` | `reconstruct-session`, and `energy/` followed by `energy.energy_provenance` |
| the energy figure of a `transmission` claim whose `energy` is not `null` | `transmission`, and `energy/` followed by `energy.energy_provenance` |
| a receipt of another WAI family that signs its own `signer_pubkey` and `signer_id` | `receipt`; and `energy/<class>` for each class its figures carry a label for |
@ -3428,7 +3617,8 @@ its keys is that party is the origin's decision, and its log records it:
- **Log inclusion.** A confirmation says under whose authority the log's
evidence was attached. It does not check `log_receipt`: §2.4.7 is
unchanged.
- **Soft binding.** A declaration confirmed with `soft-binding` is its
- **Soft binding.** A declaration confirmed with `soft-binding`, or a
span declaration with `soft-binding-span`, is its
origin's; confirmed under the subject's origin, it is the publisher's.
§3.2 step 3 and §2.6.3 check 4 are unchanged: a recovery still needs
the declaration's key to be the key of a verified delivery receipt.
@ -3509,6 +3699,9 @@ its keys is that party is the origin's decision, and its log records it:
| 3 | unconfirmed | `key_log_fork` | a parent has several authorised children and not exactly one rotation among them, or a trusted revision has several superseding rotations |
| 4 | refused | `key_not_listed` | the head lists no entry with the key-id |
| 4 | refused | `key_mismatch` | the entry's key is not `signer_pubkey` |
| 4a | refused | `hybrid_downgrade` | the entry is hybrid and the item carries a classical signature only ([pq-signatures](pq-signatures.md) §6.1) |
| 4a | refused | `pq_key_mismatch` | the item's ML-DSA key is not the entry's, or the entry is classical (pq-signatures §6.1) |
| 4a | unconfirmed | `hybrid_required` | the anchor requires hybrid and the item carries a classical signature only (pq-signatures §6.1) |
| 5 | refused | `key_revoked` | the entry is revoked |
| 5 | refused | `key_retired` | the entry is retired and the item's signed time is later than `until` |
| 6 | refused | `authority_not_granted` | the entry's `may_sign` does not hold every authority the item needs |

View file

@ -37,7 +37,8 @@ In scope: the per-hop session record in its two versions, its track entries, its
subscriber time by layer class, its ledger, version 2's DVR figures, its size bound and its
signature (§3); the room-session receipt, the key that may sign it, its units, its joules
per hop and per class, and its ceilings (§4); verification (§5); quality-of-experience
observations, how they are carried and what of them reaches the receipt (§6); the mapping
observations, how they are carried, what of them reaches the receipt, and their aggregation
under [telemetry-aggregation](telemetry-aggregation.md) (§6); the mapping
onto C2PA (§7); and what the reference relay emits (§8).
Out of scope: a transport; how a hop measures its energy, which
@ -478,6 +479,12 @@ is not suppressed is refused `qoe_not_suppressed`. The cell is the signer's aggr
statements nobody signed (delivery-telemetry §1.1) and **MUST NOT** be presented as evidence
of what a viewer saw; it carries no joule figure (§1.2 there).
A room **MAY** instead aggregate its quality of experience under
[telemetry-aggregation](telemetry-aggregation.md) (§6.5): its receipt then names no logs
(`qoe` zero) and its cell is suppressed, as above, and the room's cell is computed from the
aggregate receipts of its tasks (telemetry-aggregation §9.2), whose floor of 50 reports each
aggregator enforces.
## 5. Verification
### 5.1 Inputs and steps
@ -647,6 +654,19 @@ a batch with `live_metering::cmcd_batch_body`.
matched to a grant. The cell is not per grant and not per layer class, so no cell is
smaller than the session.
### 6.5 Aggregated
A room's clients **MAY** report their sessions' quality of experience as the measures of
[telemetry-aggregation](telemetry-aggregation.md) §3 instead of as logs: each client
secret-shares each session's measurement between the room's two aggregators under DAP
(`draft-ietf-ppm-dap-20`), and the room's service receives aggregates alone. The room's tasks
name the room id as their scope (telemetry-aggregation §4.1). The room-session receipt then
states no logs and a suppressed cell (§4.7), and the room's cell is computed, field by field,
from the accepted aggregate receipts of the room's `outcomes`, `stalls` and `durations` tasks
over one batch (telemetry-aggregation §9.2): the figures §4.7 computes from logs, without the
room's service holding any session's. What §6.4 says of logs then holds of the aggregators,
each of which holds one share of each measurement and learns nothing from it alone.
## 7. C2PA
A room-session receipt maps onto C2PA 2.4's `c2pa.environmental-sustainability` assertion
@ -775,4 +795,5 @@ mutated copy of the corpus to fail.
alone, by its audit path. A grant names its principal (live-rooms §13), so a deployment
that publishes a receipt publishes its root and counts, not its ledgers.
- QoE observations are unsigned (delivery-telemetry §1.1); the receipt's cell is suppressed
below 50 sessions and never carries a session's data (§6.4).
below 50 sessions and never carries a session's data (§6.4). Aggregated (§6.5), the floor is
each aggregator's, and the service holds no session's figures.

589
wai/extensions/opus-dred.md Normal file
View file

@ -0,0 +1,589 @@
# WAI Extension: Opus Deep Redundancy, Decoded Exactly
> Status: Draft. Registers two companion-only capabilities for the deep redundancy (DRED) of
> draft-ietf-mlcodec-opus-dred-07: a compact neural latent of the recent speech, carried in an
> Opus packet's padding, from which a receiver rebuilds the acoustic features of packets that
> were lost. `wai.audio.opus.dred` is that decoding as the draft defines it, held to the draft's
> own conformance test (its §4.1), which admits any decoder whose features lie within its
> thresholds of the reference. `wai.audio.opus.dred.int` is the same decoding through an
> **integer profile**, `dred-int/1`: the draft's own decoder network and its own weights file,
> pinned by digest, lowered to `wai-ops/1` graphs ([integer-operators](integer-operators.md))
> whose output is the same integers on every machine and on every fabric whose operator
> implementation conforms. With it, a stream under loss has one reconstruction, named by a
> digest that a verifier recomputes from the packets, the loss and the weights, and a player can
> sign that digest in the log of [synthesis](synthesis.md) §10.3. This extension also says where
> the working group's other documents stand in WAI's registry and in synthesis's lattice (§2.3,
> §7.1), and measures the profile against the floating-point network (§6). No new transport.
> The reference implementation is the `dred_exact` module of `wai-rs` (feature `dred_exact`);
> the corpus is [`live-conformance/dred/`](../live-conformance/dred/), and its second
> implementation is `live-conformance/dred_verify.py`. The integer profile as a proposal to the
> working group is drafted in [`proposals/dred-integer-profile.md`](../proposals/dred-integer-profile.md),
> which is not filed.
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
>
> Texts read for this revision, each pinned to the version named: draft-ietf-mlcodec-opus-dred-07
> (4 August 2026), with the files its §7 references by SHA-256 ([DRED-Weights],
> [DRED-Test-Vectors], [DRED-Compare], [DRED-Ref-Impl]); draft-ietf-mlcodec-opus-extension-06;
> draft-ietf-mlcodec-opus-speech-coding-enhancement-04; draft-ietf-mlcodec-opus-scalable-quality-extension-02;
> draft-ietf-mlcodec-test-battery-00; RFC 6716 §3, §4.1 and §5.1; RFC 7587.
## 1. Scope
The draft's decoder has two parts (its §4): a **feature decoder**, a recurrent network that
turns the latents into 20 acoustic features per 10 ms, which the draft makes normative and
tests within tolerances; and a **vocoder** that turns features into samples, which the draft
leaves to the implementation (its §2.2.4, §4.2). This extension's profile is of the first part.
**Conformance targets.**
- A **sink** that advertises `wai.audio.opus.dred.int` finds DRED in a packet (§3), decodes it
through `dred-int/1` (§4), and gives exactly the features §4 gives.
- A **verifier** of a reconstruction recomputes a stream's reconstruction from its packets, its
loss pattern and the weights, and checks a record of it (§5) and a player's statement of it
(§7.2).
**Out of scope.**
- The vocoder. A sink renders features to samples with any vocoder the draft admits; those
samples are its own, and §7.2 says what a player states of them.
- The decoding of an Opus packet's own frames (RFC 6716 §4), and concealment of a frame no DRED
rebuilds. §7.1 classes both.
- Encoding. The draft's encoder is not normative (its §2.2.1); the corpus's packets are written
by a generator that quantizes as §9 describes.
## 2. Registration
### 2.1 Two strings, one payload
| string | kind | role | replicate class | parameter set |
|---|---|---|---|---|
| `wai.audio.opus.dred` | companion | enhancement layer over `wai.audio.opus.packet` | `StandardTolerance`: features within the draft's §4.1 thresholds of the reference | the draft's, fixed by the draft |
| `wai.audio.opus.dred.int` | companion | enhancement layer over `wai.audio.opus.packet` | `NeuralIntegerExact`: the features of §4, exactly | one file, the draft's weights file (§4.1) |
Both carry the same payload. They differ in what a sink that advertises them promises, which is
what a sender chooses between: a sender that needs any rebuilt speech names the first; a sender
whose reconstruction is to be recomputed, signed or presented at `decode-equivalence` names the
second, with a pin on the weights file (SPEC §3.1) that declares `tier` `decode-equivalence`.
Two strings are needed because a capability's class bounds the tier a pin may claim (SPEC §3.1,
*Tier*): a decode admitted within tolerances cannot back `replicate`, and the draft's decoding is
admitted within tolerances.
### 2.2 Why a companion, not a refinement
A refinement-only capability is applied to the output of the stage below it, bound to that
output's producer by content hash ([staged-delivery](staged-delivery.md)): its payload corrects
what the base decoded. DRED corrects nothing the base decoded: it is a second, coarser encoding of
the same speech, sent ahead so that a receiver can rebuild what a loss took, and it is read only
where the base's own frames are missing. Its payload has no meaning without the encode it was
made with: its offsets index that encode's frames (draft §3), and its first rebuilt samples
continue that encode's last decoded ones (draft §2.2.4). That is the model of an **enhancement
layer** (SPEC §5): a companion-only capability, decoded by its own standard over one base
encode, bound to exactly one selectable rendition of a base it lists, and the base of no second
layer. So both strings are registered as enhancement layers. Their one base is
`wai.audio.opus.packet`, one Opus packet per object, because there the envelope itself aligns the
DRED payload with the packet it belongs to; this revision pins no alignment of a separate DRED
stream with an Ogg Opus stream (`wai.audio.opus`), as SPEC §5 pins none for a separately carried
LCEVC stream.
DRED is carried one of two ways, as an enhancement layer is (SPEC §5, *Enhancement layers*):
- **Embedded.** The DRED extension rides in the base packet's padding (draft §3), under extension
ID 32, or, until the IANA action the draft asks for, under the experimental ID 126 with the
two-byte prefix `'D'`, 12 (draft §3, §5). The payload is the base's bytes, under the base's
capability; a sink without DRED discards the padding (draft-ietf-mlcodec-opus-extension-06 §2).
No DRED component exists.
- **Separate.** A `WAI2` companion of the base rendition (SPEC §7.1), `role` `"companion"`,
`companion_of` `wai.audio.opus.packet`. Its payload is one DRED extension payload as draft §3
defines it (the bytes after the extension's ID byte and any length, with no experimental
prefix), for frame 0 of the base packet in the same envelope (a frame offset of 0, §3.3).
### 2.3 The working group's other documents
- **draft-ietf-mlcodec-opus-extension-06** defines the padding's extension format that §3.2
reads. It carries no payload of its own and registers no capability here.
- **draft-ietf-mlcodec-opus-speech-coding-enhancement-04** sets requirements for a decoder-side
enhancement of the Silk layer's output, and for a blind extension of its bandwidth above
8 kHz. It changes no byte of a packet, so it is no WAI capability: it is a property of the
sink's Opus decoder, and a stream decoded with it is still `wai.audio.opus` or
`wai.audio.opus.packet`, decoded within RFC 6716 §6's tolerances by a decoder that also passes
that draft's objective tests. §7.1 classes what it does to an object.
- **draft-ietf-mlcodec-opus-scalable-quality-extension-02** adds refinement bits for the CELT
layer, and bands above 20 kHz, in the same padding. It is not a neural decoder, and the
refinement rides embedded in the base packets, decoded by the base's decoder; this revision
registers no string for it.
- **draft-ietf-mlcodec-test-battery-00** describes test material for these extensions. WAI reads
it as informative.
### 2.4 Licence class
Both strings are classed `patent-pool`, the conservative class REGISTRY.md gives a capability
whose royalty status is not established. One IPR disclosure on the individual draft that became
draft-ietf-mlcodec-opus-dred, the IETF's disclosure 6063, states an intent to license
royalty-free if the technology is included in a standard the IETF adopts; until that happens the
status is not established. A later revision MAY move both strings to `royalty-free` once it is.
## 3. Finding DRED and its integers
### 3.1 The packet
A sink reads an Opus packet's framing as RFC 6716 §3.2 defines it, and holds it to §3.4's rules
R1–R7. A packet that breaks one is not a valid Opus packet: nothing in it is read, and its DRED
is refused (`packet_malformed`). From a valid packet it takes the number of frames, each frame's
duration in units of 2.5 ms (RFC 6716 §3.1: 4, 8, 16 or 24 for configurations 0–11 by
configuration modulo 4; 4 or 8 for 12–15 by configuration modulo 2; 1, 2, 4 or 8 for 16–31 by
configuration modulo 4), and the padding of a code-3 packet.
### 3.2 The extensions
The padding's extensions are read as draft-ietf-mlcodec-opus-extension-06 §2 defines them,
including the frame separator (ID 1) and the repeat mechanism (ID 2, §2.3), in bitstream order,
each instance with its frame index. Iteration stops at the first extension whose length, or
whose frame index, would read past the padding or the packet's last frame (§2.7); the instances
before it stand.
The packet's **DRED payload** is the first instance, in that order, that is either:
- ID 32 with at least one byte of data: the data; or
- ID 126 whose data is longer than two bytes and starts with `'D'` (0x44), 12: the data after
those two bytes.
Its **frame offset** is its instance's frame index times the frame duration, in units of 2.5 ms.
A packet with no such instance carries no DRED. (The reference implementation the draft names in
its Appendix B finds DRED this way, under ID 126.)
### 3.3 The payload
The payload is decoded with the range decoder of RFC 6716 §4.1, as draft §3 and §3.1 define it.
This section fixes the details the draft's prose leaves open, as the draft's reference decoder
does; where the two could be read apart, the reference decoder's reading is this profile's.
1. The header: `q0 = uint(16)`, `dQ = uint(8)`, `X = uint(2)`; if `X = 1`, an extended offset
`E = uint(256)`, else `E = 0`; an indicator `I = uint(32)`. `uint(n)` is `ec_dec_uint` of RFC
6716 §4.1.5 for `n ≤ 256`, one symbol of `n` equally likely values. `encoded_offset = 32·E + I`.
2. `qmax`: 15, unless `q0 < 14` and `dQ ≠ 0`. Then, with `n = 14 − q0`, a symbol is decoded over a
total of `2n` (`ec_decode`): a value `s ≥ n` gives `qmax = q0 + (s − n) + 1` and is consumed as
`[s, s + 1)`; a value `s < n` gives 15 and is consumed as `[0, n)`.
3. The **offset**, `dred_offset = 16 − encoded_offset + frame_offset`, in units of 2.5 ms: the
newest feature vector the payload rebuilds ends this long after the start of the frame that
carries the extension.
4. The **initial state**: 50 coefficients `k = 0 … 49`, at quantizer `q0`, with the state tables
(draft Tables 6, 8 and 9). Then **latent vectors** `l = 0, 1, …`, newest first, each of 25
coefficients at quantizer `q_l = min(qmax, q0 + ⌊(D[dQ]·l + 8) / 16⌋)` with
`D = [0, 2, 3, 4, 6, 8, 12, 16]`, the slope table of draft §3 in sixteenths, with the latent
tables (Tables 2, 4 and 5). Before each latent
vector, if `8·len − tell ≤ 7`, where `len` is the payload's length in bytes and `tell` is
`ec_tell` (RFC 6716 §4.1.6.1), no more are decoded.
5. **A coefficient** with decay `r` and zero probability `p0` (the tables' entries for its
coefficient and quantizer): if `r = 0` or `p0 = 255`, it is 0 and nothing is decoded.
Otherwise, with `P = 128·p0` and `S = 32768 − P`, a symbol is decoded by `ec_dec_icdf16` (with
`ftb = 15`) against the table `[S, ⌊S/2⌋, 0]`: 0 is a zero coefficient, 1 positive, 2
negative. A non-zero coefficient's magnitude is then `1 + v_1 + v_2 + …`, each `v_j` decoded
by `ec_dec_icdf16` against `icdf[0] = max(7, 128·r)`, `icdf[i] = max(7 − i, ⌊icdf[i − 1]·128·r
/ 2^15⌋)` for `i = 1 … 6`, `icdf[7] = 0`, while the symbol just decoded is 7. When the
magnitude being summed passes `2^16`, the payload is refused (`dred_latent_range`): the draft's
escape rule bounds nothing, and past a payload's last byte the decoder reads zero bytes
(RFC 6716 §4.1.2), so a crafted payload could otherwise keep a decoder reading.
The draft's test bit files carry payloads with no header (each record gives `q0`, with no slope,
and a count of latents); §6 reads them so.
## 4. The integer profile `dred-int/1`
### 4.1 The parameter set
The parameter set of `wai.audio.opus.dred.int` is **one file**: the decoder weights file draft
§2.2.2.1 and §7.1 name ([DRED-Weights]), whose SHA-256 is
`394f0ecf19926cebd678019dc94a54c88ae078340c16325069707f286cdf28a6`. A sink MUST check the file
against that digest before it reads it, and MUST refuse any other file
(`weights_digest_mismatch`): the draft makes another set of weights non-conforming (its §4.1, "an
alternate DNN model is not allowed"), and §4.4 makes these weights' integers a function of this
file's bytes. A pin over the set names that digest.
The file is read as the draft's Appendix A defines it. The profile reads, for each layer of the
table below, the arrays `dec_<layer>_weights_float` and `dec_<layer>_bias`, and for a block-sparse
layer `dec_<layer>_weights_idx`; it reads no other array. A dense matrix is stored input-major
(`weights[in·outputs + out]`, A.3.1). A block-sparse one (A.3.2) is a run of groups of 8 outputs,
each a count of blocks and then each block's first input (a multiple of 4), and its weights are
blocks of 8 outputs by 4 inputs stored input-major inside the block (`w[in·8 + out]`); every
position no block covers is 0.
| layer | inputs | outputs | sparse |
|---|---|---|---|
| `dense1` | 26 | 96 | no |
| `hidden_init` | 50 | 128 | no |
| `gru_init` | 128 | 320 | yes |
| `gru1_input` … `gru5_input` | 96, 192, 288, 384, 480 | 192 | yes |
| `gru1_recurrent` … `gru5_recurrent` | 64 | 192 | no |
| `glu1` … `glu5` | 64 | 64 | no |
| `conv_dense1` … `conv_dense5` | 160, 256, 352, 448, 544 | 32 | yes |
| `conv1` … `conv5` | 64 | 32 | no |
| `output` | 576 | 80 | yes |
The weights are not in this repository. The corpus names the file by digest, and its fetch script
(`live-conformance/dred/fetch.sh`) fetches it from the location the draft gives and checks the
digest.
### 4.2 The tables
The decoder reads draft Tables 2, 4, 5, 6, 8 and 9 (scale, decay and P(0), for the latents and
for the state). Serialized row by row (coefficient `k` from 0, the sixteen quantizers in order,
one byte each), in the order latent scale, latent decay, latent P(0), state scale, state decay,
state P(0), their SHA-256 is
`03f7d6b22e2aca5f5a28525a1311e1113d94b917fbc74a5493b04bbed5c97ded`. An implementation that
transcribes them checks its transcription against this digest.
### 4.3 The inputs
Every graph input is an integer at `2^16` (Q16). A coefficient `x` of the initial state, with
state scale `s` at `q0`, and a coefficient of latent `l`, with latent scale `s` at `q_l`, stand
for `x·256 / max(1, s)` (draft §3.1), which the input holds as
`⌊(2·x·2^24 + s′) / (2·s′)⌋` with `s′ = max(1, s)`: the quotient rounded to the nearest
integer, a tie upward. A latent's 26th input is `q_l/8 − 1` (draft §2.2.2), held as
`(q_l − 8)·2^13`.
### 4.4 Weights to integers
Every weight becomes an integer at `2^24`, and every bias an integer at the scale of the
accumulator it joins: `2^40` for `dense1` and `hidden_init`, whose inputs are at `2^16`, and
`2^39` for every other layer, whose inputs are activations at `2^15`. Each is computed from the
float32 value's bits alone, with no floating-point arithmetic:
- a float32 with sign `σ`, exponent field `e` and fraction field `m` is `(−1)^σ·M·2^E`, with
`M = m`, `E = −149` when `e = 0`, and `M = m + 2^23`, `E = e − 150` otherwise;
- at scale `2^f`, its integer is `(−1)^σ·R_half_even(M, −(E + f))` when `E + f < 0`, and
`(−1)^σ·M·2^(E + f)` otherwise, with `R_half_even` of [integer-operators](integer-operators.md)
§2 (0 for a shift of 63 or more).
A value that is not finite (`e = 255`), a weight whose integer does not fit i32, a missing array,
an array of the wrong length, a block that starts at an input that is not a multiple of 4 or past
the layer's inputs, a group that names one block twice, or a record the file format refuses,
makes the set fail to lower (`model_mismatch`, integer-operators §10.5). The pinned file does
none of these.
### 4.5 Activations
Activations are integers at `2^15` (Q15), in `[−32767, 32767]`. `tanh` and the sigmoid are
`lut16` tables (integer-operators §5.6), read at `2^12` and `2^11`. Their entries are this
integer computation, not the functions' exact values:
- `C_0 = 4609434768280048980` (`⌊e^(−1/2048)·2^62⌋`), and `C_(k+1) = ⌊C_k² / 2^62⌋`;
- for `0 ≤ u < 2^15`, `X(u)` starts at `2^62`, and for each bit `k` of `u` from bit 0 to bit 14
that is set, in that order, `X ← ⌊X·C_k / 2^62⌋`;
- `tanh`: entry `v + 32768`, for `v` in `−32767 … 32767`, is `sgn(v)·min(32767, ⌊(2a + b) /
(2b)⌋)` with `a = 2^15·(2^62 − X(|v|))` and `b = 2^62 + X(|v|)`;
- sigmoid: entry `v + 32768` is `min(32767, ⌊(2a + b) / (2b)⌋)` with `b = 2^62 + X(|v|)`, and
`a = 2^77` for `v ≥ 0`, `a = 2^15·X(|v|)` for `v < 0`;
- entry 0 (`v = −32768`) of each is 0, as `lut16` requires. No certified input reaches it.
Every intermediate fits 128 bits. Serialized as their 65,536 entries in order, each a 16-bit
two's-complement little-endian integer, the tables' SHA-256 are
`aea887ef206a10ea37bd31ef310a75c2ff05ca17df7edbbc15916969bccb4c22` (`tanh`) and
`1fe2d7c6b3255127f612576093f2f50e9e13d88da546ad4c04de264e2bbc8c36` (sigmoid).
### 4.6 The graphs
`dred-int/1` lowers the set to two `WHG1` graphs (integer-operators §10), `init` and `step`, in
which every tensor is `[C, 1, 1]`. Below, `dense(x; L, s)` is a `conv` with `kh = kw = 1` and
`groups = 1` over `x`, with layer `L`'s integer weights (`w_bytes` 4), and an `RQ` with no
multiplier, one shift `s`, `L`'s integer bias placed `pre` (`b_bytes` 8) and `round` `half_up`;
`T_tanh` and `T_sig` are `lut16` with the tables of §4.5; `C(·)` marks an output tensor whose
policy is `clamp [−32767, 32767]` (every table input, and every GRU state); `mul(a, b)` is `mul`
with an `RQ` of shift 15, no bias, `half_up`; `[a, b]` is `concat`; every other tensor's policy is
`derived`.
**`init`.** Input 0 is the initial state `[50]`, policy `clamp [−(2^31 − 1), 2^31 − 1]`.
1. `a = T_tanh(C(dense(IS; hidden_init, 28)))` `[128]`;
2. `s = T_tanh(C(dense(a; gru_init, 27)))` `[320]`;
3. outputs: the five GRU states `h_k = split(s, 64·(k − 1), 64)`, `k = 1 … 5`.
**`step`.** Inputs: the latent `Z` `[26]`, policy `clamp [−(2^31 − 1), 2^31 − 1]`; the GRU states
`h_1 … h_5` `[64]`; the convolution memories `c_1 … c_5` `[32]`; each of the last ten with policy
`clamp [−32767, 32767]`. Then:
1. `t = T_tanh(C(dense(Z; dense1, 28)))` `[96]`.
2. For `k = 1 … 5`, with `x = t`, `h = h_k`, `I = gru<k>_input` and `U = gru<k>_recurrent`:
- the **gates**: `g = T_sig(C(conv([x, h])))`, `[128]`, where the `conv` is `dense` with shift
28 whose output `o < 128` has the weights of row `o` of `I` followed by those of row `o` of
`U`, and the bias `b_I[o] + b_U[o]` (each converted by §4.4 on its own); `z = split(g, 0,
64)`, `r = split(g, 64, 64)`;
- the **candidate**: `p = dense(x; rows 128–191 of I, 19) + mul(r, dense(h; rows 128–191 of
U, 19))` (`add`), at `2^20`; then `hc = T_tanh(C(rescale(p)))`, the `rescale` with one shift
8, no bias, `half_up`;
- the **state**: `h′ = C(hc + mul(z, h + rescale⁻(hc)))`, where `rescale⁻` is `rescale` with
one multiplier −1 (`m_bytes` 4), shift 0, no bias, `floor`, and each `+` is `add`. This is
draft §2.2.2's `z·h + (1 − z)·hc`, written so that each product has one rounding; with
`0 ≤ z < 2^15` its value lies between `hc` and `h`, so the clamp changes nothing;
- the **GLU**: `u = mul(h′, T_sig(C(dense(h′; glu<k>, 28))))`;
- `t ← [t, u]`;
- the **causal convolution**: `c = T_tanh(C(dense(t; conv_dense<k>, 27)))` `[32]` and
`v = T_tanh(C(dense([c_k, c]; conv<k>, 27)))` `[32]`;
- `t ← [t, v]`; the new `h_k` is `h′` and the new `c_k` is `c`.
3. `x = dense(t; output, 23)` `[80]`, at `2^16`, policy `clamp [−2^31, 2^31 − 1]`.
Outputs, in order: `x`, the five new GRU states, the five new memories.
Tensors are numbered as integer-operators §13.0 numbers a lowered graph (inputs first, then each
operator's output in operator order), every input declares `max_h = max_w = 1`, every exponent is
none, and the operators are written in the order above (for the GRU: `concat`, the gates' `conv`,
`lut16`, the two `split`s, the candidate's two `conv`s, `mul`, `add`, `rescale`, `lut16`, then
`rescale⁻`, `add`, `mul`, `add`). For the pinned set, the graphs' identities (the SHA-256 of their
`WHG1` bytes) are `6527304e48bbd6c972fb41cb24ab5f387a3adee6f88347dfc8f10f47060e5c9d` (`init`)
and `4c76f2e5f6b2657b985aa171f7872fc18ae48b9419447e69cb3e52a3225b34d2` (`step`).
### 4.7 The driver
A payload is decoded as a **sequence** of graph runs:
1. `init` on the state input (§4.3); its outputs are the GRU states. The memories are 0.
2. For latent `l = 0, 1, …`, newest first: `step` on the latent's input (§4.3), the GRU states and
the memories; its first output `x` gives four feature vectors, and the others are the states
and memories of the next latent.
The **rows** of the payload are those vectors, newest first: row `4l + j` is
`x[20j], …, x[20j + 19]` of latent `l` (draft §2.2.2: the four vectors of a latent are in reverse
chronological order), and each row is 10 ms older than the row before it. Row 0 ends at the
payload's offset (§3.3 step 3). Each value is the feature at `2^16`, an i32.
Decoding the first `n` latents gives the first `4n` rows, the same integers whatever follows:
the network runs newest first, so a row never depends on an older latent. A sink MAY stop after
the rows it needs.
### 4.8 Profile and fabrics
Every operator of both graphs is in `wai-ops/1-i32` (integer-operators §9.1), and both graphs'
certificates meet `acc64` and not `acc32`: a 16-bit activation times a 32-bit weight, summed over
up to 576 inputs, passes 32 bits. The registry's `ops` member of `wai.audio.opus.dred.int` is
`{"set": "wai-ops/1", "profile": "acc64", "subset": "full", "lowering": "dred-int/1"}`; the
payload's range decoder is RFC 6716's and not a stage operator of integer-operators §5E, so the
member has no `stage`. On a GPU, the reference implementation's WGSL kernels (`wai-ops-gpu`) run
both graphs at `acc64`, and `wai-rs/tests/dred_exact_gpu.rs` holds their outputs to the CPU's
graph by graph.
## 5. A stream under loss
### 5.1 The loss pattern
A loss pattern is a seed of 32 bytes and two thresholds, `enter` and `stay`, each an integer in
`0 … 2^16`. Packet `n` (from 0) draws `u_n`, the first two bytes, big-endian, of
SHA-256(`"wai:dred-loss\x01"` ‖ seed ‖ `n` as a big-endian u32). It is lost when `u_n < enter` and
the packet before it was received (or `n = 0`), and when `u_n < stay` and the packet before it was
lost.
### 5.2 Slots
A stream is a run of packets of one frame each, all of duration `d` (in units of 2.5 ms), so
packet `n` starts at `n·d`. Each lost packet's frame is two 10 ms **slots**, half 0 (the earlier)
and half 1, and half `h` of frame `m` ends at `E = m·d + 4·(h + 1)`. A maximal run of lost
packets is **recovered** by the packet after it, when that packet was received and carries DRED
whose payload is not refused (§3); then, with `A = n·d + dred_offset` the end of its row 0 (`n`
the recovering packet), half `h` of frame `m` takes row `r = ⌊(A − E) / 4⌋` of it when `A − E ≥ 0`
and `r` is less than four times the payload's latent count. Otherwise the slot is **not
covered**: no DRED rebuilds it.
### 5.3 The reconstruction buffer
The reconstruction of a stream is its slots in order (frame ascending, then half), as bytes: for
each, the frame (u32), the half (u8) and 1 if it is covered or 0 if not (u8); for a covered one
then the recovering packet (u32), the row (u32) and the row's 20 features (i32 each); every
integer little-endian. Its digest is SHA-256 over those bytes. The buffer of one run is the same
over that run's slots alone.
### 5.4 The record
A record of a reconstruction states:
- `weights_sha256`: the weights file the decode used;
- `lost`: the indices of the packets the stream lost, ascending;
- `slots`: each slot as `[frame, half, packet, row]`, or `[frame, half, null, null]` for one not
covered;
- `output`: the reconstruction's digest, hexadecimal.
### 5.5 Verification
A verifier is given the stream (each received packet as the object a live track carries it in:
a `WAI1` envelope of `wai.audio.opus.packet`, with nothing where a packet was lost), its loss
pattern, the record, and the weights file. It checks, in order, and refuses at the first check
that fails:
1. the record's `weights_sha256` is the digest of §4.1 (`weights_digest_mismatch`);
2. the packets the loss pattern loses are the record's `lost`, and are exactly the packets the
stream lacks (`loss_pattern_mismatch`);
3. the slots §5.2 gives are the record's `slots` (`reconstruction_mismatch`);
4. the digest of the reconstruction §4 gives is the record's `output` (`reconstruction_mismatch`).
A reconstruction that passes is the one every conforming sink gives: the profile admits no other.
## 6. Measurement
What the profile changes is the arithmetic: the same network, the same weights, at fixed point.
`wai-rs/tests/dred_exact_measure.rs` measures how far that moves the features, on the draft's own
test vectors ([DRED-Test-Vectors]): all eight DRED bit files, 20 records each, every record's
latents decoded through the profile, and through the network in floating point (`f64`, from the
same float32 weights, with `tanh` and the sigmoid computed exactly to `f64` precision); and every
packet of the eight packet files that carries DRED, its DRED decoded both ways. Each pair is
compared by the draft's feature comparison (its §4.1 and its tool [DRED-Compare]): per feature,
the mean squared difference over the frames; `total` the square root of their sum, `max` of
their largest, the pitch feature left out of both; `pitch` the mean absolute pitch difference
over the frames the reference voices. The draft's DRED decoding test passes at `total ≤ 0.5`,
`max ≤ 0.15` and `pitch ≤ 0.02`. Two figures are added: the largest absolute difference of any
feature but pitch, and a band log-spectral distance. The 18 cepstral features are the orthonormal
DCT-II of the log10 band energies (draft §2.1.3), so the inverse DCT of their difference is the
difference of the log band energies, and ten times its root mean square over the bands is a
distance in decibels for each frame; its mean over the frames and its largest are given.
The reference features are the test vectors' own. "8-bit emulation" is the floating-point network
computing each layer the weights file also holds 8-bit weights for as the reference
implementation does when it reads them: each input rounded to `⌊0.5 + 127·x⌋`, the 8-bit weights,
each output scaled by its scale.
| compared | frames | total | max | pitch | largest difference | band LSD mean (dB) | band LSD max (dB) |
|---|---|---|---|---|---|---|---|
| integer, reference | 16000 | 0.1314 | 0.0767 | 0.00492 | 0.4139 | 0.2945 | 1.0034 |
| float, reference | 16000 | 0.1314 | 0.0767 | 0.00492 | 0.4151 | 0.2944 | 1.0060 |
| 8-bit emulation, reference | 16000 | 0.0831 | 0.0458 | 0.00255 | 0.2542 | 0.1844 | 0.6929 |
| integer, float | 16000 | 0.0021 | 0.0013 | 0.00011 | 0.0084 | 0.0048 | 0.0210 |
| integer, float (packets) | 80452 | 0.0022 | 0.0013 | 0.00004 | 0.0085 | 0.0049 | 0.0208 |
What the table shows:
- **The profile passes the draft's test** against the draft's reference features, on each of the
eight vectors and over all of them, with `total`, `max` and `pitch` well inside the thresholds.
- **The profile is close to the network.** Against the floating-point network on the same
latents, its features differ by `total` 0.0021, at most 0.0084 in any feature, 0.005 dB of band
log-spectral distance on average: about one sixtieth of the distance between the network and the
draft's reference features.
- **The reference features are not the network's.** The floating-point network and the profile
lie the same distance from them, and the 8-bit emulation lies closer, but not at them. So the
draft's test vectors carry the arithmetic of the build that wrote them.
The last point was also checked once, informatively, on one arm64 host, by building the draft's
reference implementation ([DRED-Ref-Impl]) twice: in its default configuration, which reads the
8-bit weights, and with its float weights, which it computes in float32 with a rational
approximation of `tanh`. Over the eight vectors, the default build's features lie at `total`
0.090–0.096 from the test vectors and the float build's at 0.131–0.136; the profile and the
floating-point network each lie at 0.015–0.018 from the float build, and at 0.129–0.135 from the
default build. The two builds differ from each other by about 0.13 (on the three vectors compared
directly), and neither gives the test vectors' features. Two builds of the draft's own decoder on
one machine, and the build that wrote the test vectors, give three different sets of features
from the same latents; under the integer profile there is one.
## 7. Receipts and the synthesis lattice
### 7.1 Classes
In [synthesis](synthesis.md)'s lattice (§3.2):
- **A reconstruction from DRED is a `convert`.** The features are what the packets carried: a
second encoding of the same speech, which a decoder with a pinned parameter set rebuilds
(synthesis §3.2: "a decoder's reconstruction (neural or not)"). The vocoder that renders them
continues that reconstruction; it generates no content the packets did not describe. So an
object rebuilt from DRED keeps its input's class, `reconstructed` from a capture.
- **Concealment beyond DRED is a `generate`.** Where no DRED covers a slot (§5.2), a sink that
fills it with speech predicted by a model (packet loss concealment, which draft §2 names as what
DRED's synthesis may continue from) produces content the packets never carried, by a trained
model:
that is `generate`, class `synthesized`, with the model in `models`. It is not `assistive`:
synthesis's `assist` edits an input without substantially altering it, and a concealed slot has
no input to edit.
- **Speech coding enhancement is an `assist`.** A decoder-side enhancement of decoded speech
(draft-ietf-mlcodec-opus-speech-coding-enhancement-04) edits one input without substantially
altering it, and that draft's tests bound how far it may move the decoder's own output (its §3
and §4); a blind bandwidth extension adds
content above 8 kHz the packets did not carry, as an upscale adds detail, which synthesis also
classes `assist` (§3.4). Neither is a pinned derivation of synthesis §4, so their evidence
states `tier` `attest`.
### 7.2 The presentation statement
A player that presents a reconstruction under the profile signs it in its log (synthesis §10.3):
for each run of lost packets it presents, a `present` entry whose
- `subject` is the content hash (jwp-receipts §2.1) of the recovering packet's object;
- `tier` is `decode-equivalence`, `decoder` is `wai.audio.opus.dred.int` and `variant` is
`dred-int/1`;
- `output` is the digest of that run's reconstruction buffer (§5.3), `origin` and `class` as
synthesis §10.3 has them (`null` where the player applies no claim).
A verifier checks the log as synthesis §10.3 does (`record_malformed`, `bad_key`, `bad_signature`,
`player_chain_broken`), then each `present` entry: its decoder, variant and tier are those above,
its subject is the content hash of the object that recovers a run of the stream, and its `output`
is the digest of that run's buffer that §4 gives. Otherwise the entry states an output the object
does not decode to (`present_output_irreproducible`, synthesis §9.2). The features are the
statement's subject because they are what the profile fixes; a player that also states the digest
of its vocoder's samples states its own output, which no other sink reproduces unless it runs the
same vocoder, exactly.
## 8. Refusals
The codes this extension adds, each with where it is raised:
| reason | raised at |
|---|---|
| `packet_malformed` | §3.1 |
| `dred_latent_range` | §3.3 step 5 |
| `weights_digest_mismatch` | §4.1, §5.5 step 1 |
| `loss_pattern_mismatch` | §5.5 step 2 |
| `reconstruction_mismatch` | §5.5 steps 3 and 4 |
A set that fails to lower or load is refused `model_mismatch` (integer-operators §10.5). A
verifier of a presentation statement also raises synthesis's codes for a log (§7.2).
## 9. Conformance
[`live-conformance/dred/`](../live-conformance/dred/) holds the corpus, written from fixed seeds
by `wai_dred_vectors gen` with the weights file of §4.1, which it names and does not hold:
`vectors.json`, its README, and `fetch.sh`. It has:
- **The profile's identities**: the tables' digest (§4.2), the constant and the two tables'
digests (§4.5), and the two graphs' identities (§4.6).
- **Payload vectors**, each a packet and what a decoder states of it: for a packet with DRED, its
header, frame offset, offset, latent count, the digest of its integers, the digest of every row
and row 0 itself; for one without, that it has none; for one refused, the code. The digest of a
payload's integers is SHA-256 over `q0`, `dQ`, `X`, `E`, `I` and `qmax`, one byte each; the
latent count (u32); the state's 50 indices (i32 each); then, for each latent, its quantizer (one
byte) and its 25 indices (i32 each); little-endian. The digest of the rows is SHA-256 over every
row in order, each feature an i32, little-endian. They cover the
experimental ID with its prefix and ID 32; a slope with a `qmax` below 15 and an extended
offset; a DRED extension on a packet's second frame after a frame separator; an experimental
extension of another version, a truncated extension and plain padding, which carry none; two
malformed packets; and a payload whose magnitude passes the cap.
- **Streams**, each a run of packets as `WAI1` objects with the lost ones absent, and a loss
pattern, and **cases** over them, each a record, a player's log, and the outcome: the
reconstruction as the profile gives it, with a log of its recoveries, for two streams (one with
a slope and an offset that leaves the newest frames of every run uncovered); and one refused
case for each check of §5.5 and §7.2: a record naming another weights file; a record listing a
received packet as lost; a record naming a row one older; a digest with one bit changed; the
digest of a floating-point decode of the same latents, rounded to `2^16`; a log presenting that
decode at `decode-equivalence`; and a log entry whose signature is broken.
Every packet of the corpus is written by its generator: its DRED indices are drawn from the
draft's own distributions, by decoding a seeded byte stream with §3.3's coefficient rule at `q0`,
and requantized to each chunk's quantizer (`x·s_q / s_q0`, rounded half up, where `q` codes the
coefficient). The primary frames are empty (length 0, RFC 6716 §3.2.1). No recorded speech is in
the corpus.
**Feature equivalence.** For each payload vector and each case, a conforming implementation
reaches the outcome the vector states, and for an accepted one, the same digests, rows and
statements, byte for byte.
**On every fabric.** `wai-rs/tests/dred_exact_gpu.rs` decodes the corpus's payloads with every
graph on each GPU adapter found and holds the output to the CPU's.
## 10. Security and privacy considerations
- **Bounded work.** A payload's work is bounded by its length and by the magnitude cap (§3.3):
without the cap, the escape rule could read without end past the payload's last byte. A sink
SHOULD also bound the latents it decodes to the span it needs (§4.7), as the draft lets it
(its §3: "decoders MAY ignore any redundancy data beyond a certain amount").
- **No floating point in the decode.** The profile's decode forms no float, so the denormal
slow-downs draft §6 warns of do not arise in it.
- **Speech before joining.** DRED can carry speech from before a receiver joined (draft §6). A
reconstruction record names the packets and slots it rebuilt; a verifier given a room's
history learns nothing from a record that its packets did not already carry, but a relay that
forwards DRED forwards that speech, and the draft's `ext32-dred-duration` limits apply.
- **What a statement proves.** A presentation statement over a reconstruction's digest proves
which features the player's decode fixed, from packets the verifier holds. It does not prove
that the packets are authentic or that the samples a listener heard are those features
rendered; the object's own receipts (jwp-receipts) and the vocoder's exactness are separate
matters.

View file

@ -0,0 +1,492 @@
# WAI Extension: Hybrid Signatures (Ed25519 with ML-DSA-65)
> Status: Draft. Sub-spec of WAI v1.0. Gives WAI's signed records a second, post-quantum
> signature beside their Ed25519 one, so a record stays verifiable while either algorithm
> holds: one suite, ML-DSA-65 (FIPS 204) beside Ed25519 (RFC 8032), combined as the composite
> `id-MLDSA65-Ed25519-SHA512` of `draft-ietf-lamps-pq-composite-sigs-19`. It covers the key
> logs of [jwp-receipts](jwp-receipts.md) §7 (an entry's post-quantum key, a hybrid root, an
> anchor that requires hybrid), group receipts (the third version of the labelled payload of
> jwp-receipts §2.3), claims (jwp-receipts §2.4.3), and every JSON record an extension signs as
> `wai:<domain>\x01 ‖ JCS(record)` (§3.4), through one shared check. It adds a verifier policy
> that refuses a record signed classically only, and a confirmation step that refuses a
> classical-only record signed by a key its origin lists as hybrid. Nothing changes for a
> publisher that signs classically: its records keep their bytes and verify as before. No new
> transport. The reference implementation is the `pq_sig` module of `wai-rs` (feature
> `pq_signatures`), with the readers of `jwp_delivery`, `claim_receipt`, `key_log` and
> `synthesis`; the corpus is [`pq-conformance/`](../pq-conformance/), and its second
> implementation is `pq-conformance/pq_verify.py`.
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
>
> Texts read for this revision, each pinned to the version named: FIPS 204, *Module-Lattice-Based
> Digital Signature Standard* (August 2024), whose PDF's SHA-256 as fetched on 22 October 2026
> was `57239b9f84c03227eda3ca0991204dc7764c79af9ce2e6824eda774918d46b6b`;
> `draft-ietf-lamps-pq-composite-sigs-19` (the revision of 20 October 2026), whose text's SHA-256
> as fetched that day was `b4ee04416efc26e7d8de7c740dc3848ffe8b8cc9dcd035ad9d4e33e18844ec83`;
> RFC 8032; and the ACVP test vectors for FIPS 204's ML-DSA at the upstream commit
> `975de31eb83d87039ec88934fdc47d8c312b892d` (§10.1). A section number of one of those texts in
> this extension is that version's.
---
## 1. Scope
Every signature WAI defines is Ed25519 (SPEC §7 *Signatures*). A quantum computer large enough
to compute discrete logarithms on Ed25519's curve recovers a private key from its public key,
and its holder then signs anything under it: on the day such a computer exists, a record signed
with Ed25519 alone no longer shows who signed it. Media provenance and delivery receipts are
archival — a receipt signed today is asked to prove something years later — so the signature
they carry has to outlast that day.
A **hybrid** signature is two signatures over the same bytes, one classical and one
post-quantum, and a record verifies only if both do. While Ed25519 holds, the record is as strong
as it was; once it does not, the record stands on the post-quantum half, provided that half's
key is bound to the signer by something a forger cannot rewrite either (§6.1, §7).
In scope:
- the suite (§2) and the members that carry its post-quantum half (§3);
- signing and verifying, and why the classical half signs what it signs (§4);
- the verifier policy that refuses a classical-only record (§5);
- where hybrid signatures go: key logs, group receipts, claims, and the records of the
`wai:<domain>\x01 ‖ JCS` pattern (§6);
- sizes and costs, measured (§9); the corpus and the vendored vectors (§10).
Not in scope, in this revision:
- the binary records of the live family (live events, rooms, takes and others), OER/2 receipts,
the receipts of the quantum family, and §7.9's module grants and key statuses: each keeps
Ed25519 alone until its own extension gives it a hybrid form. A key an origin's log lists in a
hybrid entry signs none of them (§6.1, step 4a);
- hash functions: BLAKE3-256 and SHA-256 are unchanged. Generic quantum search lowers a 256-bit
hash's preimage resistance to about 2^128 operations, and nothing here depends on less;
- confidentiality: key agreement for encrypted rooms is [confidentiality](confidentiality.md)'s;
- a transport.
---
## 2. The suite
One suite:
| member | value |
|---|---|
| `pq_suite` | `id-MLDSA65-Ed25519-SHA512` (`draft-ietf-lamps-pq-composite-sigs-19` §6, OID 1.3.6.1.5.5.7.6.48) |
| post-quantum half | ML-DSA-65 (FIPS 204 §4): a 1952-byte public key (`pkEncode`, Algorithm 22), a 3309-byte signature (`sigEncode`, Algorithm 26) |
| classical half | Ed25519 (RFC 8032), the key a record's `signer_pubkey` already carries, verified by SPEC §7 *Signatures* |
| label | `COMPSIG-MLDSA65-Ed25519-SHA512`, in ASCII (draft §6) |
| prefix | `CompositeAlgorithmSignatures2025`, in ASCII (draft §2.2) |
| pre-hash | SHA-512 (FIPS 180-4) |
**Why ML-DSA-65.** The post-quantum half is the half that must still hold when the classical one
does not, so its parameters are chosen for the life of the record, not for the life of the key.
FIPS 204 §4 claims security category 3 for ML-DSA-65 and category 2 for ML-DSA-44; for records
asked to prove something for decades, the margin of category 3 against advances in the
cryptanalysis of module lattices is worth the 889 bytes per signature and 640 bytes per key it
costs (FIPS 204 §4, Table 2; §9 measures what that is per record). ML-DSA-87 (category 5) adds
1318 bytes per signature more. The draft's §10.4 recommends this composite where the signature
must be strongly unforgeable, and WAI's link hashes cover signature bytes (jwp-receipts §3 step
3, §2.4.3), so a second valid signature of the same bytes would be a second receipt (§7).
**Why the composite.** The draft's construction is one WAI can adopt as it stands: it prefixes
and pre-hashes the message once for both halves, binds both to the suite by the label, and has a
published analysis of what it gives when one half fails (draft §9.2). A WAI hybrid record carries
the composite's two component signatures in two members, `sig` and `pq_sig`; `pq_sig ‖ sig` is
the draft's composite signature value and `pq_key ‖ signer_pubkey` its composite public key
(draft §4), so a composite verifier can check a WAI record given the bytes it signs. A simpler
form — two signatures over the same domain-separated bytes — would also bind both halves where
the record's own members include the post-quantum key, as every JSON record's do (§3.2); the
composite adds that the classical half is over bytes no classical record of any family signs
(§4.3), which holds for the binary group receipt too, whose members are not a JSON object.
**Keys.** A hybrid key is an Ed25519 key and an ML-DSA-65 key generated apart, each from its own
32-byte seed (RFC 8032 §5.1.5; FIPS 204 Algorithm 6, `ML-DSA.KeyGen_internal(ξ)`), and used only
together (draft §3.1, §9.3): its Ed25519 key never signs an item with a classical signature only,
and its ML-DSA key never signs outside this suite. §6.1 makes the first of these checkable.
---
## 3. The hybrid members
### 3.1 In a JSON record
A hybrid JSON record carries three members beside its `signer_pubkey` and `sig`:
| member | type | meaning |
|---|---|---|
| `pq_suite` | string | The suite (§2): `id-MLDSA65-Ed25519-SHA512`. |
| `pq_key` | 1952 B hex | The signer's ML-DSA-65 public key. In a key-log revision, whose signer is its root, the member is `root_pq_key` (§6.1). |
| `pq_sig` | 3309 B hex | The ML-DSA-65 signature (§4). |
Byte strings are lowercase hex, as every byte string of [jwp-receipts](jwp-receipts.md) §2.4.3.
A record carries all three or none: with none it is **classical** and is read and verified as
its family defines; with all three it is **hybrid**. A reader checks them in this order, and
refuses the record at its family's member step (§6) with the reason given:
1. one or two of the three present: `pq_malformed`;
2. `pq_suite` not a string: `pq_malformed`; a string naming no suite of §2: `pq_suite_unknown`;
3. `pq_key`, then `pq_sig`, not lowercase hex of exactly the suite's length: `pq_malformed`
(FIPS 204 §3.6.2: a key or signature of another length is refused, never read).
A reader built without this extension does not know the members, and refuses a hybrid record as
its family refuses any member it does not define (`malformed`, `unknown_member`,
`key_log_malformed`, `record_malformed`), so a hybrid record is never read as a classical one.
### 3.2 What is signed
The **message** `M` of a hybrid record is the bytes its family's rule signs, computed with
`pq_suite` and the key member among the record's members and with `sig` and `pq_sig` left out:
for a claim, `"moq-jwp:claim\x01" ‖ JCS(claim without "sig" and "pq_sig")`; for a key-log
revision, `"wai:key-set\x01" ‖ JCS(revision without "sig" and "pq_sig")`; for a record of the
pattern of §3.4, `domain ‖ JCS(record without "sig" and "pq_sig")`. JCS is
[jwp-receipts](jwp-receipts.md) §2.4.3's canonical form. A record's link hash and identity are
unchanged in definition: they are over the whole record, both signatures and all three hybrid
members included.
### 3.3 In a binary record
The group receipt's binary form carries the post-quantum key inside its signing payload and the
post-quantum signature after `sig`, under the payload's third version, whose signing domain names
the suite (§6.2). It has no `pq_suite` member: `moq-jwp:group-sign\x03` is this suite, and a
later suite takes a later version.
### 3.4 Records of the pattern `wai:<domain>\x01 ‖ JCS`
Many extensions sign their JSON records the same way: a record carries `signer_pubkey` and `sig`,
and `sig` is Ed25519 over `domain ‖ JCS(record without "sig")`, `domain` being the extension's
own `wai:<name>\x01` ([synthesis](synthesis.md) §2 is one). Any such record **MAY** carry the
three members of §3.1 beside `sig`, and then is checked by one **shared check**, the same for
every such extension:
1. the hybrid members, as §3.1 reads them;
2. `signer_pubkey` and `sig` present as 32 and 64 bytes of lowercase hex, or the record is the
extension's own malformed record;
3. §4.2 over `M = domain ‖ JCS(record without "sig" and "pq_sig")`, under the verifier's policy
(§5): a key that fails is the extension's own bad-key reason, an Ed25519 half that fails its
own bad-signature reason, and otherwise this extension's reasons (§8).
The extension's own member tables then apply to the record without its hybrid members, and its
own checks to what it states. A classical record's message is the bytes its extension signs
today, so a classical record reads exactly as before. An extension's verifier implements this
section by calling the shared check where it checks a signature; the reference does so for
[synthesis](synthesis.md) records. A verifier of an extension that does not implement it refuses
a hybrid record as malformed (§3.1).
---
## 4. Signing and verifying
### 4.1 Signing
Given `M` (§3.2), the signer computes the composite's message representative with an empty
application context (draft §2.2, §3.2 step 2):
```
M' = "CompositeAlgorithmSignatures2025" ‖ "COMPSIG-MLDSA65-Ed25519-SHA512" ‖ 0x00 ‖ SHA-512(M)
sig = Ed25519(ed_private_key, M') RFC 8032, 64 bytes
pq_sig = ML-DSA.Sign(ml_dsa_private_key, M', ctx = "COMPSIG-MLDSA65-Ed25519-SHA512")
FIPS 204 Algorithm 2, 3309 bytes
```
The ML-DSA half takes the label as its context string (draft §3.2 step 4), so FIPS 204's own
domain separation (Algorithm 2 line 10) binds it to the suite. A signer **MAY** sign in FIPS
204's hedged or deterministic variant (§3.4); a verifier cannot tell them apart. The corpus signs
deterministically, so it regenerates byte for byte; a signer on a platform exposed to fault or
side-channel attacks **SHOULD** sign hedged (FIPS 204 §3.4, §3.6.1).
### 4.2 Verifying
A verifier checks an item's signature in this order and reports the first that fails:
1. `signer_pubkey` is an Ed25519 key SPEC §7 *Signatures* steps 1 and 2 accept: otherwise the
family's bad-key reason (`bad_signer_key`, `bad_key`, `key_log_signature_invalid`);
2. under the policy that requires hybrid (§5), an item with no post-quantum half:
`hybrid_required`, before its signature is examined;
3. the Ed25519 half under SPEC §7 *Signatures* steps 3 to 5, over `M'` for a hybrid item and over
`M` for a classical one: otherwise the family's signature reason (`signature_verify_failed`,
`bad_signature`, `key_log_signature_invalid`);
4. the post-quantum half: the key and the signature of the suite's lengths (`pq_malformed`), and
`ML-DSA.Verify(pq_key, M', pq_sig, ctx = label)` (FIPS 204 Algorithm 3) true:
`pq_signature_invalid` otherwise, a signature whose hint does not decode or whose response
is out of range (Algorithm 27, Algorithm 8 line 13) among them.
The classical half is verified by WAI's strict rule, which refuses some signatures RFC 8032's
permissive reading accepts and no honest signer makes; the composite's verification (draft §3.3)
requires each component to verify under its own specification, which this is.
### 4.3 What stripping does
The Ed25519 half of a hybrid record signs `M'`, never `M`. Remove the post-quantum half from a
hybrid record, and its `sig` verifies over no classical record's bytes: `M'` begins with the
composite's prefix and holds a digest, not a family's domain and members (draft §9.2.3, weak
non-separability). Remove only the members of §3.1 from a JSON record, and its `M` changes too,
since `pq_suite` and the key member are signed. Either way the stripped record is refused at its
signature step; neither way can a party that cannot forge Ed25519 turn a hybrid record into a
classical one.
A party that *can* forge Ed25519 does not need to strip anything: it makes a classical record
outright. Against it, what holds is policy, not construction: §5 for a relying party that
requires hybrid of every record, and §6.1 for any record signed by a key its origin lists as
hybrid.
---
## 5. The policy
A verifier that implements this extension **MUST** offer the policy **require hybrid**: an item
with a classical signature only is refused (`hybrid_required`) at its family's signature step,
after its key is checked and before its signature is examined. A relying party that relies on
records for longer than it trusts Ed25519 **SHOULD** apply it to them. Without it, a verifier
accepts classical and hybrid items alike, and verifies both halves of a hybrid one.
The policy is the relying party's, and is not carried in any record. Its counterpart in a key
log is an anchor that requires hybrid (§6.1).
---
## 6. Where hybrid signatures go
### 6.1 Key logs ([jwp-receipts](jwp-receipts.md) §7)
**A hybrid entry.** A key entry of jwp-receipts §7.2 **MAY** carry `pq_suite` and `pq_key`
(§3.1), together: the entry is then **hybrid**, and the origin states that every item its key
signs is hybrid with that ML-DSA key. Rule 1 adds that no two entries share a `pq_key`, none is
the revision's `root_pq_key`, and no entry's pair is the one `next_root` commits to (below).
Rule 6 adds that an entry's form never changes: an entry listed hybrid keeps its `pq_suite` and
`pq_key`, and one listed classical never gains them (`key_log_rewrites_history`). An origin that
moves a key to hybrid lists a successor, as for any change of authority (jwp-receipts §7.6).
**A hybrid root.** A revision **MAY** carry `pq_suite`, `root_pq_key` and `pq_sig` (§3.1): its
root is then hybrid, and both halves sign it, §4 over the `M` of §3.2. Rule 3 requires both to
verify (`key_log_signature_invalid`). A hybrid root's ML-DSA key is part of the root: rule 5's
"its `root` and `next_root` are its parent's" holds only if `root_pq_key` is the parent's too,
present or absent alike.
**The hybrid commitment.** `next_root` commits to a classical root as jwp-receipts §7.2 defines,
or to a hybrid one as
```
commitment_hybrid(K, P) = BLAKE3("wai:key-set-next\x02" ‖ K ‖ P)
```
over its Ed25519 key `K` and its ML-DSA key `P`. Rule 1 adds that `next_root` is not the
commitment to the revision's own root in either form. A rotation (rule 5) is a child whose root
is not its parent's and whose commitment, in the child's form, is the parent's `next_root`: a root
becomes hybrid only by a rotation its parent committed to in the hybrid form, and a hybrid root's
non-rotating children are signed by both its halves.
A classical root is no stronger than Ed25519: whoever can forge it signs revisions that add keys,
hybrid ones among them, and a hybrid entry under such a root binds its ML-DSA key to the origin
only as firmly as Ed25519 does. Hence:
**An anchor that requires hybrid.** A relying party that pins an origin (jwp-receipts §7.3)
**MAY** record that it requires hybrid of it. Then:
- only a hybrid-signed revision descends from the anchor: at §7.4 step 3, a revision without the
hybrid members is no child of anything, as a revision signed by a key its parent does not
authorise is not. The pinned revision itself may be classical: it is trusted by provisioning,
and its hybrid successor arrives by a rotation it committed to;
- the anchor moves only by pinning: a retrieval that holds it leaves it where it is, and the head
walk follows its hybrid-signed descendants;
- an item with a classical signature only is unconfirmed (`hybrid_required`) at step 4a.
**Confirmation step 4a.** After jwp-receipts §7.4 step 4 has found the entry and matched its key,
in order:
- the entry is hybrid and the item carries a classical signature only: **refused**,
`hybrid_downgrade`. The log contradicts the item's claim to speak for the key: the origin
states the key signs nothing classically, so the item is a forgery or the key was misused;
- the item is hybrid and its ML-DSA key is not the entry's, or the entry is classical:
**refused**, `pq_key_mismatch`;
- the anchor requires hybrid and the item carries a classical signature only: **unconfirmed**,
`hybrid_required`. Nothing contradicts the item; the verifier lacks what its anchor requires.
A key status and a module grant (jwp-receipts §7.9) have no hybrid form in this revision: a
status is signed by the root's Ed25519 key alone, and a grant by a key that §6.1 refuses if its
entry is hybrid. An origin lists classical keys for grants until §7.9 gives them a hybrid form;
§7.9's freshness bound limits how long a status matters.
### 6.2 Group receipts ([jwp-receipts](jwp-receipts.md) §2.3, §2.4.1, §2.7)
**The payload's third version.** A hybrid group is signed over
```
signing_payload_v3 = "moq-jwp:group-sign\x03"
|| the labelled payload's fields after its domain, in its order // §2.3
|| pq_key[1952] // the publisher's ML-DSA-65 key
```
by both halves (§4, `M` = the payload). A hybrid group is a labelled group: its class, coverage
and parent link are the labelled payload's, under every rule of jwp-receipts §2.4.1. Its JSON form
is the labelled group's members with `sign_version` `3` and two more, `pq_key` and `pq_sig`.
Read at jwp-receipts §3 step 1: `sign_version` `3` with neither of them is a version jwp-receipts
does not define (`group_label_invalid`); with one of them, or either of them in a group whose
`sign_version` is not `3`, or either not lowercase hex of the suite's length, `pq_malformed`.
Verified at step 2 by §4.2.
**Canonical bytes and link hash.** `canonical_bytes(G)` is the payload, then `sig`, then
`pq_sig`, so a hybrid group's link hash (jwp-receipts §3 step 3) covers both signatures. The
binary form (jwp-receipts §2.7.1) of a hybrid group is its canonical bytes, read in that order:
the fields of the labelled form, the 1952-byte key, the 64-byte `sig`, the 3309-byte `pq_sig`. A
reader of jwp-receipts §2.7.4 that predates this extension finds a signing domain that is
neither of §2.3's and refuses the record (`malformed`).
**Objects.** Object receipts are unchanged: they are bound to a hybrid group through its root as
to any other (§2.2, §3 step 5), so the post-quantum cost is paid once per group, not per object.
**Confirmation.** A hybrid group is an item whose ML-DSA key is its `pq_key` (step 4a above).
### 6.3 Claims ([jwp-receipts](jwp-receipts.md) §2.4.3, §3.1)
A claim **MAY** carry the three members of §3.1; a claim has no other optional members. At §3.1
step 1, after the subject type is admitted, a verifier reads them as §3.1 says (`pq_malformed`,
`pq_suite_unknown`), and the envelope's member check is of the claim without them. At step 3 it
verifies by §4.2: `bad_signer_key`, `hybrid_required`, `signature_verify_failed`,
`pq_signature_invalid`. The claim's `link_hash` is over the whole claim. A claim chain (§2.4.3) is
per `signer_pubkey`, hybrid or not.
### 6.4 Records of the pattern
As §3.4 says. The reference wires the shared check into [synthesis](synthesis.md)'s records; the
other extensions that sign as `wai:<domain>\x01 ‖ JCS` adopt it by the same call.
---
## 7. Security considerations
- **What a hybrid signature gives.** Under the composite, a classical adversary cannot forge a
record if either half is unforgeable, and a quantum adversary cannot if ML-DSA is (draft
§9.2.1). It does not say who holds the ML-DSA key. A forger who can forge Ed25519 generates an
ML-DSA key of its own and signs a hybrid record with it; only the key log tells the two apart
(§6.1, step 4a `pq_key_mismatch`), and only a key log whose revisions from the anchor on are
hybrid-signed tells them apart once Ed25519 is forged. A verifier that must check a record
years from now keeps the revisions it confirmed it against (jwp-receipts §7.3) and pins an
anchor that requires hybrid.
- **Records signed before.** A record signed classically stays classical. Nothing here makes an
old record hybrid, and once Ed25519 can be forged, a classical record proves nothing about its
signer. An origin that wants its history to outlast that day registers its receipts with a
transparency service while Ed25519 still holds ([transparency](transparency.md) §3), and re-signs
what it still vouches for.
- **Strong unforgeability and link hashes.** WAI names receipts by link hashes over their
signature bytes. Ed25519 under SPEC §7's strict rule has one signature per key and message;
ML-DSA is designed to be strongly unforgeable (FIPS 204 §3.1), so no one but the signer can make
a second valid ML-DSA half. A signer that signs hedged can make two hybrid records of the same
members with different link hashes; that is the signer's own fork, which jwp-receipts §3 step 3
and §3.1 step 5 refuse as for any other.
- **Key reuse.** A hybrid key's Ed25519 half signing a classical item is the stripping attack
draft §9.3 warns of; step 4a refuses it for every item confirmed under the key's origin. A key
status (§6.1) is the one classical use left to a hybrid root, under its own signing domain.
- **The implementation.** The reference's ML-DSA implementation is a maintained, permissively
licensed (Apache-2.0 OR MIT) pure-Rust one that has had no independent audit. Before anything
is built on it, it is held to FIPS 204's published ACVP vectors and the composite to the draft's
own vector (§10.1), and the corpus's second implementation verifies ML-DSA from FIPS 204's text.
- **Side channels.** Verification handles no secret. Signing does; see §4.1 on the hedged
variant.
---
## 8. Reasons
The codes this extension adds. A family reports them at the step §6 names, beside its own codes,
which keep their meaning: a hybrid item whose Ed25519 key or half fails is refused with the
family's own reason; a key-log revision that breaks §6.1's additions to rule 1 is
`key_log_malformed`, to rule 3 `key_log_signature_invalid`, to rule 5
`key_log_root_not_committed`, to rule 6 `key_log_rewrites_history`.
| code | where | raised when |
|---|---|---|
| `pq_malformed` | the family's member step | one or two of the hybrid members present; `pq_suite` not a string; a key or signature not lowercase hex of the suite's length; a group's hybrid members outside its third version, or one of them missing in it |
| `pq_suite_unknown` | the family's member step | `pq_suite` names no suite of §2 |
| `pq_signature_invalid` | the family's signature step | `ML-DSA.Verify` over `M'` with the label as context is false (§4.2 step 4) |
| `hybrid_required` | the family's signature step; confirmation step 4a | under the policy of §5, an item with a classical signature only; under an anchor that requires hybrid, the same item at confirmation (unconfirmed) |
| `hybrid_downgrade` | confirmation step 4a | the entry is hybrid and the item carries a classical signature only (refused) |
| `pq_key_mismatch` | confirmation step 4a | the item's ML-DSA key is not the entry's, or the entry is classical (refused) |
---
## 9. Sizes and costs
Sizes are the corpus's own items (`pq-conformance/vectors.json`, `sizes`), the same on every
machine. Times are `wai_pq_vectors bench`, built with `--release`, on the reference's build host:
a 32-core arm64 workstation that other jobs shared during the runs (its load average between 15
and 24). Each time is the median of seven rounds over 64 distinct 512-byte messages, about a
claim's signing input — ML-DSA's signing loop repeats a number of times that depends on the
message (FIPS 204 §4, Table 1: 5.1 on average for ML-DSA-65), so one message would time one draw
of it. The range is that median across three runs.
| operation | time per operation |
|---|---|
| Ed25519 sign | 10.6–11.5 µs |
| Ed25519 verify, SPEC §7 strict | 34.0–34.9 µs |
| ML-DSA-65 sign, deterministic | 349–378 µs |
| ML-DSA-65 verify | 75–88 µs |
| hybrid sign, both halves | 323–366 µs |
| hybrid verify, both halves | 114–128 µs |
A hybrid record costs about thirty times an Ed25519 signature to sign and between three and four
times to verify: some eight thousand hybrid verifications a second on one core.
| item | classical | hybrid | difference |
|---|---|---|---|
| group receipt, binary (jwp-receipts §2.7.1) | 291 B | 5552 B | +5261 B: the key, 1952, and the signature, 3309 |
| a group's receipts with 3 objects (`WJR1`, §2.7.3) | 722 B | 5983 B | +5261 B |
| object receipt, binary | 141 B | 141 B | none |
| claim, JSON | 579 B | 11164 B | +10585 B: the key and signature in hex, and `pq_suite` |
| first key-log revision, JSON: classical root and one classical entry; hybrid root, one hybrid and one classical entry | 684 B | 15443 B | +14759 B: the root's key and signature and the hybrid entry's key, in hex, and one entry more |
| origin claim of synthesis, JSON | 557 B | 11142 B | +10585 B |
A receipts track ([moq-streaming-format](moq-streaming-format.md) §4.1) carries one group's
receipts per media group. A hybrid publisher's track grows by 5261 bytes a group, whatever the
group holds: at one group a second, by 42 kbit/s. Beside a group of one object (376 bytes
classical) that is fifteen times the track; of 30 objects (7409 bytes), 1.71 times; of 60 (16439
bytes), 1.32 times. A room's receipts are its tracks' receipts tracks, each a publisher's: the
cost is per publishing track and group, never per subscriber, and a subscriber pays it only for
the tracks it subscribes to. The second implementation, in pure Python, verifies an ML-DSA-65
signature in about 4 ms on an arm64 laptop (median of 45, Python 3.15).
---
## 10. Conformance
### 10.1 The vendored vectors
`pq-conformance/acvp/` holds FIPS 204's ACVP test vectors for ML-DSA-65, derived by `extract.py`
from the internal projections at the upstream commit named above, each upstream file and each
derived file pinned by SHA-256 (`pq-conformance/README.md`): key generation (25 vectors), the
deterministic signature generation of the external interface with a context, of the internal
interface, and of the internal interface over an external μ (15 each), and signature verification
over the same three interfaces (15 each, four of every five modified). The reference reproduces
every key and every signature byte for byte and gives every verification its verdict; the
second implementation verifies every signature both files state. `draft-composite-sigs-19.json`
is the draft's Appendix E vector for this suite, which both verify, with no context and with the
draft's.
### 10.2 The corpus
`pq-conformance/vectors.json`, written by `wai_pq_vectors gen` from seeds that are one byte
repeated 32 times (jwp-receipts §7.8: every key in it is published and attests nothing). Each case
is a group receipt (JSON or a group's receipts in the binary form, its objects verified by
inclusion), a claim, a record of §3.4's pattern, or a key log anchored by pinning; a group or claim
may carry a confirmation against a pinned log, with or without the hybrid requirement. The negative
controls include: the post-quantum half stripped, made over other bytes, and with a bit flipped;
a classical item under the policy of §5, under a hybrid entry, and under an anchor that requires
hybrid; a classical revision under such an anchor; a hybrid entry later listed without its key; a
child signed by a hybrid root's Ed25519 key alone and with another ML-DSA key; another parameter
set, named (`id-MLDSA44-Ed25519-SHA512`, validly signed) and by length. Every code of §8 is given.
A conforming verifier gives every case its stated verdict. `wai_pq_vectors verify` regenerates
the file byte for byte and checks every verdict; `pq_verify.py`, written from this text and
sharing no code with the reference, checks the vendored vectors, every case, the sizes of §9 and
this section's table of codes, and then requires every mutated case to be refused and every one
of its own checks, dropped, to be caught by the corpus.
---
## 11. References
- FIPS 204, *Module-Lattice-Based Digital Signature Standard*, August 2024.
- FIPS 180-4, *Secure Hash Standard*.
- `draft-ietf-lamps-pq-composite-sigs-19`, *Composite ML-DSA for use in X.509 Public Key
Infrastructure*.
- RFC 8032, *Edwards-Curve Digital Signature Algorithm (EdDSA)*.
- RFC 8785, *JSON Canonicalization Scheme (JCS)*.
- [jwp-receipts](jwp-receipts.md), SPEC §7 *Signatures*.

View file

@ -0,0 +1,525 @@
# WAI Extension: Robustness Evidence for Soft Bindings
> Status: Draft. Registers the record `wai.media.robustness`. A soft binding — a watermark read
> back out of the samples, or a fingerprint computed over them ([jwp-receipts](jwp-receipts.md)
> §2.6) — is worth what its algorithm survives, and a declaration states nothing about that. A
> **robustness record** measures it: the algorithm by term and definition digest, a **corpus**
> of pictures or clips each named by the SHA-256 of its samples, an **attack battery** of
> pinned, integer, seeded transforms with their exact parameters, the **harness** that runs
> them, and per attack the counts — items that survived out of the corpus, unmarked items read
> as marked out of the negatives — and rates derived from them as exact fractions, never
> floating point. Every step is an integer function of its inputs, so anyone who holds the
> corpus runs the battery, runs the detector and gets the same table, bit for bit; a verifier
> that does so **reproduces** the record, and one that cannot reads it as **stated**. A
> **robustness claim** — "survives `crop-5%`" — holds only where a record shows every item of
> its corpus survived that attack and no negative was read as marked; a claim with no record,
> or above what its records show, is refused. WAI's registered watermark,
> `wai-mark:tent64` ([synthesis](synthesis.md) §7.5), carries records over its measurement sets
> and a claim that is exactly the list its extension states. The record maps field for field
> onto the `robustnessEvidence` object a proposal to the C2PA soft-binding list describes
> (§11). No new transport. The reference implementation is the `robustness` module of `wai-rs`
> (feature `robustness`); the corpus is
> [`live-conformance/robustness/`](../live-conformance/robustness/), and its second
> implementation is `live-conformance/robustness_verify.py`.
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
>
> Texts read for this revision, each pinned to the version named: the C2PA Technical
> Specification, version 2.4, §9.3 and §18.10; and *Robustness Evidence for C2PA Soft-Binding
> Algorithms*, a proposal to the C2PA soft-binding and conformance task forces whose status is
> "proposal / reference results. Draft for discussion" and which states no version number, so
> this revision pins its text by digest: SHA-256
> `4ea8ab27711ef812a3cf8ade364cd40082ab797d071c87a6313217070dfbc9a2` as fetched on 22 October
> 2026. A section number of the C2PA text in this extension is that version's.
## 1. Scope
In scope: the records and their encodings (§2); the corpus (§3); the registered transforms
(§4); the robustness record (§5) and the harness it names (§6); exact rates (§7); robustness
claims and when one holds (§8); verification (§9); the records of WAI's own watermark (§10);
the mapping onto the proposed `robustnessEvidence` object (§11).
Out of scope: any soft-binding algorithm itself, which its own definition specifies (WAI's is
synthesis §7.5); a transport; which attacks a deployment ought to care about, which is the
relying party's; transforms of audio and of text, which this revision does not register, so a
corpus of either has no battery here yet (§3); and an adversary who knows the algorithm and
searches for a transform outside every battery, which no measurement bounds (§14).
Relationship to the core spec: `wai.media.robustness` 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.
Relationship to [jwp-receipts](jwp-receipts.md): a soft-binding match is evidence at the
algorithm's own error rates (§3.2 there, *What a match is worth*). This extension is where
those rates are measured and how a claim about them is held to its measurement. A recovery
(jwp-receipts §3.2) is unchanged by it: a verifier **MAY** report beside a recovery the
accepted claims and records it holds for the declaration's algorithm, and they change no step
of the recovery.
Relationship to [synthesis](synthesis.md): synthesis §7.5.7 defines the attack battery of
`wai-mark:tent64` and §7.5.8 states what the scheme claims to survive. §4 here registers that
battery's attacks as transforms with parameters, so a record names them by term; §10 gives the
scheme's records and its claim, which a verifier checks under §8.
## 2. Records
Every record of this extension is a JSON object under the encodings and the reading of
[synthesis](synthesis.md) §2 — byte strings in lowercase hexadecimal, unsigned integers of at
most 2^53 − 1, no other number, no boolean, strict reading of RFC 8259, exactly the members its
section lists at every level, and a `kind` naming it; otherwise `record_malformed` — with one
exception: a **rate** member (§7) is read after every other member, and one that holds anything
but an exact fraction is `rate_not_exact`, never `record_malformed`.
A **robustness record** (§5) and a **robustness claim** (§8) are signed:
```
sig = Ed25519(signer_key, "wai:robustness\x01" || JCS(record without "sig"))
link_hash = BLAKE3("wai:robustness-link\x01" || JCS(record))
```
JCS is RFC 8785, which on these values reduces to what jwp-receipts §2.4.3 states. The
signature is verified by WAI's strict rule ([SPEC](../SPEC.md) §7 *Signatures*): a key that
fails step 1 or 2 is `bad_key`, a signature that fails a later step `bad_signature`. A record
is named by its link hash wherever another names it. `issued_at` is a date-time of
jwp-receipts §2.4.3, self-asserted.
A **corpus document** (§3) is not signed: it is named by its **digest**, the SHA-256 of its
JCS, which every record that measures it states.
The **samples** of a picture or a clip are its canonical buffer: `RGB8`, row-major, three bytes
a pixel, no row padding ([reconstruction-binding](reconstruction-binding.md) §2), frame after
frame in presentation order, as synthesis §2 has it. An item is named by the SHA-256 of its
samples.
## 3. The corpus
A corpus document, `kind` `"wai-robustness-corpus"`:
| member | type | meaning |
|---|---|---|
| `kind` | string | `"wai-robustness-corpus"` |
| `name` | term | A label for people; nothing is checked against it. |
| `media` | string | `"image"` or `"video"`: what every item is. |
| `items` | array | The items an algorithm binds: each marked with its value (a watermark) or bound to it (a fingerprint), then attacked. |
| `negatives` | array | The items it does not bind, read after the same attacks to count false positives. They may be the same samples as `items`, unmarked. |
Each entry of `items` and of `negatives` is an object of exactly these members:
| member | type | meaning |
|---|---|---|
| `name` | term | The item's name, unique within its list. |
| `frames` | integer | How many frames; 1 for every item of an `image` corpus. |
| `width`, `height` | integer | The size of each frame, in pixels. |
| `samples` | 32 B hex | SHA-256 of its samples (§2). |
A corpus document with no item or no negative, a name twice in one list, a `frames`, `width` or
`height` of 0, an `image` item of more than one frame, or an item of more than 2^53 − 1 bytes
(`frames`·`width`·`height`·3) is `corpus_malformed`, as is one that does not read under §2.
An item is held by its samples: a verifier that holds a buffer finds it by its SHA-256, and a
buffer it holds for an item is `frames`·`width`·`height`·3 bytes (`samples_mismatch`). A
corpus is a list of digests, so it can be published without its samples; a record over it is
then **stated** to everyone who does not hold them (§9).
A corpus of audio or of text needs transforms of its medium, which §4 does not register: its
`media` is a later revision's.
## 4. The transforms
A **transform** is named by a term and takes integer parameters. Applied to an item's frames at
a **seed**, each one gives other frames, an integer function of the frames, the parameters and
the seed alone, so its result is the same bytes on every machine. Below, rnd(*n* / *d*) is
*n* / *d* rounded to the nearest integer, halves away from zero, and every sample is clamped to
0 … 255, as in synthesis §7.5.7, whose definitions these are where the table names them.
| transform | parameters | media | the frames it gives |
|---|---|---|---|
| `wai-attack:none` | none | both | the frames unchanged |
| `wai-attack:int-motion` | *q*, 1 to 255 | both | each frame a keyframe of `wai.video.int_motion` at step *q* (`int-motion-q`*q*) |
| `wai-attack:staged-base` | *q*, 1 to 255 | both | each frame's staged base at step *q* (`staged-base-q8`'s definition at *q*) |
| `wai-attack:denoise3` | *n*, 1 to 16 | both | `wai-synthesis:denoise3` applied *n* times (synthesis §4.2) |
| `wai-attack:scale` | *n*, *d*, each 1 to 16 | both | area resampling to ⌊*W*·*n*/*d*⌋ × ⌊*H*·*n*/*d*⌋ (`scale-`*n*`/`*d*) |
| `wai-attack:aspect` | *n*, *d*, each 1 to 16 | both | area resampling of the width alone to ⌊*W*·*n*/*d*⌋ (`aspect-3/4`'s definition at *n*/*d*) |
| `wai-attack:upscale2` | none | both | `wai-synthesis:upscale2` (synthesis §4.1) |
| `wai-attack:half-then-int-motion` | *q*, 1 to 255 | both | `scale` 1/2, then `int-motion` at *q* |
| `wai-attack:crop` | *p*, 0 to 99 | both | ⌊*W*·*p*/200⌋ columns removed from each side and ⌊*H*·*p*/200⌋ rows from the top and from the bottom (`crop-`*p*`%`) |
| `wai-attack:mirror` | none | both | the columns in reverse order |
| `wai-attack:rotate-90` | none | both | a quarter turn clockwise |
| `wai-attack:rotate` | *c*, *s*, each 0 to 65536; *k*, 0 or 1 | both | the rotation of `rotate-0.5`'s definition with cosine *c* and sine *s* at 2^16, the sine negated where *k* is 1 |
| `wai-attack:noise` | *s*, 0 to 255 | both | noise uniform in −*s* … *s* from the stream of `noise-`*s* at the seed |
| `wai-attack:brightness` | *b*, 0 to 255; *k*, 0 or 1 | both | *v* + *b*, or *v* − *b* where *k* is 1 |
| `wai-attack:contrast` | *n*, *d*, each 1 to 16 | both | 128 + rnd((*v* − 128)·*n* / *d*) |
| `wai-attack:gamma` | *n*, *d*, each 1 to 6 | both | below |
| `wai-attack:local-blur` | none | both | `local-blur` |
| `wai-attack:clip-int-motion` | *q*, 1 to 255 | `video` | the clip encoded as `wai.video.int_motion` with motion at step *q* (`clip-int-motion-q`*q*) |
| `wai-attack:frame-drop` | none | `video` | frames 0, 2, 4, … |
| `wai-attack:one-frame` | none | `video` | the first frame alone |
**Gamma.** Each sample *v* becomes the greatest *y* from 0 to 255 such that *y* = 0 or
(2*y* − 1)^*d*·255^*n* ≤ 2^*d*·*v*^*n*·255^*d*: 255·(*v*/255)^(*n*/*d*) rounded to the nearest
integer, halves up, computed in integers. With *n* and *d* at most 6 every product is below
2^103. A gamma below 1 (*n* < *d*) lifts the dark samples, one above it darkens them; a
display's response and an encoder's transfer function differ from a picture's by such a curve.
A transform is applied to every frame of an item and to every channel of every sample. The
seed matters only to `noise`; every transform takes one. A transform's parameters, outside the
table's ranges or of the wrong number, are `transform_invalid`. A transform applied to a
corpus whose `media` the table does not list for it is `battery_not_applicable`. A term the
table does not register is admitted in a record: what it does is its definer's, a verifier
here cannot run it, and a record that names it is stated (§9).
The table is the battery of synthesis §7.5.7 with its parameters free, and `gamma`. More
transforms are registrations in a later revision, each an integer function with its
parameters' ranges.
## 5. The robustness record
The party that measured an algorithm signs a robustness record, `kind` `"wai-robustness"`:
| member | type | meaning |
|---|---|---|
| `kind` | string | `"wai-robustness"` |
| `algorithm` | term | The algorithm measured: a registered soft-binding algorithm's term, as a soft-binding claim's `alg` names it (jwp-receipts §2.6.2), or a WAI scheme's (synthesis §7.4). |
| `algorithm_digest` | 32 B hex | SHA-256 of the algorithm's definition. |
| `binding_type` | string | `"watermark"` or `"fingerprint"`, as jwp-receipts §2.6.2 types it. |
| `media` | string | The corpus's `media`. |
| `corpus` | 32 B hex | The corpus document's digest (§2). |
| `values` | array of hex | One per item of the corpus, in its order: the value the item is marked with (a watermark) or bound to (a fingerprint). Each is at least one byte. |
| `battery` | array | The attacks, in order, below. |
| `harness` | term | The procedure that ran them: `wai-robustness-harness:1` for §6. |
| `table` | array | One row per attack, in the battery's order, below. |
| `issued_at` | date-time | When it signed. |
| `signer_pubkey`, `sig` | | §2 |
An **attack** is an object of exactly `attack` (a term: its name, unique within the battery),
`transform` (a term of §4, or one this revision does not register), `params` (an array of
integers) and `seed` (an integer below 2^32: the four bytes a stream of synthesis §7.5.7 reads
it as). A **row** is an object of exactly:
| member | type | meaning |
|---|---|---|
| `attack` | term | The attack's name. |
| `trials` | integer | The corpus's items: how many marked items were attacked. |
| `survived` | integer | How many of them, attacked, gave their own value (§6). |
| `wrong` | integer | How many gave another value. |
| `negatives` | integer | The corpus's negatives: how many were attacked. |
| `false_positives` | integer | How many of them, attacked, gave a value (§6). |
| `survival` | rate | `survived` / `trials` (§7). |
| `false_positive_rate` | rate | `false_positives` / `negatives`. |
| `balanced_accuracy` | rate | The mean of `survival` and the true-negative rate (§7). |
| `tpr_at_1pct_fpr` | rate or `null` | `survival` where `false_positives`·100 ≤ `negatives`; `null` otherwise (§7). |
`missed`, the items that gave nothing, is `trials` − `survived` − `wrong`.
Its checks, in order, after reading and the signature (§2):
1. the battery has at least one attack, its names are unique and each seed is below 2^32
(`battery_malformed`); each registered transform's parameters fit §4
(`transform_invalid`), and then each one's media the record's (`battery_not_applicable`);
2. the table has one row per attack, with the attack's name, in the battery's order
(`table_malformed`);
3. in each row: `trials` is the number of `values` and at least 1; `survived` + `wrong` ≤
`trials`; `negatives` is at least 1 and the same in every row; `false_positives` ≤
`negatives` (`table_inconsistent`);
4. each rate is the one its row's counts give (§7, `rate_mismatch`);
5. an algorithm this revision registers is named with its digest and its binding type —
`wai-mark:tent64` is a `watermark` — (`algorithm_mismatch`), and the values are values the
algorithm takes: for `wai-mark:tent64`, 8-byte payloads whose first byte is a class code, 0
to 3 (synthesis §7.2) (`values_invalid`).
Then against what the verifier was given (§9.1): the corpus document, and the samples it holds.
6. The corpus document reads under §3 (`corpus_malformed`); its digest is `corpus` and its
`media` the record's (`corpus_mismatch`); it has as many items as `values` and as many
negatives as each row's `negatives` (`table_inconsistent`).
7. Each item and negative whose samples it holds is the size §3 gives (`samples_mismatch`).
8. **Reproduction.** Where the verifier holds the corpus document and the samples of every item
and negative, implements the algorithm, the record names the harness of §6, and every
transform of the battery is registered, it runs the harness (§6): a fingerprint's values are its own value of each item
(`values_invalid`), and the table it gets is the record's, row for row and count for count
(`table_irreproducible`). The record is then **reproduced**; otherwise **stated**.
A reproduced record says that the algorithm, run by this harness on this corpus under this
battery, gives this table: not that it survives an attack outside the battery, a parameter
between two measured, or content unlike the corpus. A stated record is its signer's statement,
checked for its arithmetic and nothing else.
## 6. The harness
`wai-robustness-harness:1` is this procedure. For each attack of the battery, in order, with
its transform *T*, parameters and seed *s*:
- **Watermark.** For each item *k*, in order: its frames are marked with `values`[*k*] by the
algorithm's embedding; *T* is applied to the marked frames at *s*; the algorithm's detector
runs on the result. It **survived** where the detector reads `values`[*k*], is **wrong** where
it reads another value, and is **missed** where it reads none. For each negative, in order:
*T* is applied to its frames, unmarked, at *s*, and the detector runs on the result; a
**false positive** is any value read.
- **Fingerprint.** For each item *k*: `values`[*k*] is the algorithm's value of the item's
frames; *T* is applied to the frames at *s*, and the value of the result is computed. It
survived where that value matches `values`[*k*] under the algorithm's own rule, is wrong where
it matches another item's value and not its own, and is missed otherwise. For each negative:
the value of *T* applied to its frames is computed, and it is a false positive where that
value matches any item's value.
Every attack sees the frames as marked or as given, never the result of another attack. Each
step is an integer function where the algorithm's embedding and detector are, as `tent64`'s
are (synthesis §7.5), so the table is a function of the record's inputs, and a second run
anywhere gives it bit for bit.
The **seed** is the record's: synthesis §7.5.7 seeds the attack at index *i* of its lists with
*i*, and a record of that battery states those seeds (§10).
## 7. Rates
A **rate** is an exact fraction, written as an array of two integers `[n, d]`: 1 ≤ *d*,
0 ≤ *n* ≤ *d*, and *n* and *d* with no common factor above 1, so 0 is `[0, 1]`, 1 is `[1, 1]`,
and every rate has one spelling. A number, a string, an array of another length or of other
values, a fraction not in lowest terms or one above 1 is `rate_not_exact`. A rate is never
floating point: a record's table is its counts, and its rates are the counts' quotients, which
any reader recomputes exactly and compares as integers.
For a row with counts `trials` *N*, `survived` *S*, `negatives` *U* and `false_positives` *F*:
- `survival` = *S* / *N*, the true-positive rate;
- `false_positive_rate` = *F* / *U*;
- `balanced_accuracy` = (*S*·*U* + (*U* − *F*)·*N*) / (2·*N*·*U*): the mean of the
true-positive rate *S*/*N* and the true-negative rate (*U* − *F*)/*U*;
- `tpr_at_1pct_fpr` = *S* / *N* where 100·*F* ≤ *U*, and `null` otherwise.
Each reduced to lowest terms. A detector that gives a value or none has one operating point, so
its true-positive rate at a false-positive rate of at most 1% is its rate where its measured
false-positive rate is at most 1%, and is not attained where it is above. The measured rate is
an observation over *U* negatives: 0 of 32 says no negative of the corpus was read as marked,
not that the algorithm's false-positive rate is below 1%, which only a bound of the algorithm's
own definition gives (synthesis §7.5.6 for `tent64`).
## 8. Robustness claims
An algorithm's **robustness claim** is the list of attacks it claims to survive. Its registrant
signs it, `kind` `"wai-robustness-claim"`:
| member | type | meaning |
|---|---|---|
| `kind` | string | `"wai-robustness-claim"` |
| `algorithm`, `algorithm_digest` | | As §5's: the algorithm the claim is about. |
| `survives` | array | The attacks claimed, at least one: each an object of exactly `media` (`"image"` or `"video"`), `transform` (a term) and `params` (an array of integers), no two equal. |
| `evidence` | array of 32 B hex | The link hashes of the robustness records it rests on, no two equal. |
| `issued_at` | date-time | When it signed. |
| `signer_pubkey`, `sig` | | §2 |
A claimed attack is named by its media, its transform and its parameters, and not by a seed: a
claim is about the transform, and a record shows it at the seed it states. A record **measures**
a claimed attack where its `media` is the attack's and its battery has an attack with that
transform and those parameters; its row **shows survival** where `survived` = `trials`,
`wrong` = 0 and `false_positives` = 0: every item of the corpus, attacked, gave its own value,
and no negative, attacked, gave any. This is the rule synthesis §7.5.8 states for its scheme.
A claim **holds** where, after reading and the signature (§2), in this order:
1. every record it cites was verified earlier in the case (§9.2) (`evidence_not_held`), and is
about the claim's algorithm, by term and digest (`evidence_mismatch`);
2. under a policy that requires reproduced evidence (§9.1), every record it cites was
reproduced (`evidence_not_reproduced`);
3. for each attack it claims, in order: at least one cited record measures it
(`claim_unevidenced`), and every cited record that measures it shows survival
(`claim_exceeds_evidence`).
So a claim with no record, a claim of an attack no record measured, and a claim of an attack a
record shows lost — one item missed under it, or one negative read as marked — are refused,
each with its own reason. A claim is as strong as the records it cites and no stronger: it
covers the parameters measured and not those between them, the corpus's kind of content and
not every kind, and a stated record's table as its signer stated it. A claim that holds over
reproduced records is **reproduced**; over any stated record, **stated**.
## 9. Verification
### 9.1 Inputs
A verifier is given a **case**: records in an order, as texts; with any robustness record, the
corpus document it was handed as that record's corpus, or none; the samples it holds, each
found by its SHA-256; the algorithms it implements, by term (each with the digest §5 check 5
pins); and its policy, `evidence`: `reproduced`, a claim's records must be reproduced (§8 step
2), or `stated`. A verifier bounds what it runs: this revision's reproduces items whose frames
are at most 2^26 bytes each and at most 2^30 bytes in all, the caps of the integer video
encoder its transforms call ([integer-payloads](integer-payloads.md) §7), and states a record
over a larger item.
### 9.2 Steps
The records are verified in their order, each by its `kind`: a robustness record by §5, a
robustness claim by §8. A record whose `kind` is neither, or that does not read, is
`record_malformed`. The first check that fails is the case's refusal, with the record's
position. A robustness record a claim cites is held only once it has been verified, earlier
in the case.
### 9.3 What an accepted case states
For each record, in order, its `kind`, its link hash and its status: for a robustness record,
`reproduced` or `stated`, with its algorithm, its corpus and its number of attacks; for a
claim, `reproduced` or `stated` (§8), with its algorithm and its number of attacks claimed.
## 10. WAI's own schemes
`wai-mark:tent64` (synthesis §7.5) carries three robustness records, one per measurement set of
synthesis §7.5.8, and a robustness claim, in the corpus (§13):
- **The corpora.** `spectral` and `leaves`, of `media` `image`, sixteen pictures of 512 × 512
each; `clips`, of `media` `video`, four clips of eight frames of 256 × 256: the sets the
synthesis corpus generates from fixed seeds, each item named by the SHA-256 of its samples.
Their negatives are the same samples, unmarked, as synthesis §7.5.8 reads them. The
photographs of synthesis §7.5.8 are not in the repository, so they have no record here.
- **The values** are the payloads synthesis §7.5.8 marked each item with: class 3, then the
first seven bytes of SHA-256(`wai-mark:battery payload` ‖ 0x00 ‖ the item's name).
- **The battery** is synthesis §7.5.7's lists, the pictures' for `spectral` and `leaves` and
the clips' for `clips`, each attack under its name there, its transform and parameters by
this table, and the seed of its index in its list:
| synthesis §7.5.7 | transform and parameters |
|---|---|
| `none` | `none` |
| `int-motion-q`*q*, `clip-int-motion-q`*q*, `staged-base-q`*q*, `half-then-int-motion-q`*q* | `int-motion`, `clip-int-motion`, `staged-base`, `half-then-int-motion`, each [*q*] |
| `denoise3`, `denoise3-x4` | `denoise3` [1], [4] |
| `scale-`*n*`/`*d*, `aspect-`*n*`/`*d*, `contrast-`*n*`/`*d* | `scale`, `aspect`, `contrast`, each [*n*, *d*] |
| `upscale2`, `mirror`, `rotate-90`, `local-blur`, `frame-drop`, `one-frame` | the transform of that name |
| `crop-`*p*`%` | `crop` [*p*] |
| `rotate-0.5`, `rotate-1`, `rotate-2` | `rotate` [65534, 572, 0], [65526, 1144, 0], [65496, 2287, 0] |
| `noise-`*s* | `noise` [*s*] |
| `brightness+32`, `brightness-32` | `brightness` [32, 0], [32, 1] |
- **The tables** are the harness's on those inputs, and equal synthesis §7.5.8's columns
`spectral`, `leaves` and `clips`: `survived` its count of pictures that gave their payload,
`wrong` 0, `false_positives` the unmarked pictures that gave any, 0 in every row.
- **The claim** is exactly the list of synthesis §7.5.8, *claims to survive*: its picture
attacks with `media` `image`, its clip attacks with `media` `video`, citing the three records.
It holds (§8): each attack it claims is measured, and shows survival, in every record of its
media. `scale-1/4`, which both sets survive, is not claimed, because one photograph of
synthesis §7.5.8 did not; a claim may claim less than its records show.
The registrant of `wai-mark:tent64`'s records in the corpus is a key of the corpus, derived
from a fixed seed: the records show the measurement, and their signature shows who stated it.
Anyone who holds the generated sets reproduces them; the corpus holds the sets' digests and not
their samples, so a verifier without the reference's generators reads them as stated, and
checks their tables against the synthesis corpus's `battery.json`, a measurement written by
another program (§13).
`wai-mark:tent64s`, the tiled scheme proposed beside it, is measured by the same battery with
attacks of its own; its records are a registration of the revision that registers it.
## 11. The proposed `robustnessEvidence` object
*Informative.* *Robustness Evidence for C2PA Soft-Binding Algorithms* (pinned in the header)
proposes an optional `robustnessEvidence` object in an entry of the C2PA soft-binding algorithm
list (C2PA 2.4 §18.10.4), filled by the algorithm's owner: a `methodology`, a `corpus`, a
`harness`, a `date`, and `results`, by attack, each with a `balancedAccuracy`. It observes that
the list's entries carry prose robustness claims with no measured evidence and no shared way to
produce it, and names, beside balanced accuracy, the survival (true-positive) rate and, for
formal use, the true-positive rate at 1% false-positive rate. A robustness record gives each of
its members:
| `robustnessEvidence` | from a robustness record |
|---|---|
| `methodology` | the extension and section of `harness`: `robustness-evidence §6, wai-robustness-harness:1` |
| `corpus` | `sha256:` and the hex of `corpus`; the corpus document names each item by the SHA-256 of its samples |
| `harness` | `harness`, and the implementation that ran it |
| `date` | the date of `issued_at` |
| `results` | one member per row, under the row's `attack` |
| `results.<attack>.balancedAccuracy` | `balanced_accuracy` [*n*, *d*], written as the decimal *n*/*d* |
| survival rate | `survival` |
| true-positive rate at 1% false-positive rate | `tpr_at_1pct_fpr`, absent where `null` |
| false-match rate | `false_positive_rate` |
The mapping runs one way. The object carries rates as decimal numbers, which a record never
does, and not the counts, the battery's transforms with their parameters and seeds, the
algorithm's digest, the corpus's items or a signature; so a record gives the object, and the
object does not give a record. A verifier of the object reads the decimals as their signer
wrote them; a verifier of the record recomputes the counts (§9). The proposal asks for each
owner to measure its own algorithm and for no ranking across owners; a record carries no
comparison either, and is about one algorithm on one corpus. The proposal's reference results
are of text, whose transforms §4 does not register (§3).
## 12. Reasons
The codes this extension adds, each with where it is raised:
| reason | raised at |
|---|---|
| `record_malformed` | §2, §9.2 |
| `rate_not_exact` | §2, §7 |
| `bad_key` | §2 |
| `bad_signature` | §2 |
| `battery_malformed` | §5 check 1 |
| `transform_invalid` | §4, §5 check 1 |
| `battery_not_applicable` | §4, §5 check 1 |
| `table_malformed` | §5 check 2 |
| `table_inconsistent` | §5 checks 3 and 6 |
| `rate_mismatch` | §5 check 4, §7 |
| `algorithm_mismatch` | §5 check 5 |
| `values_invalid` | §5 checks 5 and 8 |
| `corpus_mismatch` | §5 check 6 |
| `corpus_malformed` | §3, §5 check 6 |
| `samples_mismatch` | §3, §5 check 7 |
| `table_irreproducible` | §5 check 8 |
| `evidence_not_held` | §8 step 1 |
| `evidence_mismatch` | §8 step 1 |
| `evidence_not_reproduced` | §8 step 2 |
| `claim_unevidenced` | §8 step 3 |
| `claim_exceeds_evidence` | §8 step 3 |
## 13. Conformance
[`live-conformance/robustness/`](../live-conformance/robustness/) holds the corpus, written from
fixed seeds by `wai_robustness_vectors gen`. It has:
- **Corpus documents**: `conformance`, three pictures of 256 × 256 whose samples the corpus
holds; and `tent64-spectral`, `tent64-leaves` and `tent64-clips`, the measurement sets of §10,
by their digests.
- **Robustness records**: one over `conformance` with a battery of thirteen attacks — among
them both gammas, a crop and a small rotation the scheme does not survive, and a quarter turn,
a mirror and a re-encode it does — which any verifier holding its samples reproduces, the
harness rerun end to end; and the three records of `wai-mark:tent64` of §10, stated without
their samples.
- **Robustness claims**: `wai-mark:tent64`'s claim of §10, and a claim over the conformance
record under a policy that requires reproduced evidence.
- **Cases** refused for each reason of §12, among them a record whose table does not
recompute (one count changed and its rates with it, signed again), a record over a corpus
digest that is not the corpus document's, a rate written as a decimal number, a rate not in
lowest terms, a claim of an attack its records show lost, a claim of an attack no record
measured, a claim citing no record, and a claim under a policy that requires reproduced
evidence, citing stated records.
A conforming verifier gives every case the outcome, the reason, the record and the statements
the corpus states. `wai_robustness_vectors verify` and the test `tests/robustness.rs` check that
the files regenerate byte for byte — the records of `wai-mark:tent64` among them, which needs
the harness run over the generated sets — that `wai-rs` gives every case its outcome, that
every reason of §12 appears, that §12 lists exactly the reference's codes, that each transform
gives the bytes synthesis §7.5.7's battery gives for every attack of it, that the tent64
records' tables equal the synthesis corpus's `battery.json`, and that the tent64 claim is
synthesis §7.5.8's list. `live-conformance/robustness_verify.py` is the second implementation,
written from this text: it shares no code with `wai-rs`; it runs `wai-mark:tent64` with the
synthesis corpus's second implementation (`_wai_mark.py`), implements the transforms of §4,
reruns the conformance record's battery end to end on the samples the corpus holds and
requires the same table, checks every signature with WAI's strict rule
(`claim-conformance/_ed25519.py`) and every link hash with BLAKE3 from
`claim-conformance/_blake3.py`, checks the tent64 records against `battery.json` and the
claim against synthesis §7.5.8's text; it mutates copies of the corpus and requires every copy
to fail, and drops each of its own checks in turn and requires the corpus to catch the
weakened verifier.
## 14. Security and privacy considerations
- **A battery is not an adversary.** A record measures the transforms its battery names. An
adversary who knows the algorithm searches for one outside them, and a key-free watermark
(synthesis §7.5.6) can be read, and so attacked, by anyone. A claim is a floor under the
transforms it names, never a statement that the binding cannot be removed.
- **Choosing the corpus.** The party that measures chooses the corpus, and a corpus of content
the algorithm favours shows more than one that it does not. A record names its corpus by
digest so a reader can see what was measured, and a claim covers that kind of content and no
other (§8). A relying party that needs a rate for its own content measures its own corpus.
- **Stated records.** A record whose corpus a verifier does not hold is checked for its
arithmetic and its signature only. Its table is its signer's statement; under a policy that
requires reproduced evidence a claim resting on it is refused (§8 step 2).
- **What a negative count shows.** False positives over *U* negatives bound nothing below 1/*U*
(§7). An algorithm's false-positive bound is its definition's, derived and checked there.
- **Privacy.** A corpus is content; a published record names its items by digest and carries
no samples. A party that publishes a corpus of pictures of people publishes those pictures;
the record does not require it.

View file

@ -0,0 +1,614 @@
# WAI Extension: Exact Splats
> Status: Draft. Registers the record `wai.splat.exact`: a Gaussian splat set that travels in a
> glTF 2.0 asset as an integer-coded WAI object, and a renderer whose frames are the same bytes
> on every machine, so a frame can be signed. A `wai.splat.int_codec` object rides in a mesh
> primitive of the asset through the draft compression extension
> `EXT_gaussian_splatting_compression_wai`, nested in the primitive's `KHR_gaussian_splatting`
> object: a buffer view holds the object's `WAI1` envelope, and the extension states its content
> hash and its parameter set (§3). The decode is integer throughout, so the attribute planes are
> bit-exact on every machine, and §4 maps them onto the base extension's attributes. The renderer
> `wai-splat-render:i1` (§5) is integer too: a fixed-point camera and projection, an order by
> squared camera distance with the Gaussian's index breaking every tie, alpha compositing with
> each rounding stated, and 16 × 16 tiles in raster order. The origin signs a **commitment**
> (§6): the object, its parameter set, the digest of its decoded attributes, and the SHA-256 of
> the frame at each of a set of **canonical poses**, so a viewer recomputes what the scene looks
> like from each of them, bit for bit. A sink signs a **view statement** for a frame it
> presented at a pose (§7). A view is a conversion of the splat set under the class lattice of
> [synthesis](synthesis.md) §3.2, so it is never labelled lower than the splat set it shows (§8).
> No new transport. The reference implementation is the `splat_exact` module of `wai-rs`
> (feature `splat_exact`); the corpus is [`live-conformance/splat/`](../live-conformance/splat/),
> and its second implementation is `live-conformance/splat_exact_verify.py`.
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
>
> Texts read for this revision, each pinned to the version named: glTF 2.0 as ISO/IEC
> 12113:2022, and the glTF extension registry's repository as it stood on 22 October 2026: the
> mesh primitive extension `KHR_gaussian_splatting`, whose text states its status as complete and
> ratified, added by pull request #2490 (merged 27 January 2026) and last changed by #2677 (merged
> 13 October 2026), with its schema `mesh.primitive.KHR_gaussian_splatting.schema.json`; the
> compression extensions proposed for it and still under review on that date,
> `KHR_gaussian_splatting_compression_spz_2` (pull request #2531), `KHR_gaussian_splatting_lgsc`
> (#2551) and `KHR_gaussian_splatting_compression_EGSC` (#2605); the earlier single proposal
> those replaced, `KHR_spz_gaussian_splats_compression` (draft #2486, closed); and the general
> compression extension `KHR_meshopt_compression` (#2517, merged). A section number of one of
> those texts in this extension is that version's.
## 1. Scope
In scope: the records and their encodings (§2); how a glTF asset carries a `wai.splat.int_codec`
object and the draft extension's schema (§3); the attribute layout, its dequantization and its
mapping onto `KHR_gaussian_splatting` (§4); the renderer `wai-splat-render:i1` (§5); canonical
poses and the commitment (§6); the view statement (§7); provenance (§8); verification (§9).
Out of scope: a transport; how a splat set is trained or encoded; the glTF node hierarchy (a
pose is in the primitive's own frame, §2); view-dependent colour (spherical harmonics of degree
above 0); lighting. WAI does not submit this extension to the glTF extension registry; its name
is WAI's draft, and §3.5 says what would change if the registry took up a WAI form.
**Why a compression extension.** `KHR_gaussian_splatting` defines a splat primitive and admits
compression extensions nested in its own `extensions` object: such an extension says how its data
decodes back to the base attributes. The base text fixes the order of a render (back to front by
camera distance) and its 3σ kernel, and leaves the arithmetic to the renderer. This extension
carries an integer-coded object whose decode is fixed to the bit, and pins a renderer, so the step
from bytes to pixels is the same on every machine.
**Why a pinned renderer.** A splat renderer that sorts, projects and blends in floating point
does so in orders and widths that differ between devices and drivers: two viewers of one asset
see different pixels, and a frame cannot be signed. §12 measures it: the same floating-point
renderer in 32-bit and in 64-bit arithmetic gives different bytes for views of the corpus, and
for more of them the larger the frame. `wai-splat-render:i1` is integer from the attribute bytes
to the frame, so its frame is a function of the asset and the pose, and its digest can be
committed to and signed.
Relationship to the core spec: `wai.splat.exact` is a **record** ([SPEC](../SPEC.md) §5): it names
no payload format and is not dispatchable (SPEC §4). The payload it carries is
`wai.splat.int_codec`'s (`WIS1`, [integer-payloads](integer-payloads.md) §6).
## 2. Records
Every record of this extension is a JSON object (RFC 8259) under the encodings of
[jwp-receipts](jwp-receipts.md) §2.4.3: byte strings in lowercase hexadecimal; integers unsigned,
at most 2^53 − 1, in plain decimal; no other number; no boolean; a **term** and a **date-time** as
defined there. A record is read as jwp-receipts §3.1 step 1 reads a claim: RFC 8259's grammar, no
member named twice in one object, at most 32 levels of nesting. Each record has exactly the
members its section lists, no member missing and none added, at any level, and a `kind` naming it;
one that does not is `record_malformed`.
Every record carries `signer_pubkey` (32 bytes, the Ed25519 key of RFC 8032 that signs it),
`issued_at` (a date-time, when its signer signed it, self-asserted) and `sig` (64 bytes):
```
sig = Ed25519(signer_key, "wai:splat-exact\x01" || JCS(record without "sig"))
link_hash = BLAKE3("wai:splat-exact-link\x01" || JCS(record))
```
JCS is RFC 8785. 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 wherever another names it. An object's **content hash** is
jwp-receipts §2.1's: BLAKE3 over `moq-jwp:object\x01` and the envelope's bytes.
A **signed integer** is a string: `0`, or an optional `-` and a digit 1–9 followed by digits (so
`-0`, `+1` and `01` are not one), of magnitude at most 2^28.
A **pose** is an object of exactly these members:
| member | type | meaning |
|---|---|---|
| `eye` | 3 signed integers | the camera's position, at 2^16, in the primitive's own frame (the node transform is not applied) |
| `target` | 3 signed integers | the point it looks at, at 2^16 |
| `up` | 3 signed integers | its up direction, at 2^16, of any length |
| `focal` | integer | the focal length in pixels, 1 to 4096 |
| `width`, `height` | integer | the frame's size in pixels, each 1 to 1024, their product at most 2^20 |
A pose that breaks a rule of this table is `record_malformed`. Two poses are the same pose when
every member is equal.
## 3. Carriage in glTF
### 3.1 The primitive
A splat set travels as one mesh primitive of a glTF 2.0 asset (ISO/IEC 12113:2022; its
`asset.version` is `"2.0"`) that carries
the extension object `KHR_gaussian_splatting`, and in it, under that object's own `extensions`,
the object `EXT_gaussian_splatting_compression_wai` (§3.2). The primitive:
- has `mode` 0 (`POINTS`), written;
- holds `KHR_gaussian_splatting` with `kernel` `"ellipse"` and `colorSpace`
`"srgb_rec709_display"`, and `projection` and `sortingMethod` absent or `"perspective"` and
`"cameraDistance"`;
- names exactly five attributes, each an accessor of component type `FLOAT` (5126) with no
`bufferView` and a `count`: `POSITION` (`VEC3`), `KHR_gaussian_splatting:ROTATION` (`VEC4`),
`KHR_gaussian_splatting:SCALE` (`VEC3`), `KHR_gaussian_splatting:OPACITY` (`SCALAR`) and
`KHR_gaussian_splatting:SH_DEGREE_0_COEF_0` (`VEC3`). glTF 2.0 initialises an accessor with no buffer view
with zeros and lets an extension override them; a sink that implements this extension fills
them from the decode (§4.3).
An asset carries one such primitive in this revision. The asset's `extensionsUsed` and
`extensionsRequired` both list `KHR_gaussian_splatting` and
`EXT_gaussian_splatting_compression_wai`: the accessors carry no data, so a reader without this
extension has nothing to fall back to, and the base extension asks that such an extension be
required.
### 3.2 The extension object
`EXT_gaussian_splatting_compression_wai` has these members:
| member | type | presence | meaning |
|---|---|---|---|
| `bufferView` | integer | required | the buffer view that holds the object's `WAI1` envelope ([SPEC](../SPEC.md) §2), and nothing else |
| `capability` | string | required | the envelope's capability: `"wai.splat.int_codec"` in this revision |
| `object` | 32 B hex | required | the envelope's content hash (§2) |
| `set` | object | required | the parameter set: `{"sha256", "bufferView"}`, its SHA-256 (the envelope's pin, SPEC §3.1) and, where the asset carries the set, the buffer view that holds its one file (`g_s.whm`, [integer-payloads](integer-payloads.md) §9); `bufferView` absent where it does not |
| `commitment` | integer | optional | the buffer view that holds the commitment's text (§6.1) |
| `extensions`, `extras` | object | optional | glTF's own |
An object that lacks a required member, whose buffer views do not read (a view that names no
buffer, a buffer whose `byteLength` is not its bytes' length, or a range past its buffer), or
whose `object` or `set.sha256` is not 32 bytes of hex, is `asset_malformed`. A `capability` that is
a string other than `"wai.splat.int_codec"` is `capability_mismatch`. The members are read in
this order: the buffer view of `bufferView`, `capability`, `object`, `set`, `commitment`.
The commitment is carried as text in a buffer, not as JSON inside the asset, so it is read as §2
reads a record, byte for byte, whatever the reader of the asset's JSON does with its numbers and
members.
### 3.3 The envelope, its set and the decode
The buffer view holds exactly one `WAI1` envelope: its magic, its manifest's length and manifest,
its payload's length and payload, and no byte after them (otherwise `asset_malformed`). Then:
1. Its capability is `wai.splat.int_codec` (`capability_mismatch`).
2. Its content hash is the extension's `object` (`object_mismatch`).
3. Its manifest's pin (`conditioning.prior`, SPEC §3.1) names the extension's `set.sha256`
(`set_mismatch`). The set is the buffer view `set.bufferView` names, or else the file a
verifier holds whose SHA-256 is `set.sha256` (`set_not_held` where it holds none). Its SHA-256
is `set.sha256`, and the pin is verified as SPEC §3.1 has it (`set_mismatch`).
4. The payload is decoded as [integer-payloads](integer-payloads.md) §6 has it, against that set;
a payload the decode refuses, with any code of integer-payloads §8, is `decode_refused`.
The decode gives `attr` planes of `s × s` bytes and the payload's `n_gaussians` and ranges. Every
step of it is integer, so these bytes are the same on every machine: the buffer of the
capability's splat-equivalence digest. Their SHA-256 is the splat set's **attribute digest**.
### 3.4 The accessors
After the decode, every accessor's `count` is `n_gaussians`, the decode has at least three planes,
and `POSITION` has `min` and `max`, three numbers each, equal to the least and the greatest
dequantized coordinate on each axis (§4.2) divided by 2^16. Every such value is exact in binary64,
so a reader of the asset's JSON reads the same number. Otherwise `asset_malformed`. (glTF 2.0
requires `min` and `max` on `POSITION`; this makes them the decode's own.)
### 3.5 The draft schema, and the registry
The extension object's JSON Schema, draft 2020-12, is
[`gltf/EXT_gaussian_splatting_compression_wai.schema.json`](gltf/EXT_gaussian_splatting_compression_wai.schema.json).
It states what §3.2 states of each member's type and presence; the rules that need the envelope,
the set or the decode are this section's, not the schema's.
The name has the prefix glTF's registry gives an extension that more than one implementation is
meant to read. WAI does not propose it to the registry. Were the registry to take up a WAI form,
the extension object would keep its members, and the commitment and the renderer would stay WAI's:
they are records and a profile, not part of a decode back to the base attributes.
## 4. The attributes
### 4.1 The layout
This revision renders splat sets of 14 planes (`attr` = 14), the layout `wai.splat.int_codec`
codes (SPEC §5): Gaussian `k`, for `k` < `n_gaussians`, is cell `k` of every plane, in raster
order, and its planes are:
| planes | attribute |
|---|---|
| 0–2 | position *x*, *y*, *z* |
| 3–5 | scale: the standard deviation along the Gaussian's own *x*, *y*, *z* axes |
| 6–9 | rotation, a quaternion *w*, *x*, *y*, *z* (of any length) |
| 10–12 | colour *r*, *g*, *b*, display-referred, the base extension's `srgb_rec709_display` |
| 13 | opacity |
A splat set of another plane count is `layout_mismatch` at the renderer (§5.2).
### 4.2 Dequantization
Each plane `p` has the range `(lo_p, hi_p)` the payload states as two binary32 values. Each is
taken at 2^16, rounded half up and computed exactly from the binary32 value:
`LO_p = ⌊lo_p · 2^16 + 1/2⌋`, `HI_p = ⌊hi_p · 2^16 + 1/2⌋`. A byte `u` of plane `p` is then
```
q = LO_p + ⌊((HI_p − LO_p) · u + 127) / 255⌋
```
the value at 2^16 (the nearest to `lo + (hi − lo)·u/255`, a tie upward). The payload makes
`lo_p ≤ hi_p`, so `HI_p − LO_p ≥ 0`.
### 4.3 The base extension's attributes
A sink that fills the accessors (§3.1) writes, for Gaussian `k`, each value rounded to the nearest
binary32: `POSITION` = (*x*, *y*, *z*); `KHR_gaussian_splatting:ROTATION` = (*x*, *y*, *z*, *w*) of
the quaternion divided by its length, or (0, 0, 0, 1) where it is zero; `KHR_gaussian_splatting:SCALE`
= the three scales; `KHR_gaussian_splatting:OPACITY` = the opacity clamped to [0, 1]; and
`KHR_gaussian_splatting:SH_DEGREE_0_COEF_0` = (*c* − 1/2) / *C*₀ per channel, with *c* the colour
clamped to [0, 1] and *C*₀ = 1/(2√π), the base extension's degree-0 term; each value being *q* /
2^16. These float attributes are presentation for a renderer of its own: the attribute digest and
the renderer of §5 read the bytes and §4.2's integers, never them.
## 5. The renderer `wai-splat-render:i1`
The renderer maps a splat set's attribute planes and a pose to a frame: `width × height` pixels of
`RGB8`, rows top to bottom, pixels left to right, three bytes a pixel, no padding — the canonical
buffer of [reconstruction-binding](reconstruction-binding.md) §2. Every value is an integer and no
formula wraps or saturates unless it says so.
### 5.1 Integer functions
`⌊a / b⌋`, `R_half_up(p, s)`, `isqrt`, `isqrt_ceil`, `clamp` and `exp_neg_q16` are
[integer-operators](integer-operators.md) §2's. In addition, for `b > 0`:
```
rdiv(a, b) = ⌊(2a + b) / 2b⌋ a / b to the nearest integer, a tie toward +∞
```
`a >> s` is `⌊a / 2^s⌋`; `×` and `·` are exact products.
### 5.2 A renderable splat set
A splat set is renderable when it has 14 planes (`layout_mismatch` otherwise) and, for every plane,
`|LO_p|` and `|HI_p|` are at most 2^28, and `LO_p ≥ 0` for the scale planes 3–5
(`range_unrenderable` otherwise). Each Gaussian `k` then has, at 2^16: its position **P**, its
scale (*s*ₓ, *s*ᵧ, *s*_z) ≥ 0, its quaternion (*w*, *x*, *y*, *z*), its colour and its opacity
(§4.2).
### 5.3 The camera
From the pose's `eye` **E**, `target` and `up` **U**:
```
F = target − E n_f = isqrt(F·F); n_f = 0 is pose_degenerate
f = rdiv(F_i · 2^14, n_f) the forward row at 2^14
R = F × U n_r = isqrt(R·R); n_r = 0 is pose_degenerate
r = rdiv(R_i · 2^14, n_r) the right row at 2^14
u = R_half_up((r × f)_i, 14) the up row at 2^14
```
`·` and `×` are the dot and cross products of the integer vectors. With `F` along −*z* and `U`
along +*y*, `r` is +*x* and `u` is +*y*: the frame's columns go right and its rows go down.
### 5.4 Projecting a Gaussian
With `W`, `H` and `f_l` the pose's width, height and focal length, for Gaussian `k`:
```
D = P − E
x_c = R_half_up(r·D, 14) y_c = R_half_up(u·D, 14) z_c = R_half_up(f·D, 14) at 2^16
key = D·D at 2^32
m_x = 128·W + rdiv(256·f_l·x_c, z_c) m_y = 128·H − rdiv(256·f_l·y_c, z_c) at 2^8 pixels
```
The pixel in column *i* and row *j* has its centre at (256·*i* + 128, 256·*j* + 128) at 2^8.
The screen covariance follows the elliptical weighted average splatting model, with the camera
coordinates held within 1.3 times the frame's half-extent as the Jacobian is formed:
```
L_x = rdiv(13·W·z_c, 20·f_l) x_l = clamp(x_c, −L_x, L_x)
L_y = rdiv(13·H·z_c, 20·f_l) y_l = clamp(y_c, −L_y, L_y)
j00 = rdiv(f_l · 2^32, z_c) j02 = rdiv((−f_l · x_l) · 2^32, z_c²)
j11 = −j00 j12 = rdiv((f_l · y_l) · 2^32, z_c²)
T0_c = R_half_up(j00·r_c + j02·f_c, 14) T1_c = R_half_up(j11·u_c + j12·f_c, 14) c = 0, 1, 2
```
The rotation, at 2^16, from the quaternion with `n = w² + x² + y² + z²`: the identity
(2^16 on the diagonal) where `n = 0`; otherwise, each entry `rdiv(e · 2^16, n)` of
```
| w²+x²−y²−z² 2(xy − wz) 2(xz + wy) |
| 2(xy + wz) w²−x²+y²−z² 2(yz − wx) |
| 2(xz − wy) 2(yz + wx) w²−x²−y²+z² |
```
Then `M_ab = R_half_up(Rot_ab · s_b, 16)`, `S_ab = Σ_c M_ac · M_bc` (at 2^32), and
```
V_ab = Σ_c Σ_d T_a,c · S_cd · T_b,d a, b ∈ {0, 1}
A = R_half_up(V_00, 48) + 19661 B = R_half_up(V_01, 48) C = R_half_up(V_11, 48) + 19661
```
the screen covariance at 2^16 pixels², with 19661 (0.3 at 2^16) added to each variance as the low
pass every splat renderer of this model adds.
### 5.5 Culling, the rectangle and the order
A Gaussian is **culled**, and adds to no pixel, when any of these holds, in this order:
1. `z_c < 13107` (0.2 at 2^16: behind the camera or inside its near plane);
2. `A ≤ 0` or `C ≤ 0`;
3. with `r_x = ⌈isqrt_ceil(9·A) / 256⌉` and `r_y = ⌈isqrt_ceil(9·C) / 256⌉` (three standard
deviations, in whole pixels), `r_x > 1023` or `r_y > 1023`;
4. its **rectangle** is empty: columns `x0 = max(0, ⌈(m_x − 256·r_x − 128) / 256⌉)` to
`x1 = min(W − 1, ⌊(m_x + 256·r_x − 128) / 256⌋)`, rows `y0`, `y1` the same with `m_y`, `r_y`
and `H`; empty when `x0 > x1` or `y0 > y1`;
5. `Δ = A·C − B² ≤ 0`;
6. with the **whitening coefficients** at 2^16
```
k1 = rdiv(2^40, isqrt(A · 2^32))
σ = isqrt(A · Δ · 2^16)
k2 = rdiv(A · 2^32, σ) k3 = rdiv(−B · 2^32, σ)
```
one of `|k1|`, `|k2|`, `|k3|` exceeds 2^31 − 1.
For each Gaussian kept, compositing reads its `m_x`, `m_y`, its rectangle, `k1`, `k2`, `k3`, its
opacity `o = clamp(opacity, 0, 2^16)` and its colour `c_ch = clamp(colour_ch, 0, 2^16)`.
The kept Gaussians are put in **order**: by `key`, the squared distance from the eye, nearest
first; a tie of `key` by the Gaussian's index `k`, lower first. This is the base extension's
`cameraDistance` order, made total.
### 5.6 Compositing a pixel
Each pixel starts with transmittance `T = 2^16` and accumulators `acc_r = acc_g = acc_b = 0`, and
takes the kept Gaussians in order. It skips a Gaussian whose rectangle does not hold it. For one
that does, at pixel (*i*, *j*):
```
dx = 256·i + 128 − m_x dy = 256·j + 128 − m_y at 2^8
e1 = k1·dx e2 = k3·dx + k2·dy at 2^24
```
- If `|e1| > 3·2^24` or `|e2| > 3·2^24`, the Gaussian adds nothing here.
- `a1 = R_half_up(e1, 12)`, `a2 = R_half_up(e2, 12)`, `d2 = R_half_up(a1² + a2², 8)`: the squared
distance in standard deviations, at 2^16. If `d2 > 9·2^16`, it adds nothing (the base
extension's 3σ cut-off).
- `w = exp_neg_q16(−⌊d2 / 2⌋)` and `α = min(64880, ⌊o · w / 2^16⌋)` (64880 is 0.99 at 2^16). If
`α < 257` (1/255 at 2^16), it adds nothing.
- `c = R_half_up(α · T, 16)` and `T' = T − c`. If `T' < 7` (0.0001 at 2^16), the pixel is
**done**: this Gaussian adds nothing and no later one is taken.
- Otherwise each `acc_ch += R_half_up(c_ch · c, 16)`, and `T = T'`.
The pixel's bytes are `min(255, R_half_up(acc_ch · 255, 16))`. The background is black.
Taking Gaussians nearest first and keeping the transmittance is the same blend as the base
extension's back-to-front alpha blending, in exact arithmetic; here every rounding is stated, the
transmittance falls by exactly what each Gaussian adds, and a pixel can stop once it is opaque.
### 5.7 Tiles
The frame is cut into tiles of 16 × 16 pixels, in raster order, the last column and row of tiles
cut short by the frame's edge. A tile's **list** is the kept Gaussians whose rectangle meets the
tile, in order. A pixel composes its tile's list (§5.6). A Gaussian whose rectangle holds a pixel
is in that pixel's tile's list, so the frame is the one §5.6 gives over the whole order, whatever
order the tiles are computed in and however the work is divided among them: tiles and pixels are
independent, and only the order within one pixel's list matters.
### 5.8 The frame's digest
A frame's **digest** is the SHA-256 (FIPS 180-4) of its bytes.
### 5.9 Widths
Within the caps of §2 and §5.2, every value §5.3–§5.5 forms fits in 127 bits plus a sign, and
§5.5's rule 3 bounds `A` and `C` before `Δ` and `σ` are formed. Every value compositing reads
fits in 32 bits, and §5.6 forms every value in 32 bits except the three products and the sum that
make `e1` and `e2`, which fit in 64: `|k| ≤ 2^31 − 1` and `|dx|`, `|dy| ≤ 256·1024 + 256`, and
each `e` is narrowed only after it is checked against `3·2^24`. `α · T` and `c_ch · c` are below
2^32 because `α ≤ 64880` and `T ≤ 2^16`.
The renderer is not a graph of [integer-operators](integer-operators.md): its order and its
rectangles are not graph operators. It uses that extension's integer functions (§2 there), so
`exp_neg_q16` is the one the operator set's `softmax`, `sigmoid` and `elu` use.
## 6. Canonical poses and the commitment
### 6.1 The commitment
The origin of a splat set signs a commitment, `kind` `"wai-splat-commitment"`:
| member | type | meaning |
|---|---|---|
| `kind` | string | `"wai-splat-commitment"` |
| `object` | 32 B hex | the content hash of the object the asset carries (§3.2) |
| `set` | 32 B hex | the SHA-256 of its parameter set |
| `attributes` | 32 B hex | its attribute digest (§3.3) |
| `renderer` | term | the renderer: `wai-splat-render:i1` in this revision |
| `class` | string | the splat set's class under [synthesis](synthesis.md) §3.2: `captured`, `reconstructed`, `assistive` or `synthesized` |
| `origin` | 32 B hex or `null` | the link hash of the splat set's origin claim (synthesis §3.1), where it has one |
| `views` | array | 1 to 64 entries, each `{"pose", "frame"}`: a **canonical pose** (§2) and the digest of the frame §5 gives at it; no pose twice |
| `issued_at`, `signer_pubkey`, `sig` | | §2 |
A commitment that breaks a rule of this table is `record_malformed`.
### 6.2 What it binds
A commitment names one object by content hash, so its decoded attributes, by digest, and through
them every frame of every pose: the canonical poses are the ones whose frames the origin states.
A viewer that recomputes a canonical frame and finds its digest knows its own decode and renderer
reproduce what the origin saw from there, bit for bit; a viewer at any other pose renders a frame
that every other conforming viewer at that pose renders too. The origin chooses the poses: views
it wants recognised (a product shot, a catalogue's angles, the poses a scene was captured from).
## 7. The view statement
A sink signs a view statement, `kind` `"wai-splat-view"`, for a frame it presented, under a key
of its viewing session (no identity of the viewer or the device):
| member | type | meaning |
|---|---|---|
| `kind` | string | `"wai-splat-view"` |
| `session` | 32 B hex | fresh random bytes of the session |
| `commitment` | 32 B hex | the link hash of the asset's commitment |
| `object` | 32 B hex | the content hash of the object it rendered |
| `pose` | object | the pose (§2) |
| `canonical` | integer or `null` | the index in the commitment's `views` of this pose, where the sink presents it as canonical; `null` otherwise |
| `frame` | 32 B hex | the digest of the frame it presented |
| `renderer` | term | the renderer: `wai-splat-render:i1` |
| `class` | string | the frame's class (§8) |
| `at` | integer | when it was presented, in microseconds of the session's clock |
| `issued_at`, `signer_pubkey`, `sig` | | §2 |
A statement that breaks a rule of this table is `record_malformed`. A statement whose `canonical`
is an index states that its pose is that canonical pose, and its frame the one the commitment
binds there; with `null` it states only that its frame is §5's at its pose, which anyone holding
the asset recomputes.
## 8. Provenance
A rendered view is a **conversion** of the splat set under [synthesis](synthesis.md) §3.2: it
rearranges and composes what the splat set holds, generates nothing and enhances nothing, and
the renderer names no model. Its class is therefore the greatest of `reconstructed` and the splat
set's class: the view of a captured or reconstructed scene is `reconstructed`, of an assistive one
`assistive`, of a synthesized one `synthesized`. A view statement's `class` is that class
(`class_mismatch` otherwise).
A splat set's own origin claim (synthesis §3.1) names `media` `volumetric`, and its subject is the
object the asset carries, by content hash. A sink that publishes a rendered view as an object
signs its origin claim as synthesis §3.4 has a conversion's: `step` `convert`, `media` `image`,
`operation` `wai-splat-render:i1`, `record` the link hash of its view statement, and one input,
the splat set's object with its claim's link hash, class and source.
A view statement is a presentation statement for one frame: what a sink presented, from which
pose, of which committed object, with what class. Its frame is recomputable from the asset, so a
verifier holding the asset proves it and does not take it on trust.
## 9. Verification
### 9.1 Inputs
A verifier is given an asset (its JSON and the bytes of the buffers it names), the parameter sets
it holds, the splat set's origin claim where it holds one, and view statements.
### 9.2 Steps
In this order, a case stopping at its first refusal; the place of each refusal is named after it:
1. The asset (§3.1, §3.2): `asset_malformed`, `capability_mismatch` — *asset*.
2. The envelope, its set and the decode (§3.3): `asset_malformed`, `capability_mismatch`,
`object_mismatch`, `set_mismatch`, `set_not_held`, `decode_refused` — *asset*.
3. The accessors (§3.4): `asset_malformed` — *asset*. An asset with no commitment is accepted
here.
4. The commitment (§6.1), read and its signature verified; its `object` is the extension's
(`object_mismatch`), its `set` the extension's `set.sha256` (`set_mismatch`), its `attributes`
the attribute digest (`attributes_mismatch`), its `renderer` `wai-splat-render:i1`
(`renderer_unknown`); the splat set is renderable (§5.2: `layout_mismatch`,
`range_unrenderable`) — *commitment*.
5. Each view in order: the frame at its pose (`pose_degenerate`), whose digest is its `frame`
(`frame_mismatch`) — *view n*, from 0.
6. Where the commitment's `origin` is not `null` and the verifier holds the claim: the claim reads
and verifies as synthesis §2 has it, its link hash is `origin`, its subject is the object, its
class is the commitment's `class` and the greatest of its step's class and its inputs' classes
(synthesis §3.2); otherwise `origin_mismatch` — *origin*.
7. Each view statement in order, read and its signature verified; its `commitment` is the
commitment's link hash (`commitment_mismatch`), its `object` the object (`object_mismatch`), its
`renderer` `wai-splat-render:i1` (`renderer_unknown`); with an index in `canonical`, that index
names a view whose pose is the statement's (`pose_not_canonical`) and whose frame is the
statement's (`frame_mismatch`); with `null`, the frame at its pose (`pose_degenerate`) has the
statement's digest (`frame_mismatch`); its `class` is the view class of §8 (`class_mismatch`) —
*statement n*, from 0.
### 9.3 What an accepted case states
The object's content hash, the attribute digest and the Gaussian count; the digest of each
canonical frame, in the commitment's order; and, for each statement, its `canonical` and its
`class`.
## 10. Reasons
| code | meaning |
|---|---|
| `record_malformed` | a record or a pose breaks a rule of its table (§2, §6.1, §7) |
| `bad_key` | a record's key fails step 1 or 2 of SPEC §7's strict verification |
| `bad_signature` | a record's signature does not verify |
| `asset_malformed` | the asset breaks a rule of §3.1, §3.2 or §3.4, or its buffer view does not hold one envelope |
| `capability_mismatch` | the extension or the envelope names a capability other than `wai.splat.int_codec` |
| `object_mismatch` | a content hash the extension, the commitment or a statement states is not the envelope's |
| `set_mismatch` | the pin, the extension and the set disagree, or the pin does not verify |
| `set_not_held` | the set is named by digest only, and the verifier holds no file of that digest |
| `decode_refused` | the payload's decode refuses it |
| `attributes_mismatch` | the commitment's attribute digest is not the decode's: a commitment over other splats |
| `renderer_unknown` | a record names a renderer this revision does not pin |
| `layout_mismatch` | the splat set does not have the 14 planes of §4.1 |
| `range_unrenderable` | a range endpoint is past 2^28 at 2^16, or a scale range goes below zero |
| `pose_degenerate` | a pose whose eye is its target, or whose up direction is along its line of sight |
| `frame_mismatch` | a frame's digest is not the digest of the frame §5 gives at its pose |
| `origin_mismatch` | the origin claim the commitment names does not match it, or is not that claim |
| `commitment_mismatch` | a statement names another commitment than the asset's |
| `pose_not_canonical` | a statement claims a pose canonical that is not the commitment's pose at that index |
| `class_mismatch` | a statement's class is not the class of a view of the splat set (§8) |
## 11. Conformance
The corpus [`live-conformance/splat/`](../live-conformance/splat/) holds glTF assets, their buffers
and commitments, origin claims and view statements, each case with the outcome a verifier
reaches. Its scenes: the learned cloud of `wai-rs/tests/vectors/int_splat/` (its payload and its
`WHM1` synthesis, held by digest), and two scenes authored as attribute bytes and carried through
the **identity set**, a one-layer `WHM1` network that decodes each latent value `v` at 2^8 to the
byte `(255·v + 128) >> 8`, so any planes can be coded. The identity set is a conformance device: it
codes each plane at the entropy of its bytes and learns nothing.
A verifier conforms when it reaches every case's stated outcome, place and statements. The
corpus refuses a case with every code of §10, and holds these negative controls among them: a
reordered sort (frames committed with a tie of distance broken by the greater index), a frame that
does not recompute (rendered without §5.4's low pass), a commitment over the wrong splats (another
scene's attribute digest), and a pose outside the pinned set claimed canonical.
Two implementations reach the same outcomes, sharing no code: the `splat_exact` module of `wai-rs`,
which also writes the corpus (`wai_splat_exact_vectors gen`, and `verify` to regenerate it byte for
byte), and `live-conformance/splat_exact_verify.py`, standard library only, written from this
text with its own integer renderer. The second also drops each of its own checks in turn and
changes each of its renderer's rules in turn (the tie order, sorting by depth instead of distance,
the low pass, the rounding of `rdiv` and of a contribution, `exp_neg_q16`, the stop, the alpha
ceiling, the cut-off, the rectangle's rounding, the near plane), and requires the corpus to catch
every one.
**On a GPU.** Compositing reads 32-bit words and forms 32-bit values but for `e1` and `e2`
(§5.9), so it runs as a compute kernel in which every pixel is an invocation and every tile a
workgroup, with `e1` and `e2` formed by the 64-bit products of the integer operator set's GPU
executor (the `wai-ops-gpu` crate), whose arithmetic every device passes a probe on before it runs
anything. The host projects, culls and orders (§5.3–§5.5). `splat_exact::gpu` in `wai-rs` (with the
features `splat_exact` and `ops_gpu`) composes that way, and its test holds every canonical and
own-pose view of every scene of the corpus to the CPU's frame, byte for byte, on every adapter it
finds, and requires the corpus's views to catch each of three edited kernels (a contribution
rounded down, no alpha ceiling, the cut-off moved). Measured on 22 October 2026 with Metal, on the
integrated GPU of an arm64 desktop (macOS 27.0.1): every view equal, every edited kernel caught.
The `macos` job of `wai-ops-gpu.yml` runs it, and an absent adapter fails there.
## 12. The quality cost
`wai_splat_exact_measure` renders each scene of the corpus at its canonical poses and at the pose
of its own-pose view, with `wai-splat-render:i1` and with a floating-point renderer of the same
model (the same camera, low pass, cut-off, alpha limits, stop and order, the platform's `exp` and
`sqrt`) in `f64` and in `f32`. Measured on one machine (the corpus's frames, and the same poses at
four times the side and focal length):
| scene | frames | PSNR of the integer frame against `f64` | largest byte difference | bytes in which `f32` and `f64` differ |
|---|---|---|---|---|
| learned cloud | 96 × 96, 80 × 64 | 62.3–64.5 dB | 2 | 0–2 per frame |
| learned cloud | 384 × 384, 320 × 256 | 62.3–64.8 dB | 4 | 7–24 per frame |
| authored cluster | 80 × 60 | 59.4–61.5 dB | 2 | 0–2 per frame |
| authored cluster | 320 × 240 | 59.4–61.7 dB | 3 | 3–17 per frame |
| authored three Gaussians | 40 × 30 | 63.2–67.2 dB | 1 | 0 |
| authored three Gaussians | 160 × 120 | 64.5–67.0 dB | 3 | 0–1 per frame |
So the cost of the integer arithmetic, against the same model in `f64`, is a byte that differs by
at most 4 levels, at about 60 dB and above; it includes §4.2's fixed-point dequantization, which a
float renderer does in float. A float renderer is not one renderer: in `f32` it gives other bytes
than in `f64` in some of the corpus's frames and in nearly all of them at four times the side, and so do two devices that order or fuse its operations differently,
so no digest of a float frame is stable. These figures are this corpus's scenes; a scene of many
more Gaussians composes more terms per pixel and adds more rounding.
## 13. Security and privacy considerations
A commitment says what the origin's splat set looks like from each canonical pose, under this
renderer; it says nothing about the scene in the world it was made from. Its class and origin
claim say where the splat set came from (§8).
A view statement reveals a pose and a time: where a viewer looked, and when. It is signed under a
session key and names no viewer or device. A sink **SHOULD** use a fresh session key and fresh
`session` bytes for each viewing session, and **SHOULD NOT** sign statements for poses a viewer
did not choose to share.
The decode's caps are integer-payloads §7's; the renderer's work is bounded by the frame's size
(at most 2^20 pixels) times the Gaussians whose rectangles hold a pixel, and §5.5 culls a
Gaussian whose rectangle is wider than 2047 pixels before its pixels are visited. A verifier
**MAY** refuse to render a commitment whose frames, added up, exceed its own budget, and says so;
the corpus's are small.

View file

@ -21,7 +21,9 @@
> by a pinned integer derivation, so a verifier that holds the unmarked frames recomputes the
> marked ones and knows the mark carries its payload and nothing else; anyone reads it with no
> key, through a code whose false-positive bound is derived and checked; and an attack battery
> measures what it survives, which is all it claims. A **signpost** in the content and in the
> measures what it survives, which is all it claims. A second registered watermark,
> `wai-mark:tent64s`, lays the same mark out in tiles, so its detector finds the grid again after
> a crop, a small rotation or a capture of a screen. A **signpost** in the content and in the
> metadata names the detection solution, and a well-known path resolves it. An **AI participant**
> of a room is marked in its grant, and its messages, captions and tracks carry its machine
> origin. A **review** is a signed verdict over one exact reconstruction, which a player presents
@ -30,7 +32,7 @@
> signed **log** shows whether it was. No new transport. The reference implementation is the
> `synthesis` module of `wai-rs` (feature `synthesis`); the corpus is
> [`live-conformance/synthesis/`](../live-conformance/synthesis/), and its second
> implementation is `live-conformance/synthesis_verify.py`. The scheme's battery and measurement
> implementation is `live-conformance/synthesis_verify.py`. The schemes' battery and measurement
> are the `synthesis_mark` module (feature `synthesis_mark`); its corpus is
> [`live-conformance/synthesis-mark/`](../live-conformance/synthesis-mark/), and its second
> implementation `live-conformance/synthesis_mark_verify.py`.
@ -55,15 +57,16 @@
In scope: the records and their encodings (§2); the classes, the steps and the origin claim
(§3); the two pinned integer derivations and the evidence that makes an assistive claim
checkable (§4); the digital source type (§5) and the C2PA statement (§6) a claim gives; the
two marking layers, their records and their agreement, the registered watermark scheme, what it
survives, its signpost and its resolver (§7); AI participants of rooms (§8); the
two marking layers, their records and their agreement, the registered watermark schemes, what
they survive, the signpost and the resolver (§7); AI participants of rooms (§8); the
review and when a player presents it (§9); when a label is shown, the EU icons pinned by digest,
and a player's log (§10); verification (§11).
Out of scope: a transport; how a generator, a codec or an editor works; a watermark for audio or
for text, which this revision does not register (audio was in this revision's sight and is not
reached; text needs a scheme of its own); finding a mark again after a crop or a rotation, which
the registered scheme does not do (§7.5.8); how a manifest is assembled, embedded and signed,
reached; text needs a scheme of its own); resistance to an adversary who sets out to remove or
forge a mark, which neither registered scheme claims (§14); how a manifest is assembled,
embedded and signed,
which is C2PA's and
[provenance](provenance.md)'s; key discovery for the signers of these records, which a verifier
takes from [jwp-receipts](jwp-receipts.md) §7 as it does for any other key; and the rendering of a
@ -124,7 +127,13 @@ link_hash = BLAKE3("wai:synthesis-link\x01" || JCS(record))
JCS is RFC 8785, which on these values reduces to what jwp-receipts §2.4.3 states. 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
`bad_key`, and a signature that fails a later step `bad_signature`. A record **MAY** also carry
a post-quantum signature: the hybrid members `pq_suite`, `pq_key` and `pq_sig` beside `sig`,
which [pq-signatures](pq-signatures.md) §3.4's shared check reads and verifies, with its own
codes (pq-signatures §8), `sig` then being over the composite's representative of
`"wai:synthesis\x01" ‖ JCS(record without "sig" and "pq_sig")`; the member tables of this
extension apply to the record without them. A verifier that does not implement pq-signatures
refuses them as members its tables do not list (`record_malformed`). A record is named by its
link hash wherever another names it. A record whose members carry `issued_at` holds a date-time
there, the instant its signer signed it: the time stamp the Code of Practice's Sub-measure 1.1.1
asks for, self-asserted.
@ -145,7 +154,7 @@ An origin claim, `kind` `"wai-origin"`, has these members:
|---|---|---|
| `kind` | string | `"wai-origin"` |
| `subject` | object | what it is about: `{"type": "object", "content_hash"}`, an object by its content hash; `{"type": "group", "receipt"}`, a group by its group receipt's link hash (jwp-receipts §3 step 3); `{"type": "track", "track", "from_group"}`, a track by its digest (live-rooms §6.2: SHA-256 over the rendering of its namespace, one zero byte and its name) from the group `from_group` on; or `{"type": "samples", "samples"}`, a picture a party presents or holds and does not publish as an object, by the digest of its samples (§2): a sink's upscale or generated frame ([exact-upscale](exact-upscale.md) §6.1) |
| `media` | string | `audio`, `video`, `image` or `text` |
| `media` | string | `audio`, `video`, `image`, `text` or `volumetric` (a splat set, a mesh or a point cloud; [splat-exact](splat-exact.md) §8) |
| `class` | string | `captured`, `reconstructed`, `assistive` or `synthesized` (§3.2) |
| `step` | string | `capture`, `convert`, `assist` or `generate` (§3.2) |
| `operation` | term | what ran: a capability or derivation string, or a term naming the type of operation (`upscale`, `inpainting`, `speech-synthesis`) |
@ -437,8 +446,9 @@ first marking whose subject it is (if it holds one):
### 7.4 Schemes
A scheme is named by a term `wai-mark:<name>` and the SHA-256 of its definition. This revision
registers `wai-mark:tent64` (§7.5). Its definition is the JCS text (RFC 8785) of this object,
whose bytes are the corpus's `scheme.json` (§13):
registers `wai-mark:tent64` (§7.5) and `wai-mark:tent64s` (§7.9). The definition of
`wai-mark:tent64` is the JCS text (RFC 8785) of this object, whose bytes are the corpus's
`scheme.json` (§13):
```
{"amplitude":12,"cells_per_bit":16,"class_max":3,"code":[255,71,29],"field":"11d",
@ -452,10 +462,10 @@ whose bytes are the corpus's `scheme.json` (§13):
(broken here into lines after commas between members; the definition itself has no line break,
and no space but those inside its strings), and its digest is
`4e1bd9f2cac9420fc276434751a3fb9b2b0916128f200bf147009a86168be7d6`. The definition pins the
scheme's parameters, and §7.5 is its algorithm. A marking or a detection that names
`wai-mark:tent64` under another digest is `scheme_mismatch`. A marking of the scheme states its
`embedding`, and a detection its `read`, of frames the scheme admits (§7.5.1): otherwise
`mark_evidence_invalid`.
scheme's parameters, and §7.5 is its algorithm; §7.9.1 gives `wai-mark:tent64s`'s. A marking or a
detection that names a registered term under another digest is `scheme_mismatch`. A marking of a
registered scheme states its `embedding`, and a detection its `read`, of frames the scheme admits
(§7.5.1): otherwise `mark_evidence_invalid`.
`wai-mark:conformance` stays as a scheme with no algorithm: its definition is the text
`wai-mark:conformance names no watermark algorithm (synthesis.md section 7.4)`, and a record of
@ -766,10 +776,10 @@ A verifier is given, beside the records, the decoded frames of the objects it ho
order:
1. its scheme (§7.4): `scheme_mismatch`, `mark_evidence_invalid`;
2. for `wai-mark:tent64`, with the unmarked frames of its object held: they are
2. for a registered scheme, with the unmarked frames of its object held: they are
`frames`·`width`·`height`·3 bytes and their SHA-256 is the embedding's `unmarked`
(`mark_input_mismatch`), and the scheme's embedding of them (§7.5.4) under the marking's
payload has the SHA-256 `marked` (`mark_recompute_mismatch`). The marking is then **proved**;
(`mark_input_mismatch`), and the scheme's embedding of them (§7.5.4, §7.9.3) under the
marking's payload has the SHA-256 `marked` (`mark_recompute_mismatch`). The marking is then **proved**;
otherwise it is **stated**;
3. with an embedding and the object's decoded frames held: their SHA-256 is the embedding's
`marked` (`samples_mismatch`);
@ -784,14 +794,14 @@ the marking step.
For each detection, at §7.3 step 2, in this order: its scheme (§7.4); with a `read` and the
object's decoded frames held, they are `frames`·`width`·`height`·3 bytes and their SHA-256 is
`samples` (`samples_mismatch`); and for `wai-mark:tent64`, the detector (§7.5.5) is run on them,
`samples` (`samples_mismatch`); and for a registered scheme, its detector (§7.5.5, §7.9.4) is run on them,
and the payload it reads, or its finding no mark, is the detection's `payload`
(`detection_irreproducible`). The detection is then **reproduced** (`reproduced`), and otherwise
**not run again** (`not-rerun`). Under a policy that requires the second layer proved, a detection
that is not reproduced is `layer_not_proved`.
So a detection that reports a mark in content that carries none, or in content altered beyond
what the scheme survives (§7.5.8), is refused wherever the verifier holds the content's frames: a
what the scheme survives (§7.5.8, §7.9.7), is refused wherever the verifier holds the content's frames: a
detection agrees with a claim only for a payload the content carries.
### 7.7 The signpost and the resolver
@ -804,9 +814,9 @@ technique within the content, and its detection mechanism, that indicates which
detection mechanism to employ where metadata is not available, and says it may be an imperceptible
machine-readable mark. This extension gives three:
1. **In the content.** `wai-mark:tent64` is itself openly disclosed and read with no key (§7.5.5).
Run on any content, its detector says whether the content carries a WAI mark, with the
false-positive bound of §7.5.6, and the payload it reads gives the class and the claim. The
1. **In the content.** Each registered scheme is itself openly disclosed and read with no key
(§7.5.5, §7.9.4). Run on any content, its detector says whether the content carries a WAI
mark, with the false-positive bound of §7.5.6 or §7.9.5, and the payload it reads gives the class and the claim. The
claim's markings name every scheme marked into its object, each by term and digest, so the mark
is the signpost to the object's other marks as well.
2. **In the metadata.** Each marking gives a C2PA statement (C2PA 2.4 §18.15.5, §18.10),
@ -825,15 +835,15 @@ machine-readable mark. This extension gives three:
with a JSON array of the texts of the origin claims it holds whose payload (§7.2) is `<p>`, empty
where it holds none. The definition names the section that specifies the detector, a public
specification any third party implements (the Code's Sub-measure 2.1.1 (i)), of which
`wai-rs` (`synthesis::mark`) and `live-conformance/_wai_mark.py` are two implementations
(§13). A client checks the
`wai-rs` (`synthesis::mark` and `synthesis::mark::sync`) and `live-conformance/_wai_mark.py`
are two implementations (§13). A client checks the
definition's digest against the term's before relying on it, and each claim it receives against
the payload it asked for and against the claim's signature. This revision does not register the
well-known name.
### 7.8 A sink that generates
Where an object's envelope generates (§3.3) and a marking of `wai-mark:tent64` names it, the
Where an object's envelope generates (§3.3) and a marking of a registered scheme names it, the
reconstruction a sink is held to is the scheme's embedding, under the marking's payload, of the
frames its generation produces: the sink generates, then marks, as one integer derivation appended
to the generative one, so the exact tier the generation holds (generation-equivalence,
@ -844,6 +854,268 @@ player that presents the unmarked frames states an output the object does not de
(`present_output_irreproducible`, §9.2). A verifier that holds the envelope generates the unmarked
frames itself, and so proves the marking (§7.6) without taking anyone's unmarked frames on trust.
### 7.9 The scheme `wai-mark:tent64s`
The mark of `wai-mark:tent64` laid out in tiles. Its embedding is §7.5.4's, under a layout in which
every quarter of the frame holds the same pattern, so a detector that does not find the grid in
place finds it again from the pattern's own period: after a crop, a small rotation, a rescale or
a capture of a screen. Nothing is added for this: the marked frames are as far from the unmarked
ones as `tent64`'s (§7.9.7), and integer throughout, a pure function of the unmarked frames and
the payload. The detector is integer throughout too, so what it reads is a pure function of the
frames, the same in every implementation.
It is a second term and not a revision of `wai-mark:tent64`: the same unmarked frames and payload
give other marked frames, a marking of `tent64` commits to `tent64`'s by digest (§7.2), and §7.6
recomputes a marking under the definition its term and digest name. `tent64` stays registered
unchanged.
#### 7.9.1 The definition
The definition is the JCS text of this object, whose bytes are the corpus's `scheme-tent64s.json`
(§13), broken into lines as §7.4's is:
```
{"amplitude":12,"cells_per_bit":16,"cells_per_tile_bit":4,"class_max":3,"code":[255,71,29],
"field":"11d","generator":"140a722a1a468d36d87a25364e685922a1e56fd1a478c1d","grid":64,
"length":248,"luma":[77,150,29,128,8],"margin":[3,2],"max_frame_bytes":268435456,
"media":["image","video"],"min_height":128,"min_width":128,"orientations":8,"pattern":"tent",
"resync":{"bins":[4,8],"candidates":8,"decodes":4,"frames":8,"robust":[25,5,100],
"slope":[3,20],"span":[[7,20],[3,4]],"subsample":64,"working_side":1024},"sample":"RGB8",
"scheme":"wai-mark:tent64s","specification":"extensions/synthesis.md section 7.9",
"stream":"wai-mark:tent64s stream","tiles":[2,2]}
```
and its digest is
`36ab9338f3ecade8adbf73190b1f3510f9bc6851339e3cfad18b0863923c8e8c`.
What the scheme does not state below is §7.5's: the frames and the luma (§7.5.1); the grid, the
tent, a cell's statistic and mass (§7.5.2); the code, the codeword and the decoding (§7.5.3,
§7.5.5); the amplitude, the margin and the embedding of each bit (§7.5.4).
#### 7.9.2 The tiled layout
The grid's 64 × 64 cells form 2 × 2 **tiles** of 32 × 32 cells. Cell (*i*, *j*) is at the
**position** *p* = 32·(*j* mod 32) + (*i* mod 32) of its tile, which has row ⌊*p* / 32⌋ and column
*p* mod 32. The **stream** is §7.5.3's under the label `wai-mark:tent64s stream`, and its words
are taken in this order:
1. the **shuffle** π of the positions: π starts as 0, 1, …, 1023; for *i* from 1023 down to 1, with
*r* the next word, the entries at *i* and at *r* mod (*i* + 1) are swapped;
2. the **signs** ε₀ … ε₁₀₂₃ of the positions: +1 where the next word is even, −1 where it is odd;
3. the **mask** μ₀ … μ₂₄₇: the lowest bit of the next word.
Bit *j* of the code is carried by the positions π(4*j*) … π(4*j* + 3), so by those 4 positions in
each of the 4 tiles, 16 cells; the positions π(992) … π(1023) carry nothing. A cell's sign is its
position's. π begins 410, 485, 761, 10, and the corpus states more of it. Every tile holds the same
signs and the same bits, so the mark repeats with a period of half the frame's width and half its
height: exactly where they are even, to within one sample otherwise.
#### 7.9.3 Embedding
§7.5.4, with this layout: each bit's amplitude is the least from 0 to 12 that meets the margin over
its 16 cells, and every frame of a video carries the whole payload.
#### 7.9.4 Detection
The detector is given frames, *F* of *W* × *H*; frames §7.5.1 does not admit carry no mark. Below,
rnd(*n* / *d*) is *n* / *d* rounded to the nearest integer, halves away from zero (for *d* < 0, as
−*n* / −*d*), ⌊ ⌋ rounds down, *a* mod *b* is in 0 … *b* − 1, and isqrt is the integer square root.
**Stage 1: the grid in place.** §7.5.5 with this layout: in each orientation from 0 to 7, the bits'
statistics summed over the frames are read, unmasked and decoded, and the first orientation that
gives a payload gives the result. Where none does, stage 2.
**Stage 2: the grid found again**, on the first min(*F*, 8) frames:
1. **The working plane** of a frame: its luma, or with *k* = ⌈max(*W*, *H*) / 1024⌉ above 1, the
⌊*W*/*k*⌋ × ⌊*H*/*k*⌋ samples each ⌊(Σ + ⌊*k*²/2⌋) / *k*²⌋ of its *k* × *k* block of luma, Σ
the block's sum. *W*′ × *H*′ is its size.
2. **Robust values**: *r*(*x*, *y*) = 25·*Y*(*x*, *y*) less the sum of *Y* over the 5 × 5 samples
centred there, each coordinate clamped to the plane, then clamped to −100 … 100.
3. **The sign plane**: with *L*ₓ = max(2, ⌊*W*′/64⌋) and *L*ᵧ = max(2, ⌊*H*′/64⌋),
*q*(*x*, *y*) = sgn Σ *f*(*u*, *L*ₓ)·*f*(*v*, *L*ᵧ)·*r*(*x* + *u*, *y* + *v*) over
0 ≤ *u* < *L*ₓ, 0 ≤ *v* < *L*ᵧ, for 0 ≤ *x* ≤ *W*′ − *L*ₓ and 0 ≤ *y* ≤ *H*′ − *L*ᵧ: the tent
pattern's response at the size of a cell, *W*_q × *H*_q of them.
4. **The autocorrelation**: *A*(*dx*, *dy*) = Σ *q*(*x*, *y*)·*q*(*x* + *dx*, *y* + *dy*) over the
frames and over the samples where both are in the plane, and the **overlap**
*o*(*dx*, *dy*) = (*W*_q − |*dx*|)·(*H*_q − |*dy*|); both 0 where |*dx*| ≥ *W*_q or
|*dy*| ≥ *H*_q. They are exact integers, however they are computed.
5. **The candidates.** For *dx* from ⌈7*W*_q/20⌉ to ⌊3*W*_q/4⌋, *dy* from −⌊3*dx*/20⌋ to
⌊3*dx*/20⌋ and *e* from ⌈7*H*_q/20⌉ to ⌊3*H*_q/4⌋, in that order (*e* fastest): the lattice
vectors **b**₁ = (*dx*, *dy*) and **b**₂ = (*g*, *e*), *g* = rnd(−*dy*·*e* / *dx*), at right
angles; its **score** is ⌊65536·Σ*A* / isqrt(Σ*o*)⌋ over the four points **b**₁, **b**₂,
**b**₁ + **b**₂ and **b**₁ − **b**₂ (isqrt(0) read as 1). In score order, highest first and
ties in the listing order, the first 8 candidates each more than 2 from every earlier one in
*dx*, in *dy* or in *e*.
6. **Refined**, each candidate's vectors in units of 1/64 of a sample:
*X*₁ = 64·*dx* + *v*(*A*(*dx* − 1, *dy*), *A*(*dx*, *dy*), *A*(*dx* + 1, *dy*)) and
*Y*₁ = 64·*dy* + *v*(*A*(*dx*, *dy* − 1), *A*(*dx*, *dy*), *A*(*dx*, *dy* + 1)), and *X*₂, *Y*₂
likewise about (*g*, *e*), where *v*(*l*, *c*, *r*) is 0 where *D* = *l* − 2*c* + *r* ≥ 0 and
otherwise rnd(32·(*r* − *l*) / −*D*) clamped to −32 … 32, the vertex of the parabola through
the three. Δ = *X*₁·*Y*₂ − *X*₂·*Y*₁; a candidate with Δ ≤ 0 is dropped.
7. **The fold.** A cell of the folded tile has *m*ₓ = ⌊*X*₁/2048⌋ and *m*ᵧ = ⌊*Y*₂/2048⌋ bins along
its sides, each clamped to 4 … 8; the tile is *n*ₓ = 32*m*ₓ by *n*ᵧ = 32*m*ᵧ. Each sample
(*x*, *y*) of each working plane has *u* = ⌊64·*n*ₓ·(*Y*₂·*x* − *X*₂·*y*) / Δ⌋ and
*v* = ⌊64·*n*ᵧ·(*X*₁·*y* − *Y*₁·*x*) / Δ⌋, its tile's parity
*c* = (⌊*u*/*n*ₓ⌋ mod 2) + 2·(⌊*v*/*n*ᵧ⌋ mod 2), and adds *r*(*x*, *y*) to the bin
(*u* mod *n*ₓ, *v* mod *n*ᵧ) of the fold *F*_c.
8. **The phase.** For *p*ᵧ from 0 to *m*ᵧ − 1 and *p*ₓ from 0 to *m*ₓ − 1: each fold's cell
statistics *S*_c[*b*][*a*] = Σ *f*(*s*, *m*ₓ)·*f*(*t*, *m*ᵧ)·*F*_c[(*b*·*m*ᵧ + *p*ᵧ + *t*) mod
*n*ᵧ][(*a*·*m*ₓ + *p*ₓ + *s*) mod *n*ₓ] over 0 ≤ *s* < *m*ₓ, 0 ≤ *t* < *m*ᵧ (row *b*, column
*a*), their sum *S*, and how well the tiles agree, Σ (*S*² − Σ_c *S*_c²) over the 1024 cells. The
candidate's **tile** is *S* at the first phase with the greatest agreement.
9. **The hypotheses**: for each candidate in order, each orientation *o* from 0 to 7 and each
offset (*x*₀, *y*₀), *y*₀ then *x*₀ from 0 to 31: the tile **seen in orientation** *o*,
*S*_o[*y*][*x*] = ±*S*[*y*₂][*x*₂] with (*x*₂, *y*₂) as §7.5.5 maps a 32 × 32 plane and the sign
− where exactly one of bits 0 and 1 of *o* is set (the tent is odd, so a mirror negates it);
bit *j*'s four values *e*ₖ = ε_p·*S*_o[(⌊*p*/32⌋ + *y*₀) mod 32][(*p* mod 32 + *x*₀) mod 32],
*p* = π(4*j* + *k*); and its **agreement**, the number of pairs *k* < *l* over every bit with
*e*ₖ > 0 and *e*ₗ > 0 both true or both false. The four cells of a bit carry the same bit, so at
the true alignment they agree, and elsewhere they agree by chance.
10. **Decoding.** In agreement order, highest first and ties in the listing order, the first 4
hypotheses each read bit *j* as 1 where Σₖ *e*ₖ > 0, unmask it with μⱼ and decode it within 29
(§7.5.5); the first that gives a payload gives the result, with its orientation and the bits
corrected. Where none does, the frames carry **no mark**.
The search reaches a lattice vector from 7/20 to 3/4 of the plane's side and up to 3/20 of its
length off its axis: a crop that leaves less than about 4/3 of a tile in either direction, a
rotation beyond about 8.5°, and a frame shown inside a larger one are out of its reach.
#### 7.9.5 What it guarantees
- **No other channel**, as §7.5.6: the marked frames are a function of the unmarked frames and
the payload, which a verifier recomputes (§7.6).
- **Imperceptibility.** §7.5.6's floor under this layout, which at every size measured is
`tent64`'s: 36.66 dB at 512 × 512, 38.73 dB at 256 × 256 and 35.76 dB at 768 × 512.
- **False positives.** The detector decodes at most 12 words, 8 in stage 1 and 4 in stage 2. Under
§7.5.6's model each gives a payload with probability at most 2^58·*V*(248, 29) / 2^248, so a clip
or a picture gives one with probability at most 12 times that: 2^−60.80, about 5.0·10^−19. The
model is checked against the words the detector decodes from the 32 unmarked pictures of the
measurement sets, 8 in stage 1 and 4 in stage 2 from each: 384 words have a mean of 124.14 ones
with a standard deviation of 7.78, and the 71,424 pairs of those words from different pictures
differ in a mean of 123.90 bits with a standard deviation of 7.93 and in no fewer than 74; the
model gives 124 and 7.87 for both. The least is further below the mean than the model makes
likely over so many pairs: stage 2's words of pictures with large even regions lean together,
towards the mask, which §7.5.3 keeps more than 29 bits from every codeword. No unmarked picture
of any set, under any attack of the battery, gives a payload.
- **Key-free**, as §7.5.6. Anyone can also make content repeat with the period of the tiles, and
stage 2 then folds along that lattice; it reads a payload only where a codeword is there to read
(the corpus's forged lattice, §13).
#### 7.9.6 The battery's additions
The battery of this scheme is §7.5.7's, with these picture attacks after its own, the attack at
index *i* of the whole list having the seed *i*:
- `crop-25%`, as §7.5.7's crops;
- `crop-left-p%`, `crop-right-p%`, `crop-top-p%` and `crop-bottom-p%` for *p* of 2, 5, 10 and 25:
⌊*W*·*p*/100⌋ columns removed from the left or the right, or ⌊*H*·*p*/100⌋ rows from the top or
the bottom;
- `rotate-5`: §7.5.7's rotation with the cosine and sine at 2^16 of (65287, 5712);
- `screen-a` and `screen-b`, a simulated capture of a screen: area resampling to
⌊*W*·*n*/*d*⌋ × ⌊*H*·*n*/*d*⌋, *n*/*d* 5/4 and 4/5; the rotation of `rotate-1` and, for
`screen-b`, of `rotate-2` clockwise, its sine negated; each sample *v* then
rnd(*v*·(*v* + 255) / 510), a display's curve; then `noise-4` at the attack's seed.
The corpus also derives frames by a crop from one side of any percent below 100, and by
**periodic**: each frame tiled by its own top-left ⌊*W*/2⌋ × ⌊*H*/2⌋, so that its content repeats
with the period of the tiles.
#### 7.9.7 What it survives
On the measurement sets of §7.5.8 and the same photographs, each cell as there:
| attack | `spectral` | `leaves` | photographs |
|---|---|---|---|
| `none` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (2) |
| `int-motion-q4` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (3) |
| `int-motion-q8` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (2) |
| `int-motion-q16` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (2) |
| `int-motion-q32` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (4) |
| `int-motion-q48` | 16 / 16 (2) | 16 / 16 (5) | 24 / 24 (6) |
| `staged-base-q8` | 16 / 16 (0) | 16 / 16 (10) | 24 / 24 (16) |
| `denoise3` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (5) |
| `denoise3-x4` | 16 / 16 (0) | 16 / 16 (10) | 24 / 24 (18) |
| `scale-3/4` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (3) |
| `scale-1/2` | 16 / 16 (0) | 16 / 16 (3) | 24 / 24 (4) |
| `scale-1/3` | 16 / 16 (12) | 16 / 16 (11) | 19 / 24 (29) |
| `scale-1/4` | 16 / 16 (0) | 16 / 16 (2) | 24 / 24 (16) |
| `scale-3/2` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (3) |
| `upscale2` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (4) |
| `aspect-3/4` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (3) |
| `half-then-int-motion-q16` | 16 / 16 (0) | 16 / 16 (6) | 24 / 24 (8) |
| `crop-1%` | 16 / 16 (0) | 16 / 16 (29) | 24 / 24 (27) |
| `crop-2%` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (23) |
| `crop-5%` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (24) |
| `crop-10%` | 16 / 16 (0) | 16 / 16 (1) | 23 / 24 (16) |
| `mirror` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (2) |
| `rotate-90` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (2) |
| `rotate-0.5` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (19) |
| `rotate-1` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (14) |
| `rotate-2` | 16 / 16 (0) | 16 / 16 (2) | 23 / 24 (10) |
| `noise-4` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (2) |
| `noise-16` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (3) |
| `brightness+32` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (8) |
| `brightness-32` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (6) |
| `contrast-1/2` | 16 / 16 (0) | 16 / 16 (0) | 24 / 24 (2) |
| `contrast-3/2` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (14) |
| `local-blur` | 16 / 16 (0) | 16 / 16 (4) | 24 / 24 (28) |
| `crop-25%` | 16 / 16 (0) | 16 / 16 (5) | 23 / 24 (27) |
| `crop-left-2%` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (15) |
| `crop-right-2%` | 16 / 16 (0) | 16 / 16 (1) | 23 / 24 (9) |
| `crop-top-2%` | 16 / 16 (0) | 16 / 16 (1) | 23 / 24 (13) |
| `crop-bottom-2%` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (13) |
| `crop-left-5%` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (19) |
| `crop-right-5%` | 16 / 16 (0) | 16 / 16 (2) | 23 / 24 (10) |
| `crop-top-5%` | 16 / 16 (0) | 16 / 16 (1) | 23 / 24 (14) |
| `crop-bottom-5%` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (18) |
| `crop-left-10%` | 16 / 16 (0) | 16 / 16 (2) | 24 / 24 (22) |
| `crop-right-10%` | 16 / 16 (0) | 16 / 16 (2) | 23 / 24 (11) |
| `crop-top-10%` | 16 / 16 (0) | 16 / 16 (2) | 23 / 24 (11) |
| `crop-bottom-10%` | 16 / 16 (0) | 16 / 16 (2) | 23 / 24 (18) |
| `crop-left-25%` | 16 / 16 (0) | 16 / 16 (3) | 23 / 24 (21) |
| `crop-right-25%` | 16 / 16 (0) | 16 / 16 (4) | 23 / 24 (15) |
| `crop-top-25%` | 16 / 16 (0) | 16 / 16 (5) | 23 / 24 (22) |
| `crop-bottom-25%` | 16 / 16 (0) | 16 / 16 (5) | 23 / 24 (20) |
| `rotate-5` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (24) |
| `screen-a` | 16 / 16 (0) | 16 / 16 (1) | 24 / 24 (14) |
| `screen-b` | 16 / 16 (0) | 16 / 16 (3) | 23 / 24 (15) |
| attack on clips | `clips` |
|---|---|
| `none` | 4 / 4 (0) |
| `clip-int-motion-q8` | 4 / 4 (0) |
| `clip-int-motion-q24` | 4 / 4 (0) |
| `frame-drop` | 4 / 4 (0) |
| `one-frame` | 4 / 4 (1) |
| `scale-1/2` | 4 / 4 (0) |
| `noise-16` | 4 / 4 (0) |
No picture gave another payload, and no unmarked picture, under any attack, gave any. The scheme
**claims to survive** an attack only where every picture of every column, marked, gave its payload
and none, unmarked, gave any. For pictures: `int-motion-q4`, `int-motion-q8`, `int-motion-q16`, `int-motion-q32`, `int-motion-q48`, `staged-base-q8`, `denoise3`, `denoise3-x4`, `scale-3/4`, `scale-1/2`, `scale-1/4`, `scale-3/2`, `upscale2`, `aspect-3/4`, `half-then-int-motion-q16`, `crop-1%`, `crop-2%`, `crop-5%`, `mirror`, `rotate-90`, `rotate-0.5`, `rotate-1`, `noise-4`, `noise-16`, `brightness+32`, `brightness-32`, `contrast-1/2`, `contrast-3/2`, `local-blur`, `crop-left-2%`, `crop-bottom-2%`, `crop-left-5%`, `crop-bottom-5%`, `crop-left-10%`, `rotate-5`, `screen-a`. For clips: `clip-int-motion-q8`, `clip-int-motion-q24`, `frame-drop`, `one-frame`, `scale-1/2`, `noise-16`.
It does **not** claim to survive `scale-1/3`, `crop-10%`, `rotate-2`, `crop-25%`, `crop-right-2%`, `crop-top-2%`, `crop-right-5%`, `crop-top-5%`, `crop-right-10%`, `crop-top-10%`, `crop-bottom-10%`, `crop-left-25%`, `crop-right-25%`, `crop-top-25%`, `crop-bottom-25%` and `screen-b`, nor any parameter between or beyond those measured.
Every set generated survived every attack of the table. One photograph, a dense natural texture
(`bc34a3ce58dea09dce1704c997171602de90cb34d0c8503a988b77f473d39b08` in the corpus's README), did
not give its payload in 14 of the crops and rotations, nor another
(`10349e963c5c813d327852f82c1795fa4148d69fedffc4c589bee458e3ac3d53`) in `screen-b`: there the
autocorrelation of the picture's own texture outweighs the mark's at the lattice, and stage 2's
eight candidates miss it. Resampling to 1/3, which `tent64` survives on `spectral` alone, is read on both sets, on
`leaves` by stage 2, but not on five photographs.
Imperceptibility, as §7.5.8 states it, beside `tent64`'s:
| set | PSNR, least … mean (dB) | floor (dB) | SSIM, least … mean | `tent64`'s PSNR | `tent64`'s SSIM |
|---|---|---|---|---|---|
| `spectral` | 44.71 … 44.99 | 36.66 | 0.9682 … 0.9730 | 44.86 … 45.02 | 0.9688 … 0.9732 |
| `leaves` | 43.31 … 43.67 | 36.66 | 0.9677 … 0.9697 | 43.05 … 43.69 | 0.9661 … 0.9696 |
| `clips` | 41.84 … 42.05 | 38.73 | 0.9439 … 0.9482 | 41.90 … 42.08 | 0.9439 … 0.9495 |
| photographs | 41.78 … 43.63 | 35.76 | 0.9772 … 0.9844 | 41.39 … 43.58 | 0.9761 … 0.9842 |
The floor is unchanged and every figure is within 0.4 dB or 0.002 of `tent64`'s, either way: the
tiled layout carries each bit in as many cells, with the same amplitudes and margin, so finding
the grid again spends no imperceptibility.
## 8. Live rooms
### 8.1 AI participants and their events
@ -1246,6 +1518,27 @@ detects, with a decoder of its own; applies every picture attack of §7.5.7 and
sample's results; verifies every case with `synthesis_verify.py`; checks §7.5.8's claims against
`battery.json`'s tallies; and mutates copies of the corpus and requires every copy to be refused.
The same directory holds `wai-mark:tent64s`'s files, sharing its frames: `scheme-tent64s.json`,
the bytes of §7.9.1's definition; `vectors-tent64s.json`, with the tile's shuffle, signs and
mask, the embeddings of the corpus's still and clip, what the detector reads from stored frames
and from frames derived from them, with stage 2's lattice, bins, phase, offset, candidate, rank and
agreement where it reads by stage 2, a battery sample of every picture attack of §7.9.6 on the
still, marked and unmarked, and cases; and `battery-tent64s.json`, the measurement of §7.9.7 over
the measurement sets. Frames a crop, a rotation, a capture of a screen or `periodic` makes are not
stored: a vector names the stored frames, their size and count, the attack and its seed, and each
implementation derives them. The cases accept the still's marking proved and its detection
reproduced in stage 1; a crop of 10% from the left and a rotation of 2° of the marked still, each
a conversion whose detection agrees by inheritance; a simulated capture of a screen; and the marked
clip cropped, its three frames folded together; each of the last four read by stage 2 and
reproduced. They refuse a detection of the still's mark in a crop of 40% from the left, beyond
stage 2's reach, and one in unmarked content forged to repeat with the tiles' period
(`detection_irreproducible`); the term under `tent64`'s digest (`scheme_mismatch`); and a marking
of this scheme over the frames `tent64` marked (`mark_recompute_mismatch`).
`wai_synthesis_mark_vectors verify`, `tests/synthesis_mark.rs` and `synthesis_mark_verify.py`
check these files as they check `tent64`'s, the second implementation running both stages of the
detector with an autocorrelation and a fold of its own, and `wai_synthesis_mark_vectors measure
<dir> <out> tent64s` gives the photographs' column of §7.9.7.
## 14. Security and privacy considerations
- A claim carries its signer's authority. A class is a statement; what this extension adds is
@ -1258,11 +1551,14 @@ sample's results; verifies every case with `synthesis_verify.py`; checks §7.5.8
mark can be copied into other content. A detection that agrees with a claim says the content
carries that claim's mark, not that the content is the claim's subject; the claim's subject is
bound by content hash.
- The registered scheme is read with no key (§7.5.6), so anyone can find the mark and try to
remove it: in the battery, a crop of 2% or a rotation of one degree leaves no mark the detector
reads in any picture measured (§7.5.8). Anyone can also embed a payload of their choosing in any
content, a real photograph among them. The scheme claims no resistance to removal or forgery,
which the Code's Measure 3.3 asks to be assessed: what it survives is the table's processing,
- The registered schemes are read with no key (§7.5.6), so anyone can find the mark and try to
remove it: in the battery, a crop of 2% or a rotation of one degree leaves no `tent64` mark the
detector reads in any picture measured (§7.5.8), and `tent64s`, which finds the grid again
after them (§7.9.7), is undone by a crop beyond its search or by content made to outweigh it.
Anyone can also embed a payload of their choosing in any content, a real photograph among them,
or make content repeat with the tiles' period (§7.9.5). Neither scheme claims resistance to
removal or forgery, which the Code's Measure 3.3 asks to be assessed: what each survives is its
table's processing,
and nothing adversarial is claimed. A forged mark agrees only with the claim it names; that
claim's subject is bound by content hash, so the mark does not make the content its subject;
and content with a claim of its own that reads another claim's mark, not inherited through its

View file

@ -0,0 +1,454 @@
# WAI Extension: QoE Aggregation
> Status: Draft. Registers the record `wai.telemetry.aggregate`: quality-of-experience
> figures the service receives only as sums. A sink reports each session's **measures**, the
> session metrics of [delivery-telemetry](delivery-telemetry.md) §7 (its §7.2) cast as
> Prio3 measurements, through the Distributed Aggregation Protocol of
> `draft-ietf-ppm-dap-20` (DAP): it secret-shares each measurement between a **leader** and a **helper** aggregator, and
> encrypts each share to its aggregator. The aggregators check each measurement with the range
> proof of its Prio3 VDAF (`draft-irtf-cfrg-vdaf-22`) without either of them seeing it, sum the
> valid ones, and release an aggregate share only for a batch of at least the task's minimum
> size, which this extension never lets fall below fifty reports. Each aggregator signs a
> **statement** of its aggregate share with the batch's parameters (`WQS1`), and the collector,
> the service, signs an **aggregate receipt** (`WQA1`) that carries the task, both statements
> and the result: a reader recomputes the result from the two shares and knows what was
> summed, over how many reports, and by whom. With two aggregators, neither learns a
> measurement as long as one of them follows the protocol. A room's quality-of-experience cell
> ([live-metering](live-metering.md) §4.7) is computed the same way. Leader and helper are
> roles any party can run. No new transport: DAP runs over HTTP, as its own text defines.
> The reference implementation is the `telemetry_aggregate` module of `wai-rs` (feature
> `telemetry_aggregate`), with a reference leader, helper and collector that run in its tests;
> the corpus is [`live-conformance/aggregate/`](../live-conformance/aggregate/), and its
> second implementation is `live-conformance/telemetry_aggregate_verify.py`.
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
>
> Texts read for this revision: `draft-ietf-ppm-dap-20` (all of it; §4 to §8 and Appendix B
> are used here) and `draft-irtf-cfrg-vdaf-22` (§4 to §7, §9, Appendices A to C), both
> Internet-Drafts, with the test vectors the VDAF draft's [TestVectors] reference names; RFC
> 9180 (§4, §5.1, §6.1, §7.1, Appendix A.1); RFC 9861 (§2.1, §5); RFC 5869; RFC 8032; FIPS
> 180-4; CTA-5004-B through [delivery-telemetry](delivery-telemetry.md). A section number of a
> draft in this text is that revision's.
## 1. Scope
In scope: the measures and the measurement each takes from a session's metrics (§3); the DAP
task a measure runs under, the WAI layout of its `task_info`, its id and the rules a task
meets (§4); the roles of DAP as this extension uses them (§5); the statement an aggregator
signs (§6); the aggregate receipt (§7); its verification (§8); where aggregation replaces
the suppression of [delivery-telemetry](delivery-telemetry.md) §8 (its §8.4), where that
suppression still applies, and a room's cell (§9).
Out of scope: running aggregators in production; how a deployment chooses its aggregators
and agrees a task with them, which DAP leaves out of band (`draft-ietf-ppm-dap-20` §4.2);
client authentication and anonymizing proxies (DAP §8.3, §8.4); differential privacy (DAP
§8.5); any VDAF but the four Prio3 variants of §3.
Relationship to the core spec: `wai.telemetry.aggregate` 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.
## 2. Terms
- **DAP**, **task**, **report**, **report share**, **input share**, **leader**, **helper**,
**collector**, **batch**, **batch bucket**, **batch interval**, **minimum batch size**,
**aggregate share**, **aggregate result**: as `draft-ietf-ppm-dap-20` §1.2.1 defines them.
This extension's collector is the content's own service.
- **Prio3**, **measurement**, **verification**, **verifier share**: as
`draft-irtf-cfrg-vdaf-22` defines them (§5, §7).
- **Session metrics**: the figures [delivery-telemetry](delivery-telemetry.md) §7 computes
from one session's log (its §7.2).
- **Measure**: a quantity of §3, aggregated by one task.
- **Statement**: an aggregator's signed account of the aggregate share it released (§6).
- **Aggregate receipt**: the collector's signed record of an aggregate result (§7).
## 3. Measures
§3.1 A measure takes one figure, or a few, from a session's metrics and aggregates them with
one Prio3 variant of `draft-irtf-cfrg-vdaf-22` §7.4, with two aggregators and one proof:
| code | measure | VDAF (§7.4 there) | configuration (DAP Appendix B) | measurement, from the session's metrics |
|---|---|---|---|---|
| 1 | `outcomes` | Prio3SumVec | `length` 4, `max_measurement` 1, `chunk_length` 2 | `[started, start_failed, exit_before_start, vst_ms ≠ null]`, each 0 or 1 |
| 2 | `stalls` | Prio3Sum | `max_measurement` 65535 | `stalls`, at most 65535 |
| 3 | `durations` | Prio3SumVec | `length` 3, `max_measurement` 4294967295, `chunk_length` 10 | `[stall_ms, engaged_ms, vst_ms]`, `vst_ms` 0 when `null`, each at most 4294967295 |
| 4 | `start_time` | Prio3Histogram | `length` 8, `chunk_length` 3 | the bucket of `vst_ms`: 0 to 5 for a time below 250, 500, 1000, 2000, 4000 and 8000 ms, the first that holds; 6 for a later start; 7 for `null` |
§3.2 A figure past its measure's largest value is reported as that value, and a sum counts
it at that value. Each largest value is past what one session's figures reach in practice: a
stall count of 65535, and 49 days in milliseconds.
§3.3 The range proof is the VDAF's: Prio3Sum and Prio3SumVec encode each value as the bits
of `draft-irtf-cfrg-vdaf-22` §7.4.2 and prove each bit is 0 or 1, so a value past the
largest cannot be encoded, and Prio3Histogram proves its vector has one 1 and every other
element 0 (§7.4.4 there). An aggregator that verifies a report whose measurement is out of
range finds the proof fails and rejects the report, `vdaf_verify_error` (DAP §4.5.3.2),
without learning the measurement.
§3.4 Prio3Count (VDAF §7.4.1) is implemented with the others and passes the draft's
vectors; no measure of this revision uses it.
## 4. The task
### 4.1 `task_info`
A measure runs under one DAP task (`draft-ietf-ppm-dap-20` §4.2). Its configuration's
`task_info`, which DAP leaves to the deployment, is laid out as follows, 153 bytes:
| field | size | meaning |
|---|---|---|
| `label` | 8 | `wai-qoe1` (ASCII) |
| `measure` | 1 | the measure's code (§3.1) |
| `scope` | 32 | 32 zero bytes for a task of the service's own; the room id for a room's (§9.2) |
| `salt` | 16 | chosen by the task's author, so that two tasks of one configuration have two ids |
| `leader` | 32 | the Ed25519 key the leader signs its statements with |
| `helper` | 32 | the helper's |
| `collector` | 32 | the collector's, which signs the aggregate receipt |
The task configuration enters the authenticated data of every input share and of every
aggregate share (DAP §4.4.2.1, §4.6.7), so a report is bound at upload to the measure, the
scope and the three keys, and an aggregator that holds another configuration cannot decrypt
it.
### 4.2 The task id
The task id is SHA-256 of the 29 bytes `wai:telemetry-aggregate/task` (ASCII) and 0x00,
followed by the TaskConfiguration's encoding. DAP admits a task id derived from the task's
parameters (§8.6.1 there); the salt makes it unpredictable.
### 4.3 Rules
A task configuration is refused, in this order:
1. `task_invalid` when it does not read as a TaskConfiguration; its `task_info` is not 153
bytes beginning `wai-qoe1`; its `time_precision` is 0; its `batch_mode` is not
time-interval (1) or its `batch_config` is not empty; or an extension is other than
`task_interval` (1) holding one Interval, or the extensions are not in ascending order of
type;
2. `measure_unknown` when `measure` is no code of §3.1;
3. `measure_mismatch` when `vdaf_type` and `vdaf_configuration` are not the measure's: its
VDAF identifier (VDAF Table 19) and its DAP Appendix B encoding;
4. `floor_too_low` when `min_batch_size` is below 50, the floor of delivery-telemetry §8
(its §8.4);
5. `aggregator_alone` when `leader` and `helper` are one key.
The time-interval batch mode is the only one, because a leader-selected batch is one the
leader composes (DAP §8.2); a task's `time_precision` **SHOULD** be an hour or more, which
also coarsens the report times an aggregator sees (DAP §8.4).
### 4.4 The verification key
The aggregators share the VDAF verification key of the task, kept from every client (DAP
§8.6.2). The reference derives it as that section shows: HKDF-Expand of
HKDF-Extract(`verify_key`, a seed the aggregators agree) with the task id. Its verification
key id is 0.
## 5. The protocol
§5.1 **The sink.** When a session ends or is abandoned, the sink computes its metrics
(delivery-telemetry §7.2) and, for each measure the service runs, a report: a fresh random
report id, the time of the session's `end` or `abandon` in units of the task's
`time_precision`, and the measurement of §3.1 sharded and encrypted as DAP §4.4.2.1 does, with
the application context `dap-20` followed by the task id. It uploads the reports to the
leader (DAP §4.4.2). A session gives at most one report to each task. Its reports carry no
`sid`, no principal and no extension.
§5.2 **The aggregators.** The leader and the helper run DAP §4.5 and §4.6 as written, over
HTTP, with the HPKE suite of DAP §7 (DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, AES-128-GCM):
- each decrypts its own input share, checks it (§4.5.3.3, §4.5.3.4) and runs Prio3's
one-round verification with its peer by the ping-pong exchange of VDAF §5.7.1, so a report
whose proof fails is rejected by both, `vdaf_verify_error`;
- each commits a valid report's output share to the batch bucket of its time, once
(`report_replayed` for a second), and keeps per bucket the aggregate share, the count and
the checksum, the XOR of the SHA-256 of each report id (§4.5.4.3);
- each refuses to release an aggregate share for a batch below the task's minimum batch
size: the leader fails the collection job and the helper the aggregate share request,
`invalidBatchSize` (§4.6.1, §4.6.4); the helper also refuses a report count or checksum not
its own, `batchMismatch`, and a batch already collected, `batchOverlap`;
- each encrypts its aggregate share to the collector (§4.6.7) and signs a statement of it (§6).
A batch below the minimum therefore yields no aggregate as long as one aggregator follows the
protocol: the result needs both shares.
§5.3 **The collector.** The collector opens both aggregate shares and both statements,
requires each statement's share and count to be the ones DAP delivered, unshards the shares
(VDAF §7.2.5) and signs the aggregate receipt (§7).
§5.4 **What each party learns.** The leader and the helper each hold one share of each
measurement: a share alone, and the verification exchange, reveal nothing about it but
whether it is valid (VDAF §7.1; DAP §2.2). Each sees the reports' ids, times and lengths and
which reports were rejected. The collector, and a reader of a receipt, learn the aggregate,
its report count and its batch, nothing per session. Two aggregators that pool their shares
learn every measurement: the deployment chooses aggregators that do not, and DAP §8.7 says
why their infrastructure should not be shared.
## 6. The aggregate share statement
### 6.1 Layout
When an aggregator releases its aggregate share for a batch, it signs a statement, `WQS1`:
| field | size | meaning |
|---|---|---|
| `magic` | 4 | `WQS1` (ASCII) |
| `version` | 1 | 1 |
| `role` | 1 | 2 for the leader, 3 for the helper (DAP §4.1) |
| `task_id` | 32 | the task id (§4.2) |
| `collection` | 32 | SHA-256 of the CollectionJobReq the share answers (DAP §4.6.1) |
| `batch` | 16 | the batch: its interval, `start` and `duration` (u64 each) in units of the task's `time_precision` |
| `report_count` | 8 | u64: the reports aggregated in the batch |
| `checksum` | 32 | the batch's checksum (DAP §4.5.4.3) |
| `agg_share` | 4 + n | u32 length, then the aggregator's aggregate share, encoded as VDAF §7.2.7.5 encodes it |
| `signer` | 32 | the aggregator's key, the one `task_info` names for its role |
| `sig` | 64 | Ed25519 by `signer` over the 30 bytes `wai:telemetry-aggregate/share` (ASCII) and 0x01, followed by every byte before `sig`, verified strictly (SPEC §7 *Signatures*) |
Integers are big-endian. A statement is read exactly: its magic, version 1, a role of 2 or 3,
and no byte past its end; otherwise it is refused `statement_invalid`.
### 6.2 When an aggregator signs
An aggregator signs a statement only for a batch whose aggregate share it releases under DAP
§4.6: a task that meets §4.3, a batch of at least the minimum batch size, and, at the helper,
a report count and checksum that are its own. Its `batch` is the batch selector's interval,
`report_count` and `checksum` are its batch's, and `agg_share` is the share it encrypted to
the collector.
### 6.3 How a statement travels
A statement carries an aggregate share in clear, so it travels as the share does: sealed to
the collector with SealBase (RFC 9180 §6.1) under the collector's HPKE configuration, with
the info string `wai-telemetry-aggregate statement` (ASCII) followed by the sender's role and
the collector's (0x00), and the AggregateShareAad of DAP §4.6.7 as authenticated data. The
leader that relays the helper's learns nothing from it. How the sealed statement reaches the
collector beside DAP's own messages is the deployment's.
## 7. The aggregate receipt
### 7.1 Layout
The collector signs the aggregate receipt, `WQA1`:
| field | size | meaning |
|---|---|---|
| `magic` | 4 | `WQA1` (ASCII) |
| `version` | 1 | 1 |
| `task` | 2 + n | u16 length, then the TaskConfiguration (DAP §4.2) |
| `collection` | 4 + n | u32 length, then the CollectionJobReq (DAP §4.6.1) |
| `interval` | 16 | the CollectionJobResp's interval: the smallest interval holding the batch's reports |
| `leader` | 4 + n | u32 length, then the leader's statement |
| `helper` | 4 + n | u32 length, then the helper's statement |
| `result` | 2 + 16 × k | u16 count, then each element of the aggregate result as a u128 |
| `signer` | 32 | the collector's key, the one `task_info` names |
| `sig` | 64 | Ed25519 by `signer` over the 32 bytes `wai:telemetry-aggregate/receipt` (ASCII) and 0x01, followed by every byte before `sig`, verified strictly |
The receipt's **digest** is SHA-256 over every byte before `sig`.
### 7.2 Reading
A reader reads exactly the bytes it is given: `truncated` when they end before a field does,
`malformed` for another magic or a byte past `sig`, and `unknown_version` for a version other
than 1. A `helper` of length zero reads, and is refused at §8.1 step 5.
## 8. Verification
### 8.1 Steps
A verifier is given the receipt and, where it has them, the batch's reports: each report's
id, its time and the task it was uploaded to. It runs these steps and stops at the first
refusal, which it reports with the reason and where:
1. **The receipt** reads (§7.2), at `receipt`.
2. **The task** reads as a TaskConfiguration and meets §4.3, at `task`: `task_invalid`,
`measure_unknown`, `measure_mismatch`, `floor_too_low`, `aggregator_alone`.
3. **The collector**: `signer` is the `collector` key of `task_info`, otherwise
`wrong_signer`; the signature verifies (`bad_key`, `bad_signature`), at `receipt`.
4. **The collection** reads as a CollectionJobReq with a time-interval query of a duration of
at least 1, an empty aggregation parameter and no extension (Prio3's only aggregation
parameter is the empty one, VDAF §7.2.3): otherwise `collection_invalid`, at
`collection`.
5. **The statements**: both are present, and their signers differ and their roles differ,
otherwise `aggregator_alone`; each reads (§6.1, `statement_invalid`); the first has role 2
and the leader's key and the second role 3 and the helper's, otherwise `wrong_signer`;
each signature verifies (`bad_key`, `bad_signature`), at `leader` or `helper`.
6. **The binding**: each statement's `task_id` is the task's id (§4.2) and its `collection`
the SHA-256 of the receipt's `collection`, otherwise `task_mismatch`.
7. **The batch**: each statement's batch has a duration of at least 1 and falls within the
query's interval, and the receipt's `interval` has a duration of at least 1 and falls
within the batch (DAP §4.1.1), otherwise `batch_invalid`.
8. **Agreement**: the two statements state one batch, one report count and one checksum,
otherwise `statements_disagree`.
9. **The floor**: the report count is at least the task's `min_batch_size`, otherwise
`batch_too_small`.
10. **The result**: each `agg_share` is an aggregate share of the task's VDAF (its length,
and each element below the field's modulus), otherwise `share_invalid`; the result is
the two shares unsharded (VDAF §7.2.5), otherwise `result_mismatch`.
11. **The reports**, where given: each was uploaded to the receipt's task, each id appears
once, each time falls within `interval`, and their number and checksum are the
statements', otherwise `batch_mismatch`, at `reports`.
### 8.2 Outcome
A receipt that passes is **accepted**: its digest; the task id, the measure, the VDAF and its
configuration, the scope, the time precision and the minimum batch size; the batch and the
interval; the report count; the result; and the leader's, the helper's and the collector's
keys. What was summed is the measure's VDAF over that task's reports, over the report count
the two aggregators each signed, by the aggregators the task named.
An accepted receipt shows that two keys each signed its share of the batch and that the
result is their sum. It does not show that the aggregators ran verification honestly: DAP
assures a correct result only when both do (DAP §8). A statement makes each aggregator's
part attributable to its key.
## 9. Where aggregation replaces suppression
### 9.1 Event and stream reporting
[delivery-telemetry](delivery-telemetry.md) §8 suppresses a published cell of fewer than 50
sessions (its §8.4); the service holds each session's observations and refrains. Under this
extension the service never holds a session's measures: it holds aggregates, each over at
least the task's minimum batch size, enforced by each aggregator (§5.2) and checked by every
reader (§8.1 step 9). For a figure a measure of §3 aggregates, a deployment **MAY** report it
by DAP instead of in an Event-mode report, and the published figure is the receipt's.
§8.4's suppression still applies where reporting is a stream rather than a sum after the
fact:
- Request-mode reports, which travel with each request to the host that serves it
(delivery-telemetry §8.3): a host acts on them per request, and a deployment that keeps
them to the delivery class does so with delivery-only Request mode (delivery-telemetry
§4.3);
- Event-mode reports a service consumes as they arrive, for one session's playback while it
plays, which no batch can wait for;
- a figure no measure of §3 aggregates.
### 9.2 A room's cell
A room's clients **MAY** report their sessions' quality of experience under this extension
instead of in the room's logs document ([live-metering](live-metering.md) §6.1). The room's
`outcomes`, `stalls` and `durations` tasks have the room id as their `scope`. Over one batch,
the cell of live-metering §4.7 is, from the three accepted receipts of that batch and scope:
| cell field | from |
|---|---|
| `started`, `start_failed`, `exit_before_start`, `vst_count` | `outcomes`, elements 0 to 3 |
| `stalls` | `stalls` |
| `stall_ms`, `engaged_ms`, `vst_ms` | `durations`, elements 0 to 2 |
each with the report count of its receipt. A set of receipts that is not one of each of the
three measures, or that names more than one scope, a zero scope, or more than one batch, is
refused `cell_mismatch`. Within the clamps of §3.2 these are the figures live-metering §4.7
computes from the same sessions' logs. The room-session receipt then names no logs (`qoe`
zero) and its cell is suppressed, as that section requires of a receipt with fewer than 50
logs; the room's cell is the aggregate receipts', whose floor the aggregators enforce.
## 10. What a report reveals
The key classes of delivery-telemetry §3 (its §3.4) state, for each key of the CMCD mapping,
what it reveals and to whom. A DAP report reveals to each aggregator its id, its time, its length, which task it
belongs to and whether its proof verified, and to no party its measurement (§5.4). This
extension sets no consent requirement for the service's own mechanics: using a distributor's
WAI service is the person's agreement to how that service works, its aggregation among them.
Where a regime asks for a lawful basis for processing quality-of-experience data, the service
records it in a `lawful-basis` claim ([jwp-receipts](jwp-receipts.md) §2.4.6).
## 11. Reasons
The codes this extension adds, each with where it is raised:
| reason | raised at |
|---|---|
| `task_invalid` | §4.3, §8.1 step 2 |
| `measure_unknown` | §4.3, §8.1 step 2 |
| `measure_mismatch` | §4.3, §8.1 step 2 |
| `floor_too_low` | §4.3, §8.1 step 2 |
| `wrong_signer` | §8.1 steps 3 and 5 |
| `collection_invalid` | §8.1 step 4 |
| `statement_invalid` | §6.1, §8.1 step 5 |
| `aggregator_alone` | §4.3, §8.1 step 5 |
| `task_mismatch` | §8.1 step 6 |
| `batch_invalid` | §8.1 step 7 |
| `statements_disagree` | §8.1 step 8 |
| `batch_too_small` | §8.1 step 9 |
| `share_invalid` | §8.1 step 10 |
| `result_mismatch` | §8.1 step 10 |
| `batch_mismatch` | §8.1 step 11 |
| `cell_mismatch` | §9.2 |
| `measurement_key_in_delivery` | delivery-telemetry §4 (its §4.3) |
A verifier of this extension also raises `truncated`, `malformed` and `unknown_version` for a
receipt that does not read, and `bad_key` and `bad_signature` for its signatures. The
reference aggregators raise DAP's report errors (`draft-ietf-ppm-dap-20` §4.1: among them
`vdaf_verify_error`, `hpke_decrypt_error`, `report_replayed`) and its problem types (§3.6
there: among them `invalidBatchSize`, `batchMismatch`, `batchOverlap`, `batchInvalid`), as
DAP names them.
## 12. Conformance
[`live-conformance/aggregate/`](../live-conformance/aggregate/) holds:
- `vdaf-22/`: the Prio3Count, Prio3Sum, Prio3SumVec and Prio3Histogram test vectors and the
XofTurboShake128 vector of `draft-irtf-cfrg-vdaf-22` Appendix C, as published at the
commit its [TestVectors] reference names;
- `vectors.json`, written from fixed seeds by `wai_telemetry_aggregate_vectors gen`:
- the keys: each aggregator's and the collector's HPKE configuration and private key, the
three statement keys and a stranger's, and the seed of the verification keys (test
material from fixed seeds, as every corpus here);
- fifty sessions' metrics, and a **flow** for each measure: its task, the reports (fifty
sessions, one with an out-of-range measurement, and in one flow a report replayed and in
another one whose helper share does not decrypt), the upload request and the reports it
refused, the aggregation job's request and response with each report's outcome, the
collection request, the aggregate share request, the helper's aggregate share, the
collection response, both sealed statements and the result; the `outcomes` flow also
holds the collections each aggregator refuses (a batch below the minimum, a checksum not
the batch's, a batch past the query, a batch collected twice);
- **receipts**: the four flows' receipts, accepted, and refused ones, each a control of one
defect: every reason of §11 the receipt raises, the reading and signature codes, a
receipt signed for a task the reports were not uploaded to, a batch below the minimum,
a leader alone and a leader signing as both aggregators;
- **cells**: the room's cell from its three receipts, with the plaintext cell of
live-metering §4.7 over the same sessions, which it equals, and a set of receipts of two
scopes;
- **delivery-only** reports (delivery-telemetry §4.3): observations with their
delivery-only reports and header shards, and reports that carry a key past the delivery
class.
A conforming verifier gives every vector its outcome. `wai_telemetry_aggregate_vectors
verify` and the test `tests/telemetry_aggregate.rs` check that `vectors.json` regenerates
byte for byte, that `vdaf-22/` is the files as published and that `wai-rs` passes every one,
that every receipt, cell and delivery-only report gets its outcome, that every reason of §11
and every reused code refuses a vector, that §11 lists exactly the reference's codes, and
that delivery-telemetry §3 (its §3.4) classes exactly the keys the reference does.
`live-conformance/telemetry_aggregate_verify.py` is the second implementation, written from
this text and the drafts it cites: it shares no code with `wai-rs`; it evaluates Prio3 itself
(the fields, TurboSHAKE128 and the XOF, the FLP in the Lagrange basis) and passes the draft's
vectors; it opens every report with its own HPKE (X25519, HKDF-SHA256 and AES-128-GCM written
from RFC 7748, RFC 5869 and the AES and GCM specifications), recombines each measurement and
requires it to be its session's, runs both aggregators' verification and requires the
aggregation job's request and response byte for byte, recomputes every batch bucket, every
refusal, every aggregate share and every result; verifies every receipt and cell with WAI's
strict Ed25519 rule (`claim-conformance/_ed25519.py`); reads the key classes from
delivery-telemetry §3 (its §3.4) and this text's reasons from §11; and requires every mutated copy of
the corpus to fail.
## 13. Security and privacy considerations
- **Non-collusion.** Privacy rests on the two aggregators not pooling their shares
(§5.4). A statement attributes each share to a key, so a reader sees which two parties a
result depended on; it cannot see whether they colluded.
- **Correctness.** The range proof stops a sink from poisoning a sum with an out-of-range
value (§3.3); it does not stop a sink from reporting a false value in range (DAP §2.2). An
aggregator can still corrupt a result by an arbitrary amount with a wrong share; the
statement makes that share its signed statement.
- **Small batches.** A batch at the floor reveals what fifty sessions sum to. A deployment
that publishes overlapping figures across tasks of one population should consider what
their differences reveal; DAP collects each batch once (§2.3 there), which this extension
keeps, and §8.5 there describes noise an aggregator can add.
- **Linking a session's reports.** A session sends one report to each task, at once; an
aggregator that sees their arrival together can link them, though not their values. A
deployment that wants them apart sends them at different times or through a proxy (DAP
§8.4).
- **Sybil reports.** Reports are not authenticated here; one party can submit many, and so
approach a batch's floor with its own (DAP §8.1). The floor is a floor of reports, not of
people.
- **Verification key.** A sink that knew the verification key could forge a report that
passes verification (DAP §8.6.2); it is the aggregators' alone.

View file

@ -3887,6 +3887,40 @@
"replicate": "standard-unclassified"
}
]
},
{
"name": "SMPTE ST 2094-50 dynamic metadata",
"year": 2026,
"body": "SMPTE",
"modality": "metadata",
"era": "classical",
"status": "emerging",
"lineage": "standards",
"desc": "Dynamic HDR metadata for display adaptation, SMPTE ST 2094-50 (Application #5): an HDR reference white and a headroom-adaptive tone map, gain functions of alternate images that a display weights by its own headroom; carried by ITU-T T.35 messages in a codec or a container. Claimed IPR offered on reasonable and non-discriminatory terms.",
"wai": [
{
"capability": "wai.meta.st2094_50",
"licence": "patent-pool",
"replicate": "standard-unclassified"
}
]
},
{
"name": "ISO 21496-1 gain map",
"year": 2025,
"body": "ISO",
"modality": "metadata",
"era": "classical",
"status": "emerging",
"lineage": "standards",
"desc": "Gain map metadata for image conversion, ISO 21496-1: a baseline image, a gain map image and metadata from which a display makes an alternate rendition at its own headroom, HDR from an SDR base or the reverse. Royalty status not established.",
"wai": [
{
"capability": "wai.meta.gainmap",
"licence": "patent-pool",
"replicate": "standard-unclassified"
}
]
}
]
}

View file

@ -1,10 +1,10 @@
# must fail: receipts_lawful_basis receipts_lawful_basis_declaration_not_served receipts_lawful_basis_declaration_renamed
# a lawful-basis decision accepted without its declaration (receipts::step6)
diff --git a/wai/wai-rs/src/http_binding/receipts.rs b/wai/wai-rs/src/http_binding/receipts.rs
index 83cd7ccb..d8cdcc81 100644
index a9ad67595..02ea0c3d1 100644
--- a/wai/wai-rs/src/http_binding/receipts.rs
+++ b/wai/wai-rs/src/http_binding/receipts.rs
@@ -654,8 +654,8 @@ fn step6(
@@ -661,8 +661,8 @@ fn step6(
}
// §2.4.6: against the declaration it names, fetched by its link.
ClaimBody::LawfulBasis(LawfulBasisClaim::Decision { declaration, .. }) => {
@ -14,4 +14,4 @@ index 83cd7ccb..d8cdcc81 100644
+ Ok(())
}
// §2.6.3: against its declaration together with the publisher key of a verified
// delivery receipt for the declaration's subject.
// delivery receipt for the declaration's subject; for a span declaration

View file

@ -1,12 +1,12 @@
# must fail: receipts_binding_recovery receipts_binding_recovery_object_not_held receipts_binding_recovery_no_matcher
# a binding-recovery record accepted without its declaration, publisher or match (receipts::step6)
diff --git a/wai/wai-rs/src/http_binding/receipts.rs b/wai/wai-rs/src/http_binding/receipts.rs
index 83cd7ccb..7cebbbd5 100644
index a9ad67595..7ae0d84e2 100644
--- a/wai/wai-rs/src/http_binding/receipts.rs
+++ b/wai/wai-rs/src/http_binding/receipts.rs
@@ -660,8 +660,8 @@ fn step6(
// §2.6.3: against its declaration together with the publisher key of a verified
// delivery receipt for the declaration's subject.
@@ -669,8 +669,8 @@ fn step6(
// (jwp-receipts §2.6.4), with a verified delivery receipt for an object of its span:
// the first passed one within it, else the first, whose check reports why not.
ClaimBody::BindingRecovery(r) => {
- if passed.is_empty() {
- return Err(ReceiptRefusal::ContextNotHeld);
@ -14,4 +14,4 @@ index 83cd7ccb..7cebbbd5 100644
+ return Ok(());
}
let d = declaration_of(&r.declaration, fetch)?;
let publisher = passed
if let ClaimBody::SoftBindingSpan(s) = &d.body {

View file

@ -35,23 +35,36 @@ and the independent verifier of each, beside it.
| [`cowatch/`](cowatch/) | [co-watch](../extensions/co-watch.md) (`wai.live.cowatch`) | `wai_co_watch_vectors gen` | `co_watch_verify.py` |
| [`synthesis-mark/`](synthesis-mark/) | [synthesis](../extensions/synthesis.md) §7.4 to §7.8 (the watermark scheme `wai-mark:tent64`) | `wai_synthesis_mark_vectors gen` | `synthesis_mark_verify.py` |
| [`upscale/`](upscale/) | [exact-upscale](../extensions/exact-upscale.md) (`wai.media.upscale`) | `wai_upscale_vectors gen` | `upscale_verify.py` |
| [`dred/`](dred/) | [opus-dred](../extensions/opus-dred.md) (`wai.audio.opus.dred.int`) | `wai_dred_vectors gen` (with the draft's weights file, `dred/fetch.sh`) | `dred_verify.py` |
| [`aggregate/`](aggregate/) | [telemetry-aggregation](../extensions/telemetry-aggregation.md) (`wai.telemetry.aggregate`) | `wai_telemetry_aggregate_vectors gen` | `telemetry_aggregate_verify.py` |
| [`tonemap/`](tonemap/) | [exact-tonemap](../extensions/exact-tonemap.md) (`wai.media.tonemap`, `wai.meta.gainmap`, `wai.meta.st2094_50`) | `wai_tonemap_vectors gen` | `tonemap_verify.py` |
| [`robustness/`](robustness/) | [robustness-evidence](../extensions/robustness-evidence.md) (`wai.media.robustness`) | `wai_robustness_vectors gen` | `robustness_verify.py` |
| [`splat/`](splat/) | [splat-exact](../extensions/splat-exact.md) (`wai.splat.exact`) | `wai_splat_exact_vectors gen` | `splat_exact_verify.py` |
**Provenance.** Generated here: each directory's corpus is written by its row's generator
(`gen`, in `wai/wai-rs`), from records authored in code and from fixed seeds, and each
directory's README says how. `c2pa-live/` cuts its media from the packaging corpus's AV1
floor, `contribution/` generates its pictures with `wai.generate.spectral` and the model
file of that capability's conformance vector, and `takedown/` carries the registry of clocks
the repository publishes, `registry/takedown-clocks.json`, as written there. `joule_moq_e2ee_vectors gen` (in
floor; `contribution/` generates its pictures with `wai.generate.spectral` and the model
file of that capability's conformance vector; and `upscale/` reads two priors that
`tools/wai_int_sr_train.py` trained on pictures it generates (`upscale/README.md`). `joule_moq_e2ee_vectors gen` (in
floor, and `contribution/` and `influence/` generate their pictures with `wai.generate.spectral`
floor; `contribution/` and `influence/` generate their pictures with `wai.generate.spectral`
and the model file of that capability's conformance vector (`influence/` also with a second
model file written from it). `joule_moq_e2ee_vectors gen` (in
model file written from it); `takedown/` carries the registry of clocks the repository
publishes, `registry/takedown-clocks.json`, as written there; and `upscale/` reads two priors
that `tools/wai_int_sr_train.py` trained on pictures it generates (`upscale/README.md`).
`tonemap/` renders generated HDR scenes to its stills with the reference's own encoder, and
tone-maps the frames of the `int_video` clip of the integer video corpus.
`robustness/` generates its pictures with the dead-leaves generator of `synthesis_mark` and
with `wai.generate.spectral`, and measures the synthesis corpus's measurement sets, whose
samples it does not hold.
`splat/` carries the learned cloud of `wai-rs/tests/vectors/int_splat/` beside scenes
authored as attribute bytes.
`joule_moq_e2ee_vectors gen` (in
`joule-code/joule-code-rs/crates/joule-moq-mls`) writes `e2ee/vectors.json` from fixed seeds,
and `e2ee/` also holds the test vectors RFC 9605 and `draft-ietf-moq-secure-objects-01`
publish, as printed (`e2ee/README.md`). One recorded record: `metering/relay-record.wmh` and
its ledger, which the reference relay signed in its test.
publish, as printed (`e2ee/README.md`), and `aggregate/vdaf-22/` the Prio3 test vectors of
`draft-irtf-cfrg-vdaf-22`, as published at the commit that draft names (`aggregate/README.md`).
`dred/` names the weights file of draft-ietf-mlcodec-opus-dred-07 by its SHA-256 and holds no
copy: its generator and its verifier read the file the draft names, which `dred/fetch.sh`
fetches and checks. One recorded record: `metering/relay-record.wmh` and its ledger, which the
reference relay signed in its test.
Each verifier is written from its extension's text, shares no code with the reference
(`wai-rs`, or for `e2ee/`, `joule-moq` and `joule-moq-mls`), and is run by
@ -87,4 +100,9 @@ python3 influence_verify.py influence
python3 direction_verify.py direction
python3 exploration_verify.py exploration
python3 co_watch_verify.py cowatch
python3 dred_verify.py dred <weights-file>
python3 telemetry_aggregate_verify.py aggregate
python3 tonemap_verify.py tonemap
python3 robustness_verify.py robustness
python3 splat_exact_verify.py splat
```

View file

@ -1,5 +1,6 @@
"""The registered watermark scheme `wai-mark:tent64` of extensions/synthesis.md §7.5, and the
attacks of its battery (§7.5.7), written from the extension's text.
"""The registered watermark schemes `wai-mark:tent64` (extensions/synthesis.md §7.5) and
`wai-mark:tent64s` (§7.9), and the attacks of their battery (§7.5.7, §7.9.6), written from the
extension's text.
Shared by the two Python verifiers of the synthesis corpora (synthesis_verify.py and
synthesis_mark_verify.py); it shares no code with wai-rs. Standard library only.
@ -9,6 +10,7 @@ results are the extension's to the byte.
"""
import hashlib
import math
SCHEME = "wai-mark:tent64"
GRID = 64
@ -217,8 +219,9 @@ def luma_plane(frame):
return [luma(frame[p], frame[p + 1], frame[p + 2]) for p in range(0, len(frame), 3)]
def bit_statistics(y, w, h):
"""T_j over one luma plane of w × h."""
def bit_statistics(y, w, h, layout=None):
"""T_j over one luma plane of w × h, under a layout (bit cells, signs) or tent64's."""
bit_cells, signs = (BIT_CELLS, SIGNS) if layout is None else (layout[0], layout[1])
cx, fx, _, _ = axis(w)
cy, fy, _, _ = axis(h)
s = [0] * CELLS
@ -230,15 +233,17 @@ def bit_statistics(y, w, h):
r0, f = cy[row] * GRID, fy[row]
for i in range(GRID):
s[r0 + i] += f * acc[i]
return [sum(SIGNS[k] * s[k] for k in BIT_CELLS[j]) for j in range(LENGTH)]
return [sum(signs[k] * s[k] for k in bit_cells[j]) for j in range(LENGTH)]
# ---------------------------------------------------------------- embedding, §7.5.4
def embed(unmarked, w, h, n, payload):
"""The marked frames, and each frame's amplitudes (a string of 248 digits as base-36)."""
def embed(unmarked, w, h, n, payload, layout=None):
"""The marked frames, and each frame's amplitudes, under a layout (bit cells, signs, mask)
or tent64's."""
bit_cells, signs, mask = (BIT_CELLS, SIGNS, MASK) if layout is None else layout
code = encode(payload)
sigma = [1 if code[j] ^ MASK[j] else -1 for j in range(LENGTH)]
sigma = [1 if code[j] ^ mask[j] else -1 for j in range(LENGTH)]
_, fx, lx, ex = axis(w)
_, fy, ly, ey = axis(h)
fb = w * h * 3
@ -251,9 +256,9 @@ def embed(unmarked, w, h, n, payload):
sg = sigma[j]
pixels = [] # (offset, ε·ω, z, ν)
q = 0
for k in BIT_CELLS[j]:
for k in bit_cells[j]:
i, jj = k % GRID, k // GRID
eps = SIGNS[k]
eps = signs[k]
for row in range(ey[jj], ey[jj + 1]):
for col in range(ex[i], ex[i + 1]):
om = fx[col] * fy[row]
@ -304,14 +309,15 @@ def orient(y, w, h, o):
return out, ow, oh
def read_word(samples, w, h, n, o):
def read_word(samples, w, h, n, o, layout=None):
mask = MASK if layout is None else layout[2]
fb = w * h * 3
t = [0] * LENGTH
for f in range(n):
y, ow, oh = orient(luma_plane(samples[f * fb:(f + 1) * fb]), w, h, o)
for j, v in enumerate(bit_statistics(y, ow, oh)):
for j, v in enumerate(bit_statistics(y, ow, oh, layout)):
t[j] += v
return [(1 if t[j] > 0 else 0) ^ MASK[j] for j in range(LENGTH)]
return [(1 if t[j] > 0 else 0) ^ mask[j] for j in range(LENGTH)]
def detect(samples, w, h, n):
@ -404,7 +410,10 @@ def area(px, w, h, nw, nh):
return bytes(out)
ROTATIONS = {"rotate-0.5": (65534, 572), "rotate-1": (65526, 1144), "rotate-2": (65496, 2287)}
ROTATIONS = {"rotate-0.5": (65534, 572), "rotate-1": (65526, 1144), "rotate-2": (65496, 2287), "rotate-5": (65287, 5712)}
# §7.9.6: the simulated captures of a screen, (num, den) of the resampling and the rotation.
SCREENS = {"screen-a": ((5, 4), (65526, 1144)), "screen-b": ((4, 5), (65496, -2287))}
def rotate(px, w, h, cs, sn):
@ -460,6 +469,23 @@ def attack(name, px, w, h, seed):
if name == "half-then-int-motion-q16":
nw, nh = w // 2, h // 2
return int_motion(area(px, w, h, nw, nh), 16), nw, nh
for side, prefix in enumerate(("crop-left-", "crop-right-", "crop-top-", "crop-bottom-")):
if name.startswith(prefix) and name.endswith("%"):
pc = int(name[len(prefix):-1])
cx, cy = w * pc // 100, h * pc // 100
x0, y0, nw, nh = [(cx, 0, w - cx, h), (0, 0, w - cx, h), (0, cy, w, h - cy), (0, 0, w, h - cy)][side]
out = b"".join(px[(y * w + x0) * 3:(y * w + x0 + nw) * 3] for y in range(y0, y0 + nh))
return out, nw, nh
if name in SCREENS:
(n, d), (cs, sn) = SCREENS[name]
nw, nh = w * n // d, h * n // d
shown = rotate(area(px, w, h, nw, nh), nw, nh, cs, sn)
shown = bytes((2 * v * (v + 255) + 510) // 1020 for v in shown)
r = stream(b"wai-mark:battery noise", seed)
return bytes(clamp(v + next(r) % 9 - 4) for v in shown), nw, nh
if name == "periodic":
qw, qh = w // 2, h // 2
return b"".join(px[((y % qh) * w + x % qw) * 3:((y % qh) * w + x % qw) * 3 + 3] for y in range(h) for x in range(w)), w, h
if name.startswith("crop-"):
pc = int(name[len("crop-"):-1])
dx, dy = w * pc // 200, h * pc // 200
@ -498,3 +524,354 @@ def attack(name, px, w, h, seed):
out[(y * w + x) * 3 + c] = mval
return bytes(out), w, h
raise ValueError("no picture attack named %r" % name)
def attack_frames(name, px, w, h, n, seed):
"""A geometric attack, or `periodic`, on each of n frames: (result, width, height)."""
fb = w * h * 3
outs = [attack(name, px[f * fb:(f + 1) * fb], w, h, seed) for f in range(n)]
return b"".join(o[0] for o in outs), outs[0][1], outs[0][2]
# ================================================================ wai-mark:tent64s, §7.9
SCHEME_S = "wai-mark:tent64s"
TILE = 32
POSITIONS = TILE * TILE
PER_TILE = 4
STAGE2_FRAMES = 8
WORKING_SIDE = 1024
ROBUST_CLAMP = 100
CANDIDATES = 8
DECODES = 4
SPAN = ((7, 20), (3, 4))
SLOPE = (3, 20)
SUB = 64
def _tile_layout():
"""§7.9.2: the shuffle of the tile's 1024 positions, their signs and the mask."""
r = stream(b"wai-mark:tent64s stream")
perm = list(range(POSITIONS))
for i in range(POSITIONS - 1, 0, -1):
j = next(r) % (i + 1)
perm[i], perm[j] = perm[j], perm[i]
signs = [1 if next(r) % 2 == 0 else -1 for _ in range(POSITIONS)]
mask = [next(r) & 1 for _ in range(LENGTH)]
return perm, signs, mask
T_PERM, T_SIGNS, T_MASK = _tile_layout()
def _cell_of(p, t):
"""The frame cell of tile position p in tile t (left to right, then top to bottom)."""
row, col = divmod(p, TILE)
return GRID * (TILE * (t // 2) + row) + TILE * (t % 2) + col
_S_SIGNS = [0] * CELLS
for _p in range(POSITIONS):
for _t in range(4):
_S_SIGNS[_cell_of(_p, _t)] = T_SIGNS[_p]
LAYOUT_S = ([[_cell_of(T_PERM[PER_TILE * j + k], t) for k in range(PER_TILE) for t in range(4)] for j in range(LENGTH)], _S_SIGNS, T_MASK)
def embed_s(unmarked, w, h, n, payload):
"""§7.9.3: §7.5.4's embedding under the tiled layout."""
return embed(unmarked, w, h, n, payload, LAYOUT_S)
def _rnd(n, d):
"""n / d to the nearest integer, halves away from zero, for any d ≠ 0."""
if d < 0:
n, d = -n, -d
sg = (n > 0) - (n < 0)
return sg * ((2 * abs(n) + d) // (2 * d))
def _working(frame, w, h, k):
y = luma_plane(frame)
if k == 1:
return y, w, h
ww, hh, kk = w // k, h // k, k * k
out = []
for oy in range(hh):
for ox in range(ww):
s = sum(y[(oy * k + dy) * w + ox * k + dx] for dy in range(k) for dx in range(k))
out.append((s + kk // 2) // kk)
return out, ww, hh
def _robust(y, w, h):
row = [0] * (w * h)
for r in range(h):
b = r * w
for x in range(w):
row[b + x] = sum(y[b + min(max(x + d, 0), w - 1)] for d in (-2, -1, 0, 1, 2))
out = [0] * (w * h)
for r in range(h):
rows = [min(max(r + d, 0), h - 1) * w for d in (-2, -1, 0, 1, 2)]
for x in range(w):
v = 25 * y[r * w + x] - sum(row[q + x] for q in rows)
out[r * w + x] = -ROBUST_CLAMP if v < -ROBUST_CLAMP else ROBUST_CLAMP if v > ROBUST_CLAMP else v
return out
def _sign_plane(r, w, h):
lx, ly = max(2, w // GRID), max(2, h // GRID)
wq, hq = w - lx + 1, h - ly + 1
fx = [tent(u, lx) for u in range(lx)]
fy = [tent(u, ly) for u in range(ly)]
horiz = [sum(fx[u] * r[row * w + x + u] for u in range(lx)) for row in range(h) for x in range(wq)]
q = []
for y in range(hq):
for x in range(wq):
s = sum(fy[v] * horiz[(y + v) * wq + x] for v in range(ly))
q.append((s > 0) - (s < 0))
return q, wq, hq
def _autocorrelation(planes, wq, hq):
"""§7.9.4 step 4, exactly: one product of two integers per frame (rows laid end to end at
a stride of 2·Wq, four bytes a value), summed, read back. Returns A(dx, dy) as a function."""
import sys as _sys
stride = 2 * wq
n = hq * stride
ones = int.from_bytes(b"\x01\x00\x00\x00" * n, "little")
total = 0
for q in planes:
flat = [0] * n
for y in range(hq):
flat[y * stride:y * stride + wq] = q[y * wq:(y + 1) * wq]
fwd = b"".join((v + 1).to_bytes(4, "little") for v in flat)
rev = b"".join((v + 1).to_bytes(4, "little") for v in reversed(flat))
a = int.from_bytes(fwd, "little") - ones
b = int.from_bytes(rev, "little") - ones
total += a * b
bias = int.from_bytes(b"\x00\x00\x00\x80" * (2 * n - 1), "little")
raw = (total + bias).to_bytes(4 * (2 * n - 1), "little")
import array
slots = array.array("I")
slots.frombytes(raw)
if _sys.byteorder == "big":
slots.byteswap()
def at(dx, dy):
if abs(dx) >= wq or abs(dy) >= hq:
return 0
return slots[n - 1 + dy * stride + dx] - (1 << 31)
return at
def _candidates(at, wq, hq):
"""§7.9.4 step 5: up to 8 lattice candidates (dx, dy, e, g)."""
(ln, ld), (hn, hd) = SPAN
def ov(x, y):
return 0 if abs(x) >= wq or abs(y) >= hq else (wq - abs(x)) * (hq - abs(y))
rows = []
idx = 0
for dx in range(-(-ln * wq // ld), hn * wq // hd + 1):
m = SLOPE[0] * dx // SLOPE[1]
a1, o1 = None, None
for dy in range(-m, m + 1):
a1, o1 = at(dx, dy), ov(dx, dy)
for e in range(-(-ln * hq // ld), hn * hq // hd + 1):
g = _rnd(-dy * e, dx)
a = a1 + at(g, e) + at(dx + g, dy + e) + at(dx - g, dy - e)
o = o1 + ov(g, e) + ov(dx + g, dy + e) + ov(dx - g, dy - e)
rows.append((-((65536 * a) // max(1, math.isqrt(o))), idx, dx, dy, e, g))
idx += 1
rows.sort()
out = []
for _, _, dx, dy, e, g in rows:
if all(max(abs(t[0] - dx), abs(t[1] - dy), abs(t[2] - e)) > 2 for t in out):
out.append((dx, dy, e, g))
if len(out) == CANDIDATES:
break
return out
def _vertex(l, c, r):
d = l - 2 * c + r
if d >= 0:
return 0
return max(-32, min(32, _rnd(32 * (r - l), -d)))
def _refine(at, dx, dy):
c = at(dx, dy)
return SUB * dx + _vertex(at(dx - 1, dy), c, at(dx + 1, dy)), SUB * dy + _vertex(at(dx, dy - 1), c, at(dx, dy + 1))
def _tile_stats(f, mx, my, px, py):
nx, ny = TILE * mx, TILE * my
tx = [tent(u, mx) for u in range(mx)]
ty = [tent(u, my) for u in range(my)]
rowsum = [] # per bin row, per cell column
for row in range(ny):
base = row * nx
rowsum.append([sum(tx[u] * f[base + (a * mx + px + u) % nx] for u in range(mx)) for a in range(TILE)])
s = [0] * POSITIONS
for b in range(TILE):
rs = [rowsum[(b * my + py + v) % ny] for v in range(my)]
for a in range(TILE):
s[b * TILE + a] = sum(ty[v] * rs[v][a] for v in range(my))
return s
def _oriented(s, o):
sg = -1 if ((o & 1) ^ ((o >> 1) & 1)) else 1
out = [0] * POSITIONS
for y in range(TILE):
for x in range(TILE):
x1 = TILE - 1 - x if o & 1 else x
y1 = TILE - 1 - y if o & 2 else y
x2, y2 = (y1, x1) if o & 4 else (x1, y1)
out[y * TILE + x] = sg * s[y2 * TILE + x2]
return out
_FULL = (1 << POSITIONS) - 1
_ROW_LO = [sum(((1 << (TILE - c)) - 1) << (TILE * r) for r in range(TILE)) for c in range(TILE)]
_ROW_HI = [_FULL ^ _ROW_LO[c] for c in range(TILE)]
def _roll(bm, r, c):
"""The bitmap over offsets s = 32·y0 + x0 whose bit s is bm's bit at position
32·((r + y0) mod 32) + (c + x0) mod 32."""
k = (TILE * r) % POSITIONS
v = ((bm >> k) | (bm << (POSITIONS - k))) & _FULL
if c:
v = ((v >> c) & _ROW_LO[c]) | ((v << (TILE - c)) & _ROW_HI[c])
return v
def _add_plane(counter, plane):
i = 0
while plane:
if i == len(counter):
counter.append(0)
counter[i], plane = counter[i] ^ plane, counter[i] & plane
i += 1
def _agreements(so):
"""For every offset, the agreement count of §7.9.4 step 8: over every bit, the pairs of its
four cells whose ε·S are both above 0 or both not. Bit-sliced over the 1024 offsets."""
pos = sum(1 << p for p in range(POSITIONS) if so[p] > 0)
neg = sum(1 << p for p in range(POSITIONS) if so[p] < 0)
odd_c, eq_c = [], []
for j in range(LENGTH):
planes = []
for k in range(PER_TILE):
p = T_PERM[PER_TILE * j + k]
planes.append(_roll(pos if T_SIGNS[p] > 0 else neg, p // TILE, p % TILE))
a, b, c, d = planes
_add_plane(odd_c, a ^ b ^ c ^ d)
_add_plane(eq_c, (a & b & c & d) | (_FULL & ~(a | b | c | d)))
out = []
for s in range(POSITIONS):
odd = sum(((odd_c[i] >> s) & 1) << i for i in range(len(odd_c)))
eq = sum(((eq_c[i] >> s) & 1) << i for i in range(len(eq_c)))
out.append(2 * LENGTH + odd + 4 * eq)
return out
def _word_s(so, x0, y0):
w = []
for j in range(LENGTH):
t = 0
for k in range(PER_TILE):
p = T_PERM[PER_TILE * j + k]
t += T_SIGNS[p] * so[((p // TILE + y0) % TILE) * TILE + (p % TILE + x0) % TILE]
w.append((1 if t > 0 else 0) ^ T_MASK[j])
return w
def stage2(samples, w, h, n, words_only=False, trace=False):
"""§7.9.4 stage 2: (payload, orientation, errors, resync) or None; with words_only, the
words it decodes, all of them; with trace, every candidate kept (its vectors, lattice, bins
and phase) and the hypotheses decoded, each [agreement, tile, orientation, x0, y0]."""
k = -(-max(w, h) // WORKING_SIDE)
fb = w * h * 3
robs, planes = [], []
for f in range(min(n, STAGE2_FRAMES)):
y, ww, hh = _working(samples[f * fb:(f + 1) * fb], w, h, k)
r = _robust(y, ww, hh)
q, wq, hq = _sign_plane(r, ww, hh)
robs.append(r)
planes.append(q)
at = _autocorrelation(planes, wq, hq)
tiles = []
for ci, (dx, dy, e, g) in enumerate(_candidates(at, wq, hq)):
x1, y1 = _refine(at, dx, dy)
x2, y2 = _refine(at, g, e)
det = x1 * y2 - x2 * y1
if det <= 0:
continue
mx, my = (min(8, max(4, v // (SUB * TILE))) for v in (x1, y2))
nx, ny = TILE * mx, TILE * my
sx, sy = SUB * nx, SUB * ny
folds = [[0] * (nx * ny) for _ in range(4)]
for r in robs:
for yy in range(hh):
for xx in range(ww):
u = sx * (y2 * xx - x2 * yy) // det
v = sy * (x1 * yy - y1 * xx) // det
folds[(u // nx) % 2 + 2 * ((v // ny) % 2)][(v % ny) * nx + u % nx] += r[yy * ww + xx]
best = None
for py in range(my):
for px in range(mx):
parts = [_tile_stats(fc, mx, my, px, py) for fc in folds]
s = [parts[0][i] + parts[1][i] + parts[2][i] + parts[3][i] for i in range(POSITIONS)]
en = sum(s[i] * s[i] - sum(p[i] * p[i] for p in parts) for i in range(POSITIONS))
if best is None or en > best[0]:
best = (en, (px, py), s)
tiles.append(({"lattice": [x1, y1, x2, y2], "bins": [mx, my], "phase": list(best[1]), "candidate": ci}, best[2], [dx, dy, g, e]))
hyps = []
oriented = {}
for ti, (_, s, _v) in enumerate(tiles):
for o in range(8):
so = _oriented(s, o)
oriented[(ti, o)] = so
for i, cnt in enumerate(_agreements(so)):
hyps.append((-cnt, len(hyps), ti, o, i % TILE, i // TILE))
hyps.sort()
if trace:
return {"candidates": [{"vectors": v, "lattice": r["lattice"], "bins": r["bins"], "phase": r["phase"]} for r, _, v in tiles],
"decoded": [[-h[0], h[2], h[3], h[4], h[5]] for h in hyps[:DECODES]]}
words = []
for rank, (ncnt, _, ti, o, x0, y0) in enumerate(hyps[:DECODES]):
wd = _word_s(oriented[(ti, o)], x0, y0)
words.append(wd)
if words_only:
continue
got = decode(wd)
if got is not None:
res = dict(tiles[ti][0], offset=[x0, y0], rank=rank, agreement=-ncnt)
return got[0], o, got[1], res
return words if words_only else None
def stage2_trace(samples, w, h, n):
"""Stage 2's trace (§7.9.4 steps 5 to 9), whatever stage 1 reads; None for frames the
scheme does not admit."""
if not admits(w, h, n) or len(samples) != w * h * 3 * n:
return None
return stage2(samples, w, h, n, trace=True)
def detect_s(samples, w, h, n):
"""§7.9.4: (payload, stage, orientation, errors, resync) or None."""
if not admits(w, h, n) or len(samples) != w * h * 3 * n:
return None
for o in range(8):
got = decode(read_word(samples, w, h, n, o, LAYOUT_S))
if got is not None:
return got[0], 1, o, got[1], None
got = stage2(samples, w, h, n)
if got is None:
return None
return got[0], 2, got[1], got[2], got[3]

View file

@ -0,0 +1,61 @@
# live-conformance/aggregate — quality of experience the service receives only as sums
The corpus of [`extensions/telemetry-aggregation.md`](../../extensions/telemetry-aggregation.md)
§12: sessions' measures secret-shared to a leader and a helper aggregator under DAP
(`draft-ietf-ppm-dap-20`) with Prio3 (`draft-irtf-cfrg-vdaf-22`), the aggregation and the
collection, the statement each aggregator signs and the aggregate receipt; and the
delivery-only reports of [`delivery-telemetry`](../../extensions/delivery-telemetry.md) §4.3.
## Files
- `vdaf-22/`: the test vectors `draft-irtf-cfrg-vdaf-22` Appendix C points to, for the
variants this extension uses or implements (Prio3Count, Prio3Sum, Prio3SumVec,
Prio3Histogram) and its XofTurboShake128 vector, each file as published.
- `vectors.json`, written by `wai_telemetry_aggregate_vectors gen`:
- `keys`: the leader's, the helper's and the collector's HPKE configurations and private
keys, the three Ed25519 statement keys and a stranger's, and the seed every task's
verification key is derived from (DAP §8.6.2). Test material, from fixed seeds;
- `sessions`: fifty sessions' metrics (delivery-telemetry §7.2) and each one's report time;
- `flows`, one per measure (§3): the task's configuration, id and verification key; the
reports, each with its kind (a session's, with the measurement its session gives; one out
of range, with its encoding; in `outcomes` one replayed, in `start_time` one whose helper
share does not decrypt); the upload request and the reports the leader refused; the
aggregation job's request and response and each report's outcome; in `outcomes`, the
collections each aggregator refuses, before or after the collection; the collection: its
request, the aggregate share request, the helper's aggregate share, the collection
response and both statements sealed to the collector; the result and the receipt;
- `receipts`: aggregate receipts (§7), with the batch's reports where a reader is given
them, and the outcome §8.2 gives each: accepted, or the reason and where;
- `cells`: a room's cell from its receipts (§9.2), with the plaintext cell of
live-metering §4.7 over the same sessions where it is accepted;
- `delivery_only`: observations with their full and delivery-only Request-mode reports and
header shards, and reports a reader refuses, each with the key it names;
- `codes`: the reasons of §11, in its order.
**Equivalence.** A conforming implementation passes `vdaf-22/`; recombines every report's
shares into the measurement stated (a session's report into its session's measurement);
reproduces each aggregation job's request and response byte for byte and each report's
outcome; gives each refusal its DAP problem type; opens every aggregate share and statement
and reaches each result; and gives every receipt, cell and delivery-only report its outcome.
**Provenance.** Generated here: `wai_telemetry_aggregate_vectors gen` writes `vectors.json`
from sessions authored in code, from fixed seeds: every key, salt, report id, Prio3 random
input, HPKE ephemeral seed and the room id is SHA-256 of `wai:telemetry-aggregate/corpus/`,
a name and a counter, joined by zero bytes; each session's metrics are a formula of its
index; times are constants. HPKE with a derived ephemeral key and Ed25519 signing are
deterministic, so the file is the same bytes on every machine. No recorded data. `vdaf-22/`
holds the test vectors of the `draft-irtf-cfrg-vdaf-22` repository (its `test_vec/` and
`test_vec/vdaf/`) at commit 888e4b127b5ba453a010c522c49a178941064919, the commit the draft's
[TestVectors] reference names, copied unchanged: code components of an IETF/IRTF
contribution, under the Simplified BSD License the IETF Trust Legal Provisions give them;
nothing in them is generated here.
## Checking
```
cd wai/wai-rs
cargo run --no-default-features --features telemetry_aggregate --bin wai_telemetry_aggregate_vectors -- verify ../live-conformance/aggregate
cargo test --no-default-features --features telemetry_aggregate --test telemetry_aggregate
cd ..
python3 -I live-conformance/telemetry_aggregate_verify.py live-conformance/aggregate
```

View file

@ -0,0 +1,89 @@
{
"agg_param": "",
"agg_result": 1,
"agg_shares": [
"355e16daa732744c",
"cda1e92557cd8bb3"
],
"ctx": "736f6d65206170706c69636174696f6e",
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"355e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6bb2277498ac41e75c01d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 1,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"355e16daa732744c",
"cda1e92557cd8bb3"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"cd7905720f16e5d9ef7657a336307ae8f3fe96d36cc09019257268349e7a7d72",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,111 @@
{
"agg_param": "",
"agg_result": 1,
"agg_shares": [
"0fda968fcb037ddf",
"cda1e92557cd8bb3",
"27847f4adb2ef76c"
],
"ctx": "736f6d65206170706c69636174696f6e",
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 2,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"0fda968fcb037ddfccc5081b305b1778a2bd741c1ae89d95b9ca77abdf92638baf89a9a556d19bc5722fad7d22e35513",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 1,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0fda968fcb037ddf",
"cda1e92557cd8bb3",
"27847f4adb2ef76c"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"645516ee55dfd833dd4171b2d9938ff5d4d73aa202fdf1673d9d08ae4f63336f",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884",
"6924ef83b9360ca6c3725f94b8fdf8899ac4004115f9e81f27cc87aa617eac84"
]
]
}
],
"shares": 3,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,329 @@
{
"agg_param": "",
"agg_result": 3,
"agg_shares": [
"06d76f4248fd447e",
"fe2890bdb602bb81"
],
"ctx": "736f6d65206170706c69636174696f6e",
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 1,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 2,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 2,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 3,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 3,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 3,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 3,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 3,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 3,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 4,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 4,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 4,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 4,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 4,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 4,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"345e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6b9d5b1d204331060f00d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 0,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"345e16daa732744c",
"cda1e92557cd8bb3"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"cd7905720f16e5d9581413b6234dedbe5d9c52e658dd03f08c70fd3a675786b4",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
},
{
"input_shares": [
"355e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6bb2277498ac41e75c01d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 1,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"355e16daa732744c",
"cda1e92557cd8bb3"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"cd7905720f16e5d9ef7657a336307ae8f3fe96d36cc09019257268349e7a7d72",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
},
{
"input_shares": [
"355e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6bb2277498ac41e75c01d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 1,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"355e16daa732744c",
"cda1e92557cd8bb3"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"cd7905720f16e5d9ef7657a336307ae8f3fe96d36cc09019257268349e7a7d72",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
},
{
"input_shares": [
"345e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6b9d5b1d204331060f00d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 0,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"345e16daa732744c",
"cda1e92557cd8bb3"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"cd7905720f16e5d9581413b6234dedbe5d9c52e658dd03f08c70fd3a675786b4",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
},
{
"input_shares": [
"355e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6bb2277498ac41e75c01d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 1,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"355e16daa732744c",
"cda1e92557cd8bb3"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"cd7905720f16e5d9ef7657a336307ae8f3fe96d36cc09019257268349e7a7d72",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,48 @@
{
"agg_param": "",
"agg_result": null,
"agg_shares": [],
"ctx": "736f6d65206170706c69636174696f6e",
"operations": [
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": false
}
],
"reports": [
{
"input_shares": [
"355e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6bb2277498ac41e75c02d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": null,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [],
"verifier_shares": [
[
"ce7905720f16e5d9ef7657a336307ae8f3fe96d36cc0901989ae428528ddf2c2",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,48 @@
{
"agg_param": "",
"agg_result": null,
"agg_shares": [],
"ctx": "736f6d65206170706c69636174696f6e",
"operations": [
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": false
}
],
"reports": [
{
"input_shares": [
"355e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6bb2277498ac41e75c01d81b4cb8485926",
"010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": null,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [],
"verifier_shares": [
[
"cd7905720f16e5d9ef7657a336307ae8f3fe96d36cc09019257268349e7a7d72",
"5f89a4089ada54621fd540ea8fcb6d6c68fbc8bb74390fd5318c13cab79e5bfe"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,48 @@
{
"agg_param": "",
"agg_result": null,
"agg_shares": [],
"ctx": "736f6d65206170706c69636174696f6e",
"operations": [
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": false
}
],
"reports": [
{
"input_shares": [
"365e16daa732744c34dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6bb2277498ac41e75c01d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": null,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [],
"verifier_shares": [
[
"cc7905720f16e5d985d99b904a1307128a61dbc07fa31d43257268349e7a7d72",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,48 @@
{
"agg_param": "",
"agg_result": null,
"agg_shares": [],
"ctx": "736f6d65206170706c69636174696f6e",
"operations": [
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": false
}
],
"reports": [
{
"input_shares": [
"355e16daa732744c35dc71fa4c85d209f9af2ecf751609386ed9e2714ecc9e6bb2277498ac41e75c01d81b4cb8485926",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": null,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [],
"verifier_shares": [
[
"cd7905720f16e5d9591413b6234dedbef3fe96d36cc09019257268349e7a7d72",
"3486fa8defe91a26a2eb81c1638c36bcf227593ab1b0e78b0d2775a9788ca884"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,96 @@
{
"agg_param": "",
"agg_result": [
0,
0,
1,
0
],
"agg_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b6173abf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb"
],
"chunk_length": 2,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 4,
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b6173abf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f62def334c7f96a411ac6fd7e371e8a1229daae809ed2fa5ce7aad581296f369a8c5037c7ff445c426ca35ed34904b335b38a164283612e000d9a14f293c88e998cec8c468354b53db7d539c3e68d0077bed5bc04691710dc8ecda1f022bef7ae724ea5e3b4d3ce268621b4d1e9012f39c404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 2,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b6173abf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb"
],
"public_share": "99fe27688507f8fb85eb564b85374872af0d5db417228ff8940d3d21c56aa1f6ac76ff51698f6c2e1a3e8869b44cf53de72da459d305e8a27e731bb685b05d86",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"0c47aa2d70cdf78b9b76ae4cbf1bab8bb6805e0c56570c0f9509bd2123644275"
],
"verifier_shares": [
[
"240bc6b75e169e6d038e3bf7c2cb841ff88d5cca88280090c2cc0e3674f45e244bee3f036043e1f14b87869d7be2899a6d19c8d38a6704b433a13ff6d88f0ad6da9f371e0c799b01374891c253741a7b47e011a8c5532aba63528ae7799e47a499fe27688507f8fb85eb564b85374872af0d5db417228ff8940d3d21c56aa1f6",
"ddf43948a1e96192e071c4083d347be07806e8fb20b426b204f73c5d5c352626851c75df044841b730623dcd732c1551382232b34bd5bd1a5aeefb4a687120ed5f6ca8e1d9ea721755f3a30788dd75fab3ec4db86e1f19c224226005677ffcc1ac76ff51698f6c2e1a3e8869b44cf53de72da459d305e8a27e731bb685b05d86"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,125 @@
{
"agg_param": "",
"agg_result": [
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0
],
"agg_shares": [
"fdba7abfd452a64f39d1691b0cc58b151758d029aebfea145c03c4a4662e16db4b4f19e18690de99a91f228ec2d93b723688d4ed51b29bdfb036fb6b1e63b68007b9a0393c8895efd2df280d53cddf0898a62cc49ed954e66bdc0326075ccb74845741a1b447e6d55ceaf1b3c7455d819847fff6cb965b98e0df1a9ba8114d12cdd6d6338954327b3f16e51eb0dbdc9695167757efd24205210b9dedeaa6a8b9046d1086221914634d44fd60c3449049",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3",
"0f08c158a338726c9cb1cd06387c71fd9b5c7115016b4cf189ed7d95e537a03cef6f29eb1164bca457648f180135917b89bf163f3191ede46878ecb33e1b87c3d567ce7545f1896e343379d964ba36792502ad372988ed01d5e69a370719e354724260b3b0023d5324f73d0aad57a7bbf26f1fa802861c780cc755ac6fdcbce83e4c8148e1d69313aaff69939f80734be7badee8eb3bc2e74fe262bef6e12064867d6b504073f9b7edd920d03f060ac3"
],
"chunk_length": 3,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 11,
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 2,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"fdba7abfd452a64f39d1691b0cc58b151758d029aebfea145c03c4a4662e16db4b4f19e18690de99a91f228ec2d93b723688d4ed51b29bdfb036fb6b1e63b68007b9a0393c8895efd2df280d53cddf0898a62cc49ed954e66bdc0326075ccb74845741a1b447e6d55ceaf1b3c7455d819847fff6cb965b98e0df1a9ba8114d12cdd6d6338954327b3f16e51eb0dbdc9695167757efd24205210b9dedeaa6a8b9046d1086221914634d44fd60c344904939a6f3e03a3c6b218ac7e25861e0be3df59ed2f2b1316c2bea8bba93ed65322065e49f495637872131b2d07233cf93a0f34ecccfefc626529dd48fd0f6d9aabaae438f1e10a5fea72b22cd5c08e5de23f5f7570bd34b2ca0412a216edc81119dc9e2704036208cd8526fd07d0996cb2c7ebe38dd61e41547d383372f15e315ae4bd598799ac205db2cd3c285fd0f428c2f063118a61ee9eb89af89fc98054fc9c993859b821980ff6df6075896d0b7d5af372f9bd3b9935afa6163ce2b255db5f8495fa49bb29f4da7ac20d0a51f239a013e07ef3ee9806e6969d4b12a8b3ce5156468a43c1fee41c91c9ee7d87dbaf04966caac210738a00b365f45ed3362e52053bef24b91cd7d657441c243b3fe3ca7de40dae6b2425dad6e0ed41bed8533f6cf18d9ca7bfc0caf8f02854de1eb6d7c85a498463981bed4c26cbd6c6a33980612396850680f557ec4ee765e67e86c808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
],
"measurement": 2,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"fdba7abfd452a64f39d1691b0cc58b151758d029aebfea145c03c4a4662e16db4b4f19e18690de99a91f228ec2d93b723688d4ed51b29bdfb036fb6b1e63b68007b9a0393c8895efd2df280d53cddf0898a62cc49ed954e66bdc0326075ccb74845741a1b447e6d55ceaf1b3c7455d819847fff6cb965b98e0df1a9ba8114d12cdd6d6338954327b3f16e51eb0dbdc9695167757efd24205210b9dedeaa6a8b9046d1086221914634d44fd60c3449049",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3",
"0f08c158a338726c9cb1cd06387c71fd9b5c7115016b4cf189ed7d95e537a03cef6f29eb1164bca457648f180135917b89bf163f3191ede46878ecb33e1b87c3d567ce7545f1896e343379d964ba36792502ad372988ed01d5e69a370719e354724260b3b0023d5324f73d0aad57a7bbf26f1fa802861c780cc755ac6fdcbce83e4c8148e1d69313aaff69939f80734be7badee8eb3bc2e74fe262bef6e12064867d6b504073f9b7edd920d03f060ac3"
],
"public_share": "ec592306b5ad39cb382410e10c07f73f38c951d2c07ec772e064a56c510b4a53b60e0d9271847d8432147861b6a374eb666b5e747a88f34585a867462487f4c8c1c72696b2e336d877a15f33c41ceb7c249967bb65f4a5fdac33886ed757ba54",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf",
"verifier_messages": [
"b5ebd9d5194aca3acc066dcc69ab0767551643a7bbd19d3ae38c002e7adf91a2"
],
"verifier_shares": [
[
"69d7ff6f9a48ffe467ee3ad53360181575f1abc1888c7cc4affb0f7a401b38827bbdc8126c3baacbe42817ee2f1306d4c7911cec9bd5572c6f3bf97372a3d654fa38c819ef4674ef89135ad448e001835a7f4bdf45fc5f27865f352ea6b376d7e5abb720ce73952b376a0c844a98280c893931f543839f68c2c5c74f33c92eddec592306b5ad39cb382410e10c07f73f38c951d2c07ec772e064a56c510b4a53",
"f1e76b139118e753040bc6979763e7955c02486da9181a47bf1f109349746c7a25de398bb389bbca0d57a4a7c1cb731234199df9869633519c4656c35b7a518996c8013324667bfc7f88cbd9d5999060dcd933f650cd85d0a4fe86b48d08e512051e39f04327e3ddb344029d21cfa4e0b0ec2f3c427cc6506643464f72fee4eab60e0d9271847d8432147861b6a374eb666b5e747a88f34585a867462487f4c8",
"a740947cd49e19c77706ff92343c0055b6069705e09d01907c04c511fcd41088f645c0cd8c4c04d8404a50c9d85c9023411a5fb27efae3b28e70e1448b5cf5324c5c83da4dda0df676a48a793a4a977a5a0e7b4236dd31f21e4822f3b81d68206baebfc9c84f54a9c1a99b9bcffb70550555b413442e04306b076d46b023e666c1c72696b2e336d877a15f33c41ceb7c249967bb65f4a5fdac33886ed757ba54"
]
]
}
],
"shares": 3,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,732 @@
{
"agg_param": "",
"agg_result": [
3,
1,
2,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
"agg_shares": [
"719e55f2b072f558711d2b56a98ce4bdeb0e9178d8aa273e146a9346fafe1fed33789bfaf78d0d720829ef82a493024a6acd30c11fa35cad51d80c3fa3ef66aa934857da10bf3aadd5be54022f4de1145b9780d6cfd197124da133a88f92d0e09003504ef5e7609b5bd0de6d8f262e625b2b33371220b1a43e8666caf24c63ce665e71db28b2bd93ffdb16f71c9b23d7cd2e5a83909432429d47ffb7d058df295a29d760dc7b870e672f2deb1fee067ec57b3e42f01faa47124d483562cdd26030e80531c84f9fd8260466068fc1f0c65976cc1616423c3cc293b0e287fcd7d7fb5e8c2a14d562f638157a0e5b8ba3daa6511a6df835d77b46ec04376b6a9694b3dee7a4e0e468350a59636ae5a60faf188c3f26e50b8ff3d94d50ca8d2f6dbc1ca8e108b2f9fe67ae0989a1be1029d1ba9d15a85af82cffd3d881e3071b8af631e716811beb07a43aa29a778969540c97ffbcc7a0979c77b2830ee56118c01572d81de31921f1652811c0e0055ce0653082a1b872f7daba2638461bb5d3b90fd618201dbab976f10be90dcf1b5aecc9a92745058c0b0b9a7f56a7242457383a49ff2c3ad09b958714407ee221d89350e7410f3cbb2ac61062df128032f491061335b395809db9dc26f9e459eeb4072ba3b5e0cb6bc70aca721c8ccf80f6ee52f0ea3854cd3323d887921ba2881f6fb55c475f09460c6011bd04d0501bf47e940528a93f0e6bca171754232715cf0e2bb69cc12e2381074bce8a4ece4aa433252dce3063e8918ee68206d5edd91b3fd4a97271fc175ce0e8442130fd86e81fa67996ee3861995caa3bdd8af2a9554d25694d52702eb1f62b4c3a2b01d633b29d2409642e659d90ee79999b00303ed39b898d858e9ef14a6cfbf6b39d16080bb83c669270ca253f56e4efa4bcad9a568124b2ca219c518d5222fc7fa05602f98a6c6b975dd053f4e1ed6b09a6133bb8ca7a394ec1681af1cb8b73b8d346065047df33d72feea4ad9c6b971fe6ac06e919088c44fadc7b8cf88da4115f9695232b804b0a18e3d70b5374aba7229744158ad4564e4f5a6932fb7e59d77308e3f95f89b8db04523e7a8efcf3e7c28d2bed59fa09d4416204ac989f1a5cf1c50c1835310b9582c0f7f44440ebbed02e417cc6cc778662655a23e25c7744bce13c2415cd00415a79748ca0f75960f2def30ce7c293a310c2d557a653fd8a262e47daf564565728ca57b397c8331bab79cde403b94066b3a539c33b9cb2117c9305b84ed9735df92f56eb5cf242bef6f25a2d55f9fbd6ba36b2b2ea8b9fd664b69c6d114f63a2595df8f0e988f25fb4ab362254c438a16b830b72f7ef755d94f7d7d42e7406e5446498d4c7127f0a31e77e61c5958a77ba6603de430dd79c8293e59aadff75aac8408304bfc3d0de5344a82ed6b26b1bc328ba87568e78b7d02562bfa374dfe9b3b2b30c9461979154662c791a902c38e3f0126203a2bfafcd06cc25aa91272e08b2f49ed21dfb77c3fbd2556c883ef8a7ed29b02d23f9f18a064631ffa032ff2679ed5bfd7742c955828f52dc5de78d26b045ff27450972f0d10ac60aecd64378b3386bf66ca3f711eefb9594a3f562b6790fa424539f1d9dd3392e328b8666cb3e971bfe7658024f37e9c50790da4580935093311f2942bc70f0c44191906cebdbd613f6008eb6732e9350f1d83db9d5b9bb8965116b7c13343ae83b26f2ef0313584d25f128178815abe2aa41382624767f6e16b9fb8f2b4e1fc64fc80e6f028da2b0a52c528eba551dd29eba202cf1fc902775a99c93fce10b9d8cd2f9a57d7e504fcab64583facf0ba5306567b6c26e7a5b324a667b2d3bf40cbb870898f00c889e4442ab5ba021c0654860f9f1bcee81391f0d86cbb2400a6eca33eb5cd6fe6efe1c6af6377253a07b4b46a0e3993709f7a6a794de74e97fb4c6394c5f19ce1d1f6c3d9b78f1578b5f3a12f7da88daf61585613446625a08230c7796e905ccbdab3c8f14d8e979597bd9747937cebcb704f674d5f0799b5be6592f1293473d9c96a5b20a4c001b00247cad32eacedd38cd77d264c3f452a0ae9d1d0b1974eefed30f4a14779204ea64c6e601def1fe3d47aa333cefaef2076355bad6f30b63f68bf9cf5590b4f930bb8b9d08d20eaeae83a8dfe94ca0496aabdae598762baa1da885b6d5332708e3c80702eb2f50fb104c4332fce99ebfb4123fa0a8e19ecbe07c09afa8c6b8e85743551fae25383ea3e6096685043f473d3d2d",
"9361aa0d4f8d0aa772e2d4a956731b4217f16e872755d8c1cf956cb90501e012d08764050872f28ddbd6107d5b6cfdb59732cf3ee05ca3529227f3c05c1099556eb7a825ef40c5520e41abfdd0b21eeba6687f29302e68ed965ecc57706d2f1f71fcafb10a189f64882f219270d9d19da6d4ccc8eddf4e5ba57999350db39c319ba18e24d74d426ce423e908e364dc2834d1a57c6f6bcdbd46b800482fa720d6a7d6289f238478f17cd0d214e011f9813c84c1bd0fe055b8d1b2b7ca9d322d9fd117face37b06027bdfb99f9703e0f39a88933e9e9bdc3c3216c4f1d7803282806a173d5eb2a9d09abea85f1a4745c255baee59207ca28849d13fbc89495696b4e21185b1f1b97cad9a69c951a59f050ea73c0d91af4700c0ab2af3572d09243e5571ef74d06019835f6765e41efd62e4762ea57a507d30010277e1cf8e47509d018e97ee414f85ba95d65887696abf36a0043385f686388317cf11a9ee73fea8f27e21ce6de0e9abbee3f1ffaa31f9ad17d5e478d082545bdc7b9e44a2c46f02be7dfe24546890ed816f230e4a5133658d8bafa73f4f46564a958dbdba8c7c5b800d3c52f646a78cfbf811dde276caf1abef0c344d539ef8120ed7fcd0b6ef9eeca4c6a7f624623bd061ba6114bf8d45e4a1f349438f53571e373307f0911ad1115c7ab32ccdc275c6de45d77e0904aa5b8a0f6b9f39fee26fb2fafe40b816bfcd756c0f19435e8ccabdcd8ea30f1d44b633ed1dc7ef8b41575b131b55bccdad431cf9c176e711961f92a1226e4c02b588d8e03e8a31f179fdecf027917e059886911c79e66a355a822750d56aab2da98b2ad8fd14e09d497c5d4fe29cc4d62ddf69bd19a626f116a6664ffcfc12c6478727a71610eb593e8084c62e9f7f447c5996d8f35dac0a9ff0f5b435265a97edd4d35de63ae72adc103805fa9fd0675969468a22fac0b1ef693f659ecc4473587c6b13e97e50e34588c472cb9f9afb822cc28d0115b52637868e01953f916e6f973bb0523847307565beea0696adcd481b4f5e71c28f4ac6f5458dd68bbea752da9b1b0a596cd0465a6288cf71c06a0784724fbadc18571e70b183d72d412a607f62bbe9dfb536744e5a30e3af3e7cad0f46a7d3f080bbba314412fd1be83393588799d9aa5dc1d8788bb431ec3dbea34ffbea5868b735feca59f0d210cf3183f6c5cef3d2aa859900275d9d1b8250a9da9a8d735a84c681bcce45486321bfc48bf994c5ac63cc4474dee836cfa47b1288ca206d0a914a3f1bc41090da5d2aa08042945c94d4d155860299b496392eeb29c5da6a2070f165b0da04b54c9ddab3dc75e947cf48d08f489a26b08282bd18df91abb9b672b38d180f5ce18819e3a6c75884599fc21bcd628637d6c1a6552028a5537bf7cfb40202f21acbb57d1294f94e43cd74578a95587482fda9d405c8d20164c4d4cf36b82686eab99d386e571d3c71c0fed9dfc41405032f933da5570d8d1f74d0b612dc604883c042daa9379c1075812d64fd2c0060e75f9b9ce0061cd00d98612a4026cbd36aa7d70ad23a41872d94fba00d89ef68d0f2ef539f51529bc874cc79409775c08ee11046a6b5e0a9d4986f05bdb9060e2622cc6d1cd76799934c168e4016da7fdb0c8163af87125ba7f6caf6ccec4d6bd438f0f3bbe706f93142429ec09e371498cd16caf0e29c2462a4644769ad29483eccbc517c4db0d10fceca7b2daf2d6e877ea541d55c0c7d9db898091e92a0470d4b1e039b039f190fd725d4f5ab7ad7145aae22d6147dfd30e036fd88a3a636c031ef462732f065a8281afb0352dba7c0530f45acf9c98493d9185a4cd999984d2c40bf3447af7670ff37761bba154a45fde3f9ab7a1060e43117ec6e0d679344dbff59135ce14a329019101e37909c88dac5f84b4bb5f1c66c8f608593c6b218b16804b39c8b3a0e631e2e093a664870ea874a0c5ef0825772509ea7a82cbb99da5f7dcf38a6916fa334254c354eb271686a684268d86c8314348fb096f2a0f8664a419a6d2ed6cb8c263695a31f5b3ffe4ffdb8354cd153122c73288119b3c0bad5f5162e4f4e68b11012cf099eb886dfb159b391bfe210e01c2b855b0c310510df89caa47290cf49c09740614aa6f4b06cf447464f72df151517c570416b35fb69554251c6789d455e2577a2d2accd8f71c37f8ff14d0af04efb3bcb1031661404bedc061571e61341f83f63457394717a8bcaae451dac7c15c19f67d7afbc0b8c2c2d2"
],
"chunk_length": 10,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 100,
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 1,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 2,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 2,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 3,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 3,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 3,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 3,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 3,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 3,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 4,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 4,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 4,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 4,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 4,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 4,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 5,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 5,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 5,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 5,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 5,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 5,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 6,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 6,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 6,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 6,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 6,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 6,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 7,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 7,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 7,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 7,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 7,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 7,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 8,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 8,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 8,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 8,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 8,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 8,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 9,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 9,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 9,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 9,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 9,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 9,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b6173abf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453aaeceb029c586cef7fa6829f898ba4cf190f0de59d40890e2153724ec0770ebd033f9f6b88fadb96ab12408ad74af9eb63196a3cbefb79cbfaaa9409e69c232719d8b7f1e8043526d404713b46c55cbd0ce0773ad67810702f4832db7b705f61416914d0dcf4478a5497a22cd6b2ebf41be90d25be3d89664d521fa64eddc771eec1ae26a563ec1ed8787be683d6714a321064b2c2cc84bf9121cb4a70abf6ab1e861cd5a8682305b067d66939b4339d6e40b4616f2165f6684b55d99a1ddbf8c227620de493b15f1e3afc8d63cdc9c95a25a16e430f441984f544cfecbf91510c7e4429e609a7d2d9004e4a3c502f94f50acd783213756bf5efaec5c0a9ef62c490969b6f953ab10658e354673aad789bcce166d20bd92a6e67bec91dbe5cecf3f00638709591831ea10e8eaeb56e1822bff0e5c18b4efc162d4744f216186d100e10d47c7c76e0b40d85613af4f1829328720b7498f8247e60729ade17a95d2a1bfed3a5cd1324346f0e29d2dbef891255bcd9ac78ba955b759f70e16c2c209b77419225c3921372c2dbe054b72970971453caaa9c79715ab803e3c76d0ff5457c06b7115abe2801ae0f1cdcef696d7c1d921cc1747df76b4bd43a42827253d2d3628a94410e54a9aca7cb45287fb5fa59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 2,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b6173abf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "63673dbd03fa7e3715f3f24c0e51f098d2e597c0b4f810fec32b7aef6c5117d471dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"6304c349a700ee4d82e9224b717a608022cef5946a990160982ecebd0c059e4b"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb243a31f0c932536b5112606ac347e6426535439dfd97085122992714428bddf4acfb33cbdcd236eca6ac1a9408deaedde34af996953afd8f53ce64ecf03800fe08641d24ef8d514350e5288143e67a695544c7a3c595b591accd19e95ae9f61d958c262fb239908bc7a8adfe0081a73f097b62604fc88a5545450d0417422f448dc5db38a1a123b65d9f93be7c6ddb0824277c1c9eeda636131fdfb886be6dc703107106854aec29980a08bd6fff3c64b50b2dfc51029efe5423ceb6659b6c39b047d982dbec82470b185f3a786407ffc70d9a7644d645c959a0c87081a902cb4708557df80fa85727e1b33f3e8f6408f3a2e8c50ea6bd6cfedb63e038590e490820c59b84d2af3a18d9a3d3f72fdbd8e85ea6299d059a9de668d217a425a4110978a81d7fbb9a319815000973409b6fc43594492f760622344e43c3aecd24e7ce0b6f06db30ceace6ae533bc26a30a72963673dbd03fa7e3715f3f24c0e51f098d2e597c0b4f810fec32b7aef6c5117d4",
"786df5fbd48af59c6ebd72f5073e44db355324d7404a55af88db42014c86c96b6a98389396740aa59dcba842303093fbd75df9e808c44c225f003f6158fe6c135b636337d27e4f77dd00c2f0d4f977de99180f2f6d863362c8b68d34a51083a9730f6d6ac487ebc1a675bb4a52c8d85a252ca3f087f45c87ad4fb0f3a027585813cf9cfeb8931e8cc404753f74217bd9bfed69c3ace2e4b74198aff4e8c6f4ff90027e75c7a4b1ac56a93e6ad9c1d8eb728f59b2a6a588b6586725c938e9ce7c3823d18f5dfce79aa497896847dcdc45cd0c6a59b41efa6c50d829702c0ac928735e01c2cb0aed95b3ea8f2f12e36a76d9b3915202952e08f072f17290e2e4f52c707ca3584db05e770d3531760790e3e85e577c498cb3b2d72319a5a4662bcda4b8758271e28a9ce5ea098fa93083440a3b6003470f51cc379cfe00b936ed483d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9ec4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453aca9bd3d157744265792d62c28b03acbc90f0de59d40890e2153724ec0770ebd0a3406661b737de235f8a081825edc8ef3196a3cbefb79cbfaaa9409e69c23271a5cf143f1b4465d223fa96710e99c49dce0773ad67810702f4832db7b705f614e487ba631c50f9516286b11707abb62abe90d25be3d89664d521fa64eddc771e15a92f9ea6f82c7238cb46198eb2a85c21064b2c2cc84bf9121cb4a70abf6ab1ede10ec5fdf5aa87ae76531e47338501e40b4616f2165f6684b55d99a1ddbf8cc8ff6f0dc638dc847474e3ba2fa19cf9a25a16e430f441984f544cfecbf9151057d7761a4b1587ff58c8febac0102cab50acd783213756bf5efaec5c0a9ef62ca61afac8a263819efe8b614d5dbfc446bcce166d20bd92a6e67bec91dbe5cecfa091e06a6c13596ac6ca59e462168e8d2bff0e5c18b4efc162d4744f216186d1181058b82053d39960a615fbb77667a1328720b7498f8247e60729ade17a95d2841c98be0b7ce0ab7efecb4389f91c79255bcd9ac78ba955b759f70e16c2c2095e6c5f924318125e1be1ef12e8ce177271453caaa9c79715ab803e3c76d0ff54c0eb5aa70d81e35d87584a35805e0b5ac1d921cc1747df76b4bd43a42827253db11f65c05ba6d40e6ef499e021a82b9ea59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 99,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9ec4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "425a8a3ae789d69b017488dedbb82a68ac6842a5b559c13dc8f2dc3a910498c271dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"a599ddd280b18d0ecd163e3455eb8e21af0f3fbf6d3bb3abea8bcd79ef49101e"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb2428136953a0cfca756faacca5bde35bc935439dfd97085122992714428bddf4acda666deeb57203865b3cc3eb9b1a8fb94af996953afd8f53ce64ecf03800fe082fe986b68c59a1ea2b4737e7cfa95309d7261147a76708f04c4317bf3be087c6d389a1045f45b834628ef67329dcfa797b62604fc88a5545450d0417422f448dbdbb610bcb95bb6da9e8171feb33a1f8277c1c9eeda636131fdfb886be6dc70381600e21a00aafe3dea30a9600b550d90b2dfc51029efe5423ceb6659b6c39b0a3eb59ff071ed5af46af3bb4ac3ca0ea0d9a7644d645c959a0c87081a902cb47fe38286bbced83b591365c76c352c344a2e8c50ea6bd6cfedb63e038590e49083be2b8d8be9019c27c5b2e7fd44a7d545ea6299d059a9de668d217a425a41109b4a40ed351fa13d6c199ed63cba8118c34dc2a24512bd9126a63dc0aa825cc01e791fa2b71f450274f0c6f12c0ace057425a8a3ae789d69b017488dedbb82a68ac6842a5b559c13dc8f2dc3a910498c2",
"786df5fbd48af59c6ebd72f5073e44db4771ab4dd3cdf58a2b91e01ed688b0076a98389396740aa59dcba842303093fbf82a57d725883543b0de0f7e9a92bb3d5b636337d27e4f77dd00c2f0d4f977decd7b0d1b6920307662051d502cb0668b730f6d6ac487ebc1a675bb4a52c8d85adfc8309e623f301ad86eb880f8f29ce713cf9cfeb8931e8cc404753f74217bd9c70d41598370dfa7374356526b6e5c2b90027e75c7a4b1ac56a93e6ad9c1d8eb01a051165187036b84cbd7a23771e2583823d18f5dfce79aa497896847dcdc4571fa923599836cc821882834e4d42706735e01c2cb0aed95b3ea8f2f12e36a76e2cfe6df554f027a5bf0d43a5cf429a42c707ca3584db05e770d3531760790e3cc413a285dabd408506cbe1d00f78661a4b8758271e28a9ce5ea098fa9308344e2f38aee7d8d8e2805332e2c45baaca93d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9ec4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453aca9bd3d157744265792d62c28b03acbc90f0de59d40890e2153724ec0770ebd0a3406661b737de235f8a081825edc8ef3196a3cbefb79cbfaaa9409e69c23271a5cf143f1b4465d223fa96710e99c49dce0773ad67810702f4832db7b705f614e487ba631c50f9516286b11707abb62abe90d25be3d89664d521fa64eddc771e15a92f9ea6f82c7238cb46198eb2a85c21064b2c2cc84bf9121cb4a70abf6ab1ede10ec5fdf5aa87ae76531e47338501e40b4616f2165f6684b55d99a1ddbf8cc8ff6f0dc638dc847474e3ba2fa19cf9a25a16e430f441984f544cfecbf9151057d7761a4b1587ff58c8febac0102cab50acd783213756bf5efaec5c0a9ef62ca61afac8a263819efe8b614d5dbfc446bcce166d20bd92a6e67bec91dbe5cecfa091e06a6c13596ac6ca59e462168e8d2bff0e5c18b4efc162d4744f216186d1181058b82053d39960a615fbb77667a1328720b7498f8247e60729ade17a95d2841c98be0b7ce0ab7efecb4389f91c79255bcd9ac78ba955b759f70e16c2c2095e6c5f924318125e1be1ef12e8ce177271453caaa9c79715ab803e3c76d0ff54c0eb5aa70d81e35d87584a35805e0b5ac1d921cc1747df76b4bd43a42827253db11f65c05ba6d40e6ef499e021a82b9ea59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 99,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9ec4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "425a8a3ae789d69b017488dedbb82a68ac6842a5b559c13dc8f2dc3a910498c271dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"a599ddd280b18d0ecd163e3455eb8e21af0f3fbf6d3bb3abea8bcd79ef49101e"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb2428136953a0cfca756faacca5bde35bc935439dfd97085122992714428bddf4acda666deeb57203865b3cc3eb9b1a8fb94af996953afd8f53ce64ecf03800fe082fe986b68c59a1ea2b4737e7cfa95309d7261147a76708f04c4317bf3be087c6d389a1045f45b834628ef67329dcfa797b62604fc88a5545450d0417422f448dbdbb610bcb95bb6da9e8171feb33a1f8277c1c9eeda636131fdfb886be6dc70381600e21a00aafe3dea30a9600b550d90b2dfc51029efe5423ceb6659b6c39b0a3eb59ff071ed5af46af3bb4ac3ca0ea0d9a7644d645c959a0c87081a902cb47fe38286bbced83b591365c76c352c344a2e8c50ea6bd6cfedb63e038590e49083be2b8d8be9019c27c5b2e7fd44a7d545ea6299d059a9de668d217a425a41109b4a40ed351fa13d6c199ed63cba8118c34dc2a24512bd9126a63dc0aa825cc01e791fa2b71f450274f0c6f12c0ace057425a8a3ae789d69b017488dedbb82a68ac6842a5b559c13dc8f2dc3a910498c2",
"786df5fbd48af59c6ebd72f5073e44db4771ab4dd3cdf58a2b91e01ed688b0076a98389396740aa59dcba842303093fbf82a57d725883543b0de0f7e9a92bb3d5b636337d27e4f77dd00c2f0d4f977decd7b0d1b6920307662051d502cb0668b730f6d6ac487ebc1a675bb4a52c8d85adfc8309e623f301ad86eb880f8f29ce713cf9cfeb8931e8cc404753f74217bd9c70d41598370dfa7374356526b6e5c2b90027e75c7a4b1ac56a93e6ad9c1d8eb01a051165187036b84cbd7a23771e2583823d18f5dfce79aa497896847dcdc4571fa923599836cc821882834e4d42706735e01c2cb0aed95b3ea8f2f12e36a76e2cfe6df554f027a5bf0d43a5cf429a42c707ca3584db05e770d3531760790e3cc413a285dabd408506cbe1d00f78661a4b8758271e28a9ce5ea098fa9308344e2f38aee7d8d8e2805332e2c45baaca93d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79d27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453a29195ae5c4b8566630299f2f09d3acae90f0de59d40890e2153724ec0770ebd0cd0fdc1bd3b357df7cdd4da263fad8013196a3cbefb79cbfaaa9409e69c232713aa11dd505ff2d00b4fbe992a9a6ed2dce0773ad67810702f4832db7b705f614cefc1b25fcfc6ed8d1f218eaaae55682be90d25be3d89664d521fa64eddc771eca8b2bf60c7c7c4c4ed2ebda9f94064f21064b2c2cc84bf9121cb4a70abf6ab11e8b5519c993e7f5b2f1c0930dd3848be40b4616f2165f6684b55d99a1ddbf8c0f4edc05ab24338b51db2dac034e7877a25a16e430f441984f544cfecbf915108f2bd9dba91533223815c27528bd92c650acd783213756bf5efaec5c0a9ef62cf58b49f9b0510e6a1827e4ed01a077c6bcce166d20bd92a6e67bec91dbe5cecfe5957f60a873ddc42eafa132ce0597492bff0e5c18b4efc162d4744f216186d1f79afc4380972480ca082f722a86033b328720b7498f8247e60729ade17a95d2459b081560c2f889c31977e867720183255bcd9ac78ba955b759f70e16c2c209f6c7944f9bee73e86eca54f5ed23dfc771453caaa9c79715ab803e3c76d0ff54bd53d79140e1c013d9fcaca2a2791fe0c1d921cc1747df76b4bd43a42827253da7323fd6e1922617fae2b58ae28095d7a59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 17,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79d27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "eda4d42a8935a38c7cdb8647352281459d01f6aab30fb403690c9f73900475af71dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"7c71dc818f7109bbe2bdfbb36149e5309eafdc44e4c2fcfa1a6beb6c0fc46295"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb243101b0d1ad66788b00fdd9bf6373a9a835439dfd97085122992714428bddf4ac7f5992e2786ad4f513e32a965ba497bc4af996953afd8f53ce64ecf03800fe0821aef66add06a4b37d2d11ad705f3c70d7261147a76708f04c4317bf3be087c63ac00a1a3956b4bc513ee2ad026cd5967b62604fc88a5545450d0417422f448d56c40ef0e3dd76b472eebdb95a1d2864277c1c9eeda636131fdfb886be6dc703d0125750cc3b9fa02facca948b33ce510b2dfc51029efe5423ceb6659b6c39b04aae9630c288d01a478acb21b8a499a10d9a7644d645c959a0c87081a902cb47f9b90945074d8682d539af34a3638eb8ddfd5c56d793f0049a0500b68627b635ab7534f0c5dc74d778da8920d8585c945ea6299d059a9de668d217a425a41109c1221489b3243bff91b246d043e34e143594492f760622344e43c3aecd24e7ced90a1c732a0666768232c8bb17bafc50eda4d42a8935a38c7cdb8647352281459d01f6aab30fb403690c9f73900475af",
"786df5fbd48af59c6ebd72f5073e44db3e8364cfc53648759a3ed30430f962286a98389396740aa59dcba842303093fb533832e3629064d3f737a8d3da08b33a5b636337d27e4f77dd00c2f0d4f977dedbb69d6618732dad101f438a8bfa7d24730f6d6ac487ebc1a675bb4a52c8d85a7892c788882e3492e8becc461f63c2ca13cf9cfeb8931e8cc404753f74217bd92e0594746a2824616e3db0b7fb84d5bf90027e75c7a4b1ac56a93e6ad9c1d8ebb2ed08e7245613ae33c317a4acf264e03823d18f5dfce79aa497896847dcdc45ca375604df18715d21ad98c6d86c2e4f735e01c2cb0aed95b3ea8f2f12e36a763ae368f372e449aab40efacb7ef5e1e22c707ca3584db05e770d3531760790e35caebe10565f79f353ed627cfce8a721a4b8758271e28a9ce5ea098fa9308344c1c069f94e854765bbe9c0a3b5ee0df93d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841bf8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453a094d1aaf2a31cbe21d3be337d3884c5e90f0de59d40890e2153724ec0770ebd03504f09c05e9fc248e8ac7435bf1b6393196a3cbefb79cbfaaa9409e69c23271dc1a95bbff3e51dabf95b28b44fbd9d9ce0773ad67810702f4832db7b705f61440fe0ef21bc6c7abd738b1367935ecc1be90d25be3d89664d521fa64eddc771e924aa52736400eb7d975eb7b34d4a49a21064b2c2cc84bf9121cb4a70abf6ab1bed09119b7353fb6c5c0df97e811fdb6e40b4616f2165f6684b55d99a1ddbf8cb2664d8fbfe66bbd721993a14b9b62eea25a16e430f441984f544cfecbf91510007527a6079a19a85a1f286e9091a4da50acd783213756bf5efaec5c0a9ef62c4fb707ad7c56a9367e9a5f772f8634f3bcce166d20bd92a6e67bec91dbe5cecf4d42660aab49f2a5bfe0bba86a31c9a62bff0e5c18b4efc162d4744f216186d19a6feb1781ec9d1cd2f2d4c8e459a785328720b7498f8247e60729ade17a95d277d9dbd233e680468cf86a5c9b4ae855255bcd9ac78ba955b759f70e16c2c209ca3b4adf49aa1fb48fd6422977b5b00671453caaa9c79715ab803e3c76d0ff54cb90ecbbc6cd02e2378a305fa13b877ec1d921cc1747df76b4bd43a42827253d44175a392947b3eb44239d6605ca8972a59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 42,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841bf8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "672380b9931a90d218fd4fe4998c4b1dde8c0ec1ab2475c45ad28826da35704f71dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"03a1c43d879862b2cb17852768cc41ca0587031762003bfbb135fa8d16e8af39"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb2410c5621876d08eb892a5d1da49a9c8d135439dfd97085122992714428bddf4ac8aa7f6afa056ae27b88f3ed548fda28b4af996953afd8f53ce64ecf03800fe08f8f62b8db4fc2f27ea6349e8afeeabfa00637213c20df506e4489616d11fa8412d45b3b0ca21242817dadef80700f9187b62604fc88a5545450d0417422f448de3cd8627e01b22795461b8958788d060277c1c9eeda636131fdfb886be6dc7030fd8eeca74808211d3c1f0f23e58541d0b2dfc51029efe5423ceb6659b6c39b0f40c3344a8dfe02b6b9f6941e3dd99830d9a7644d645c959a0c87081a902cb479326b53a5a0c90a73982172c143ae103a2e8c50ea6bd6cfedb63e038590e490800ff0781c9d7c830e253418c938d70c65ea6299d059a9de668d217a425a4110953fcfe8cf1328b173073a030cfc5587e3594492f760622344e43c3aecd24e7ce4774e850fc672c335ccdaa51e729d843672380b9931a90d218fd4fe4998c4b1dde8c0ec1ab2475c45ad28826da35704f",
"786df5fbd48af59c6ebd72f5073e44db60bfb188fdcc3148ec95dbe949c343ff6a98389396740aa59dcba842303093fb48eacd153ba48aa1538b9494edafa76b5b636337d27e4f77dd00c2f0d4f977ded1e0a944e41ed78e8a3a93d267aa452e730f6d6ac487ebc1a675bb4a52c8d85a840d1ff2f662c4263f23d0fb19cf9e4813cf9cfeb8931e8cc404753f74217bd9a1fb1b3d6eea789c8ccab5dbce192dc390027e75c7a4b1ac56a93e6ad9c1d8eb7228716c7c11303dacadf145f9cdde143823d18f5dfce79aa497896847dcdc4520d9b9f0f8c1604cfd97faa6ad332e6d735e01c2cb0aed95b3ea8f2f12e36a764de25910b830f687b3a419850b0d0ce52c707ca3584db05e770d3531760790e30825eb7f5264259ace73ab1041b493efa4b8758271e28a9ce5ea098fa93083442fe77ef51077f74c1d2967432a0c048f3d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0cc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453a23be9bd9face09301a5f9041eb39d3a890f0de59d40890e2153724ec0770ebd064a6f54738141d08fc8fba50b47cab243196a3cbefb79cbfaaa9409e69c23271ebd37d229ff756a0137c9e5ad0c9afbece0773ad67810702f4832db7b705f614b7888583a64a26ab52e8ceb878cfe670be90d25be3d89664d521fa64eddc771ee7eb3eb526c37a46eadc09d14a5d6a3c21064b2c2cc84bf9121cb4a70abf6ab1f7245404b7b6a86754fc3a54cb837e4be40b4616f2165f6684b55d99a1ddbf8c07de6994cbe28b515a89943ecfcea75ea25a16e430f441984f544cfecbf91510e196d5e76438d67d00bf162f1323715b50acd783213756bf5efaec5c0a9ef62ce64af803906ea53295fd401872a4c8e1bcce166d20bd92a6e67bec91dbe5cecfa045faf95791d81d0b74d2a2e788eaa42bff0e5c18b4efc162d4744f216186d10a880f47f4f1cfd793ed98db58ca2369328720b7498f8247e60729ade17a95d2960dc6e88efb89ab30ac96e310a680a2255bcd9ac78ba955b759f70e16c2c2094f190984da07f4431ae945d81e63515071453caaa9c79715ab803e3c76d0ff54814dde94fa3626a821a4a8c0884aee9cc1d921cc1747df76b4bd43a42827253d1c68b9cc2c0af8ed9d2fed80d2a7c060a59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 0,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0cc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "4093c0e803c3522dfe7be1552784f1341d6ffeb7221e2652672a3c97271386d771dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"31a68cd5ce793eb2c7f99c3709b24dc8c4d3f7f90b69f6bd940ac45044292657"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb24a1f0df448a0cc7c3fcdbd1c5e0a5a31ba2e32f7c8656dade19fee5dd38f48a7b3f0b40f98d700748f61c75a2ef813f7f4af996953afd8f53ce64ecf03800fe08e402924a0b26b99190fbf629df6b992dd7261147a76708f04c4317bf3be087c61a7ab32d2d858d61e8ac9755ba9b27a47b62604fc88a5545450d0417422f448dd1dc05ea0a73503cc8a6b4f1cb93c57e277c1c9eeda636131fdfb886be6dc7032f162bbca88bac69ea143f676ae7417d0b2dfc51029efe5423ceb6659b6c39b08d76813b75b2ac442c669eedd5e022430d9a7644d645c959a0c87081a902cb4775e955ac79f05fb4ba073be132862657a2e8c50ea6bd6cfedb63e038590e490860274dda7b44aff047f2df202cdbd9f55ea6299d059a9de668d217a425a411097359f651984deae3b91bd5abff23a9a43594492f760622344e43c3aecd24e7ce5127df060aa1a7d73ac7512105fad21f4093c0e803c3522dfe7be1552784f1341d6ffeb7221e2652672a3c97271386d7",
"786df5fbd48af59c6ebd72f5073e44dbec951c589b1a4a817f14b7e83f92697f6a98389396740aa59dcba842303093fb938684cc4d8a318115fe5dc7462b0b785b636337d27e4f77dd00c2f0d4f977de18620287ea5318cffd505d0d1dee2067730f6d6ac487ebc1a675bb4a52c8d85a98d81e7594ff5aed5150179f673370bd13cf9cfeb8931e8cc404753f74217bd9b3ec9c7a43934ad91885b97f8a0e38a590027e75c7a4b1ac56a93e6ad9c1d8eb53ea347b480606e5785aa3d1cd3ef1b43823d18f5dfce79aa497896847dcdc45876f6bf92bef94333cd1c5faba30a5ad735e01c2cb0aed95b3ea8f2f12e36a766b1fb99e984c267b321ff6cfecc0c6912c707ca3584db05e770d3531760790e3a8fca526a0f73eda68d50c7ca8662ac0a4b8758271e28a9ce5ea098fa93083440f8a87306a5c9880938032c8f9adb3683d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0cc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453a23be9bd9face09301a5f9041eb39d3a890f0de59d40890e2153724ec0770ebd064a6f54738141d08fc8fba50b47cab243196a3cbefb79cbfaaa9409e69c23271ebd37d229ff756a0137c9e5ad0c9afbece0773ad67810702f4832db7b705f614b7888583a64a26ab52e8ceb878cfe670be90d25be3d89664d521fa64eddc771ee7eb3eb526c37a46eadc09d14a5d6a3c21064b2c2cc84bf9121cb4a70abf6ab1f7245404b7b6a86754fc3a54cb837e4be40b4616f2165f6684b55d99a1ddbf8c07de6994cbe28b515a89943ecfcea75ea25a16e430f441984f544cfecbf91510e196d5e76438d67d00bf162f1323715b50acd783213756bf5efaec5c0a9ef62ce64af803906ea53295fd401872a4c8e1bcce166d20bd92a6e67bec91dbe5cecfa045faf95791d81d0b74d2a2e788eaa42bff0e5c18b4efc162d4744f216186d10a880f47f4f1cfd793ed98db58ca2369328720b7498f8247e60729ade17a95d2960dc6e88efb89ab30ac96e310a680a2255bcd9ac78ba955b759f70e16c2c2094f190984da07f4431ae945d81e63515071453caaa9c79715ab803e3c76d0ff54814dde94fa3626a821a4a8c0884aee9cc1d921cc1747df76b4bd43a42827253d1c68b9cc2c0af8ed9d2fed80d2a7c060a59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 0,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0cc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "4093c0e803c3522dfe7be1552784f1341d6ffeb7221e2652672a3c97271386d771dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"31a68cd5ce793eb2c7f99c3709b24dc8c4d3f7f90b69f6bd940ac45044292657"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb24a1f0df448a0cc7c3fcdbd1c5e0a5a31ba2e32f7c8656dade19fee5dd38f48a7b3f0b40f98d700748f61c75a2ef813f7f4af996953afd8f53ce64ecf03800fe08e402924a0b26b99190fbf629df6b992dd7261147a76708f04c4317bf3be087c61a7ab32d2d858d61e8ac9755ba9b27a47b62604fc88a5545450d0417422f448dd1dc05ea0a73503cc8a6b4f1cb93c57e277c1c9eeda636131fdfb886be6dc7032f162bbca88bac69ea143f676ae7417d0b2dfc51029efe5423ceb6659b6c39b08d76813b75b2ac442c669eedd5e022430d9a7644d645c959a0c87081a902cb4775e955ac79f05fb4ba073be132862657a2e8c50ea6bd6cfedb63e038590e490860274dda7b44aff047f2df202cdbd9f55ea6299d059a9de668d217a425a411097359f651984deae3b91bd5abff23a9a43594492f760622344e43c3aecd24e7ce5127df060aa1a7d73ac7512105fad21f4093c0e803c3522dfe7be1552784f1341d6ffeb7221e2652672a3c97271386d7",
"786df5fbd48af59c6ebd72f5073e44dbec951c589b1a4a817f14b7e83f92697f6a98389396740aa59dcba842303093fb938684cc4d8a318115fe5dc7462b0b785b636337d27e4f77dd00c2f0d4f977de18620287ea5318cffd505d0d1dee2067730f6d6ac487ebc1a675bb4a52c8d85a98d81e7594ff5aed5150179f673370bd13cf9cfeb8931e8cc404753f74217bd9b3ec9c7a43934ad91885b97f8a0e38a590027e75c7a4b1ac56a93e6ad9c1d8eb53ea347b480606e5785aa3d1cd3ef1b43823d18f5dfce79aa497896847dcdc45876f6bf92bef94333cd1c5faba30a5ad735e01c2cb0aed95b3ea8f2f12e36a766b1fb99e984c267b321ff6cfecc0c6912c707ca3584db05e770d3531760790e3a8fca526a0f73eda68d50c7ca8662ac0a4b8758271e28a9ce5ea098fa93083440f8a87306a5c9880938032c8f9adb3683d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b2b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453ae23089c6aa925edb8867f0083c9ccddf90f0de59d40890e2153724ec0770ebd082b9a4bddc014d26d748f311df9237103196a3cbefb79cbfaaa9409e69c232711c6f0decfccf8a792e18470b8684c8e7ce0773ad67810702f4832db7b705f614927814c52d1972f6b6617e1ec4438c3dbe90d25be3d89664d521fa64eddc771eb9b1908dcf5162d4f3cf79fa62b509f821064b2c2cc84bf9121cb4a70abf6ab13a93a197aa6fe5bb256ed5f3e50eefe0e40b4616f2165f6684b55d99a1ddbf8ce263cb82515e7615aee17b397d2fb168a25a16e430f441984f544cfecbf91510f415e242b69db8e8b32affa75f1e4bda50acd783213756bf5efaec5c0a9ef62c0a761fa9be03de3d1807d11fc211b960bcce166d20bd92a6e67bec91dbe5cecf40a7e18896d9e2dcdb3c18af091056752bff0e5c18b4efc162d4744f216186d143b400c6dc262c4f4510212b4d2aea26328720b7498f8247e60729ade17a95d2b9c0a0838d027080b37d88f2450710cb255bcd9ac78ba955b759f70e16c2c209a2603332f5c8577c5c7e1ff47981425171453caaa9c79715ab803e3c76d0ff5472f4b029b9052d3f11e2cda20dec55a2c1d921cc1747df76b4bd43a42827253dea84ee0f9723706c3b9aec52b7b3e51ea59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 1,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0bc33b18788b18bcf18237224441fd12b2b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "d1ca14325b92d71e8e2a7e8973b69753bb7a87a81b57e6ad165fab2339f112bb71dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"7bd0469fe63a173abb4a71293172f539d3ecd367e57bd1f45c47dfa9d8d58e41"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb2437cc5fcb3034c39a3824b5843cad7f7535439dfd97085122992714428bddf4acd20af2a69c5c19684b28f0d62a2ad706b8992914294b1910333bbe8ce61694d7089e4c39d0c49638eef4e40f41e17aa6d7261147a76708f04c4317bf3be087c6e77cabfd1e9e8e680184e9663a4079837b62604fc88a5545450d0417422f448d750714ca8bb19b4084f308f2b6b7c4e6277c1c9eeda636131fdfb886be6dc703d955839b9653341c2248c8595b426b4a0b2dfc51029efe5423ceb6659b6c39b0df3acf3e9533ff4dfcb27455a7c8f5d80d9a7644d645c959a0c87081a902cb470aae9cc956f590af0812b3de21078658a2e8c50ea6bd6cfedb63e038590e4908f4a38f58ef802af6cc4e82c0dab3e14a5ea6299d059a9de668d217a425a411098d194f45272160fa438bbbcf4e8336dc3594492f760622344e43c3aecd24e7ce6b83871a3d3b0b192b12d9236b2a98c0d1ca14325b92d71e8e2a7e8973b69753bb7a87a81b57e6ad165fab2339f112bb",
"786df5fbd48af59c6ebd72f5073e44db38b8b4d54269fd656217f83f57bf8c5b6a98389396740aa59dcba842303093fb18316f7fb8800bb23cba4462e106d4a55b636337d27e4f77dd00c2f0d4f977def5c6479825b53a2884576f27bb783fee730f6d6ac487ebc1a675bb4a52c8d85acbd526a5a2e659e63879c58de78e1ede13cf9cfeb8931e8cc404753f74217bd90fc28e9ac254ffd45c38657f9fea383d90027e75c7a4b1ac56a93e6ad9c1d8eba9aadc9b5a3e7e3241271adfdce3c7e73823d18f5dfce79aa497896847dcdc4535ab1df60b6e422a6c84ef92e948d217735e01c2cb0aed95b3ea8f2f12e36a76d65a7281bb47f57fe4147ed2fd3f67902c707ca3584db05e770d3531760790e3138063a82cbbc3d4ff786adcf98d226ba4b8758271e28a9ce5ea098fa9308344f5c92e3ddb88226a09114ca4aa4e26313d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b6173abf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453aaeceb029c586cef7fa6829f898ba4cf190f0de59d40890e2153724ec0770ebd033f9f6b88fadb96ab12408ad74af9eb63196a3cbefb79cbfaaa9409e69c232719d8b7f1e8043526d404713b46c55cbd0ce0773ad67810702f4832db7b705f61416914d0dcf4478a5497a22cd6b2ebf41be90d25be3d89664d521fa64eddc771eec1ae26a563ec1ed8787be683d6714a321064b2c2cc84bf9121cb4a70abf6ab1e861cd5a8682305b067d66939b4339d6e40b4616f2165f6684b55d99a1ddbf8c227620de493b15f1e3afc8d63cdc9c95a25a16e430f441984f544cfecbf91510c7e4429e609a7d2d9004e4a3c502f94f50acd783213756bf5efaec5c0a9ef62c490969b6f953ab10658e354673aad789bcce166d20bd92a6e67bec91dbe5cecf3f00638709591831ea10e8eaeb56e1822bff0e5c18b4efc162d4744f216186d100e10d47c7c76e0b40d85613af4f1829328720b7498f8247e60729ade17a95d2a1bfed3a5cd1324346f0e29d2dbef891255bcd9ac78ba955b759f70e16c2c209b77419225c3921372c2dbe054b72970971453caaa9c79715ab803e3c76d0ff5457c06b7115abe2801ae0f1cdcef696d7c1d921cc1747df76b4bd43a42827253d2d3628a94410e54a9aca7cb45287fb5fa59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 2,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b6173abf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "63673dbd03fa7e3715f3f24c0e51f098d2e597c0b4f810fec32b7aef6c5117d471dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"6304c349a700ee4d82e9224b717a608022cef5946a990160982ecebd0c059e4b"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb243a31f0c932536b5112606ac347e6426535439dfd97085122992714428bddf4acfb33cbdcd236eca6ac1a9408deaedde34af996953afd8f53ce64ecf03800fe08641d24ef8d514350e5288143e67a695544c7a3c595b591accd19e95ae9f61d958c262fb239908bc7a8adfe0081a73f097b62604fc88a5545450d0417422f448dc5db38a1a123b65d9f93be7c6ddb0824277c1c9eeda636131fdfb886be6dc703107106854aec29980a08bd6fff3c64b50b2dfc51029efe5423ceb6659b6c39b047d982dbec82470b185f3a786407ffc70d9a7644d645c959a0c87081a902cb4708557df80fa85727e1b33f3e8f6408f3a2e8c50ea6bd6cfedb63e038590e490820c59b84d2af3a18d9a3d3f72fdbd8e85ea6299d059a9de668d217a425a4110978a81d7fbb9a319815000973409b6fc43594492f760622344e43c3aecd24e7ce0b6f06db30ceace6ae533bc26a30a72963673dbd03fa7e3715f3f24c0e51f098d2e597c0b4f810fec32b7aef6c5117d4",
"786df5fbd48af59c6ebd72f5073e44db355324d7404a55af88db42014c86c96b6a98389396740aa59dcba842303093fbd75df9e808c44c225f003f6158fe6c135b636337d27e4f77dd00c2f0d4f977de99180f2f6d863362c8b68d34a51083a9730f6d6ac487ebc1a675bb4a52c8d85a252ca3f087f45c87ad4fb0f3a027585813cf9cfeb8931e8cc404753f74217bd9bfed69c3ace2e4b74198aff4e8c6f4ff90027e75c7a4b1ac56a93e6ad9c1d8eb728f59b2a6a588b6586725c938e9ce7c3823d18f5dfce79aa497896847dcdc45cd0c6a59b41efa6c50d829702c0ac928735e01c2cb0aed95b3ea8f2f12e36a76d9b3915202952e08f072f17290e2e4f52c707ca3584db05e770d3531760790e3e85e577c498cb3b2d72319a5a4662bcda4b8758271e28a9ce5ea098fa93083440a3b6003470f51cc379cfe00b936ed483d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
},
{
"input_shares": [
"0cc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f6a3686b65d6720f6c32b87edea27c145661f2eb63d146a9d80dd939d0b683ca504ef6203303e952f986cc8eaa6d27038c4cf74166a023e40ff09f0c9ae70fde07652abad574a5930844a784fd0be1334dd92e5b8693172a63754f69724ee741ec20a10ac2cfdea1633dba667432f535ea0dd8157798b14f5c996d5308eb69d7ae8131a08b13bd4da4e799d7e9efdad1136f11f7335eae6c97bf095d691d50f73beac3cb0427c18477942a1405d46a0e9e1b84d2b292eeccbb9c876ebd752143b3bc3824e0049fb69a5793ef95bf4e3669ce030e20f8d2de894c0bd916b220d4d33f93146fe559b5d658daa9488e3ca3336d9a1648531df7a6ffc14c8e6ae371dbf8dbf1ef16af466d540bdcb8f286453a23be9bd9face09301a5f9041eb39d3a890f0de59d40890e2153724ec0770ebd064a6f54738141d08fc8fba50b47cab243196a3cbefb79cbfaaa9409e69c23271ebd37d229ff756a0137c9e5ad0c9afbece0773ad67810702f4832db7b705f614b7888583a64a26ab52e8ceb878cfe670be90d25be3d89664d521fa64eddc771ee7eb3eb526c37a46eadc09d14a5d6a3c21064b2c2cc84bf9121cb4a70abf6ab1f7245404b7b6a86754fc3a54cb837e4be40b4616f2165f6684b55d99a1ddbf8c07de6994cbe28b515a89943ecfcea75ea25a16e430f441984f544cfecbf91510e196d5e76438d67d00bf162f1323715b50acd783213756bf5efaec5c0a9ef62ce64af803906ea53295fd401872a4c8e1bcce166d20bd92a6e67bec91dbe5cecfa045faf95791d81d0b74d2a2e788eaa42bff0e5c18b4efc162d4744f216186d10a880f47f4f1cfd793ed98db58ca2369328720b7498f8247e60729ade17a95d2960dc6e88efb89ab30ac96e310a680a2255bcd9ac78ba955b759f70e16c2c2094f190984da07f4431ae945d81e63515071453caaa9c79715ab803e3c76d0ff54814dde94fa3626a821a4a8c0884aee9cc1d921cc1747df76b4bd43a42827253d1c68b9cc2c0af8ed9d2fed80d2a7c060a59b448600e4d85c6768efb63e8fb322404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 0,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0cc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbe47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682bda8d9fbc76142e840c39e5d0e75aec9f599a154654a23299de12fbe749d043d8ab71e9fce1c7810eda6704718ee09fb0b23587c6a2bc68ee9154fb24f5c50e27bd15540db0e05ed8cedffabe188c91d89ea7bd6628c0d1b571e1e31034b9a0cfba56cd36436c4a068d420d2891415f005644d6bfa87a915cb663d1a5b131847093fe19b68d3d2d2c30e7863da322f2fb33c4104824870e51602d9e755f4a962c4a182a46585953fce4a4d52a40a0f4246967d10b0e3f09e34ef09f116f7e7f79c27d3833081c1fe92d4d42d8e51712c36f77c9a5e7f993d5ee7c0a9ac81ea14f9c29bddd5181e3315fc8c631a69a7181f174ff3b5ca00aac4a9c25827a43b81f67f2c47c3a88fa550404efd3ccf2c820cfc82634f83fed60c684663cda2c9a39f2610acbe1849ac8c05874fc52e2c9b7c0250695fdf8bfee1304e2e696f6447911dba33c11a01293d2277d0b6086c1f55e66a9f615cf5738239a696362f75ee6453ce52ac6aad01874968a69ecb411ae91ec5db8c5cdfe2094cfd084bc580b7917896c78aad9a7a91cf5aaed94b7ebb18b105222e8503fc735b9c765ab624128aedef0007cebc81fc99e1549c4ba6db9b1dc46c81d72d4f1c5550ea4eaeb4eaac8f461e1dc080070f416ee16d90eb36d247eb0964dba7b02c1a6231fcb56cc845580b6602d67c4a07d0844cda3003f77375b185560fd65ddee20d65f7eeba83f13a08d8b711ff9dd185b799c89e5e2951677051bd0fa8647bc242336bb92ea9288e400ec3b13af16b65f84202b49ac5a070dba4fab66cd5bee4762cde7555733778c7695cbba76e97ff3f43a2e61841be8af5a261083230c88a9a901b39df2d599f5413a482fe2dc13e5f483a9a210797ebfb377e90442977f5cfe3aa80cab59ba7d3e5620c0ecc63904ed65bf5e99d5ad4cde8c9c81ad5e65daab6a8533574e23bee07890a857f59effb711afd9809a8c5e2663b06d9a785cbb0c6275131bc000162d3099a77c2980256cb13cee89e1f81a8a6f94be50612b1ace1b739d99395a540f0d655d0494572a05fe3d2b69baf19a0220c7274f6e508704b964b81fdfac176cef92e6f5d1ce60d371e07c94b3e226f6ac7882b0fe4511c91f27a30cd13a0f0919052606cce91cef2c133df87635889326b55e4a270d3df4b188984883319af129fde1131b3dc7b704529be81bcd629bc6fb231e45acb3cc5aa38d0ee7a52c38af3cdf1cb6425d68e65e2ae043f1a4a6d704295ade23fb4514a26f046dc8da51257006320ac48a926f516295e003f444753404dc61048963b6daa042f2cf1b546372ca7089725df94d089f9a9266397ab5e7834f50c8f0ea2708472cfa8371f7d7e9b56005dc6c4479ac70311f5036b9ade7ea92e80ff8b937ffb6e247439ffc3976a5e5150ffe40d67ed841977eb7f1d8c64bcffc7b92da226dba1af2397749d912033b71d34d8647b67ad1ae5fb39bfdeb80a7fe029ff34fe6575a82ab2d62b8c01aa838529b68ffb389e1e0ea7f0adec5b9c4c3c6fb3545297601a0fc9d38cdb5428b8d8d039793e4b2da042db8a97afc8ce4b9174c53e1e75ee64308692c8c5925abdd13d5968386ccad29efe97b3ce88541dd45002f44e44b0aa076c9d03bf0c0b4f51ccf49d5436fa87e1e7d7190eddc443653b0ef9ee02154346031e18e6f483580bf6419996e742412fccc33fa6213b1487200d9961b4436b8b3d12ada4f2d5d187f0251e39e51af90e340f18ce4076a078f7d55c03603d8724ccb1df9726ec4f518d477806010be1ec7d3ce27f71193696980525d55c8c873bc396c2b84db2902d75492564a6abe006eeef6861e9cf8a4adc58cb8827a3524fb2e2407c65b5f364383a706f1a9d67d95b97002ec6aa1f39352f64bf558c628cf26be19245cd4b4d1598f2f5d5636f38e8c1200676f5767567d44c9c990326ab9e4a2e16ecfa0bdf56e07e3b435e29b71a9c0b4b66c834ee81a50e9a4a3dfa6433967e99ecd35dcc527e11651abd3be0fb3181a39827cc50d574f818b892a743677b01abc4a65d60176ef6a08a772f4b0fbf6af702c473df2e859d4db02de7e7fd37bbb201ee3960cc7d291312b56cdd9016c37a1626b4d81047df30efb93b9dc4036cb976fd00490d1a53ba1f8684",
"f63cc4e78774e743f27cc8ddbbbe02ed504bbec050d5c8f9e10ebec5b39949e8c840bd33670b65c1e27b4e593cf1321243b814d37cbc763bae5018e0a281c2bb25df90507e86e0a1dcec5d194878e97d44572604389ebd17a33c61a2f18a51360c665eab9ab5dcd6461ed0418b62fbc27748e16031e387eff6588fb8e711f604f6dca78395d43971fae9b04db0a3af1d862eaabf24f1fa12571200541e7736e2781584299d73f2e48ce1e1cefcb465f3065a932c9bc93b5f7b2bdf2d76ebea0ffc9bb294057856ea1899c2e5a4ece7b8f8c01e64972c2d2d20f1879c25cdd0d04ec3befb7db78f1acdfd2618aa0b569d3d5e7d5b9a7a6ac015b5b2ad5bf5f0bdbb6982ef4f1c0f61af10f60ee908180865d82c7ccf7e3e01512b2bd271ae8ed3cb088365a18066c285183f56537e15eb083d64222ae7e1ccce03739ce59658e7e2e8b00c4a35ff551f563da7d85bc47e0b80d3b83c57705a93bfb102c330d37df5037d9cb07c0129d797b99c325d365c62d9ef5341e7b65357fa78b03ad1d36485fdaf96a020740102cfb1d196909bb870e245cc3ee5fed6a6dd882f49f793e0ac1995609ea30a8c61c65969c9d08a119dac31ad539552fe5cb697596134bee518e13a2473a3201ddab302f7b43a7f4870876938755265855230a55126b48144e94efaddd17afc0370a46389a549dbed771210fff831437ee7651eab63b4592466e23b937e28d2b0c7aaaf15b1514b155570b9e1e23f7ff8d4be911e926f14c92fb814f69b24584fb7e59dce034a9337bca7f499fd2983b5dc2f7bb325cffc088e8a4e7aa9f029a2051df29a0811457c10c5f72748ee0062127a48663761a1d6b0988fae42f0579b683dbdcc9446d156d971bff13c4ec50e789a07bdfd4b653a618f245b0549932a251b89d3218aaa8cca873896a34458914c00c0bc5d19e7be43750a5d9ef7cdcf1b75656fe4c620d2a860abec5b7d01d222c1a0b7c565def86a1404c8816fbbd66c0a301c557f354a66582c1a9df3f133806fb129a40a1662a72b32173637e52afda1554957acca8b1fc411f876f57a808a10048ee50267f6593a1d99c4f926585e344f39d8aece4301ff9d2cf665883d4bfda934ec311761e27e575906b41af9d14e531e48c6266c6c5abf0f29aa2fb69e8d5fa01c2d496452e65fddf38d8b09fef68fb469b47e02073e893106d190a2c719f2c8e1f836b4c3dd90953877d4f0ffade36e0d85cf32ee5f0f6e6fad9f93156e310d3ecc20789ea776cd94aa1b5d732c20b4e7767b77cee650ed6021eece3023848fbad6417e4529d643904dce1b8934c33a55c72f1187ad3c750c320e347fda29719a1d51fbc2e5b5928fbd6a5201c04baeb5d90fb925725aeda8ff9cdf37b756d90ae9d6a101c1bbb8acbfb239d3b769c49255fbd0d50e4ab9c8d358f74cda206b2f760656db9c6854a187cb0ad770f15d8f7b8d3059c8e0828164a9ff86393bb86538fcee0cfc9465218156d16300746c800491db8dc6003c6895a1ae93001bf298127be68a1480e2739b43001c46d25dd9245e50de688b626edfcc48c6cb279b849852e51c04c6402147f58003d600cb019a8a57d74d29d473fe557c5ed6497004c761e1f3580f5213a463b3a7904cabad689fe5f2362c7324abd7470b2fc686c1b4d25fbf247568503731b4528b3ac1e18a119bd1796d373a6da54212c2a697c793352d6301684c3177abe20faffd0bb1bb4f55fa9362fc40f3f4b092330b62abc90578201828e6f1223bbc7ec4f10611fdeabcbbfce1e7190b7ca7d809be666918bdbed2333cc059dec4eb5cdff2669e4bbc9476c2ed525b0d2a2e5c0fdae1c61ae506f3cbf0e731bf895f6b082aa3fc9fc278dd334e2068d913b09272b887f9fef41e1582c31d808ee6c94d67fada2aa37378c63c693d47b24d6fb68ab6da9b59541ffb1110979e1630759923a73477d85cadb24d1dbf839a4a0c7fc7c58f90e5629828a468ffd13955e0aacad09b40aa739d750d941e6dba32b496ea670d0a2a9c90c9173edff9890a896e982bb36366fcd95661b5d1e91305f404a91f81c4bca1d64ae563f4b49937cbf57d5af165b5c2059dcc698166132ca217ad81ee9ae542c42104ce7e5c67d833932a8b07e7476d58be9884fe543b59a283e891095f7588d0b6f0409508fd3b8c04d17a62b24fd2181a02c8444dfe11c6833382d6eced4a93246fe93c85e9d94b0befb820cf1046c4643bfc93468902ff9af2e5ac45e0797b"
],
"public_share": "4093c0e803c3522dfe7be1552784f1341d6ffeb7221e2652672a3c97271386d771dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"31a68cd5ce793eb2c7f99c3709b24dc8c4d3f7f90b69f6bd940ac45044292657"
],
"verifier_shares": [
[
"89920a042b750a6375428d0af8c1bb24a1f0df448a0cc7c3fcdbd1c5e0a5a31ba2e32f7c8656dade19fee5dd38f48a7b3f0b40f98d700748f61c75a2ef813f7f4af996953afd8f53ce64ecf03800fe08e402924a0b26b99190fbf629df6b992dd7261147a76708f04c4317bf3be087c61a7ab32d2d858d61e8ac9755ba9b27a47b62604fc88a5545450d0417422f448dd1dc05ea0a73503cc8a6b4f1cb93c57e277c1c9eeda636131fdfb886be6dc7032f162bbca88bac69ea143f676ae7417d0b2dfc51029efe5423ceb6659b6c39b08d76813b75b2ac442c669eedd5e022430d9a7644d645c959a0c87081a902cb4775e955ac79f05fb4ba073be132862657a2e8c50ea6bd6cfedb63e038590e490860274dda7b44aff047f2df202cdbd9f55ea6299d059a9de668d217a425a411097359f651984deae3b91bd5abff23a9a43594492f760622344e43c3aecd24e7ce5127df060aa1a7d73ac7512105fad21f4093c0e803c3522dfe7be1552784f1341d6ffeb7221e2652672a3c97271386d7",
"786df5fbd48af59c6ebd72f5073e44dbec951c589b1a4a817f14b7e83f92697f6a98389396740aa59dcba842303093fb938684cc4d8a318115fe5dc7462b0b785b636337d27e4f77dd00c2f0d4f977de18620287ea5318cffd505d0d1dee2067730f6d6ac487ebc1a675bb4a52c8d85a98d81e7594ff5aed5150179f673370bd13cf9cfeb8931e8cc404753f74217bd9b3ec9c7a43934ad91885b97f8a0e38a590027e75c7a4b1ac56a93e6ad9c1d8eb53ea347b480606e5785aa3d1cd3ef1b43823d18f5dfce79aa497896847dcdc45876f6bf92bef94333cd1c5faba30a5ad735e01c2cb0aed95b3ea8f2f12e36a766b1fb99e984c267b321ff6cfecc0c6912c707ca3584db05e770d3531760790e3a8fca526a0f73eda68d50c7ca8662ac0a4b8758271e28a9ce5ea098fa93083440f8a87306a5c9880938032c8f9adb3683d816a5bee828c5412acbef21b2bf9c7c571404479fef9a40f441ca601946db971dabf813c84a7a422fbb6cda351601f03531f144e40c5a71749a5b130344be3"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,50 @@
{
"agg_param": "",
"agg_result": null,
"agg_shares": [],
"chunk_length": 2,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 5,
"operations": [
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": false
}
],
"reports": [
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbf47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f62def334c7f96a411ac6fd7e371e8a12204f1d5fc39099668c05163af0920df13c5037c7ff445c426ca35ed34904b335bdee38b9cbf06b75b7ea6fd4eb53dd89ecec8c468354b53db7d539c3e68d0077be8cab0be8e919a82ec87649845dd584124ea5e3b4d3ce268621b4d1e9012f39c404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f212122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": null,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [],
"public_share": "0799017bb24c65181d958448ce8e2c173c91161c41b7326d6da095d8f479eae6c3737e95d95616ea9cb504757a00404a5fee380211a47e5e36439cc0f900f002",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [],
"verifier_shares": [
[
"95f58cb93c37a03b87a5655488fff748a72b008764dec4dd1a8987149133ea13729988943dbf1127bece72d0a4a845f73ca64899d9555250bf6832041c060884a45a8b68ccb4d1cd839a228c1695b75e2d2b22e95bb5757243b245c7ac002ed10799017bb24c65181d958448ce8e2c173c91161c41b7326d6da095d8f479eae6",
"6c0a7346c3c85fc45c5a9aab770008b79c14b4870653a2b060f31841e889dee9b4e1e4e0e2762540d693dd56469fa190bb1c237c761e00082b5844e67bc80732be7aac8058e28b453d3703df1ca61725b3ec4db86e1f19c224226005677ffcc1214e4922b47bfd5f47724e9a826a393f30fea54df1aff8969a08c9f729d06895"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,50 @@
{
"agg_param": "",
"agg_result": null,
"agg_shares": [],
"chunk_length": 2,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 5,
"operations": [
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": false
}
],
"reports": [
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbf47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f62def334c7f96a411ac6fd7e371e8a12204f1d5fc39099668c05163af0920df13c5037c7ff445c426ca35ed34904b335bdee38b9cbf06b75b7ea6fd4eb53dd89ecec8c468354b53db7d539c3e68d0077be8cab0be8e919a82ec87649845dd584124ea5e3b4d3ce268621b4d1e9012f39c414142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": null,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [],
"public_share": "0799017bb24c65181d958448ce8e2c173c91161c41b7326d6da095d8f479eae6c3737e95d95616ea9cb504757a00404a5fee380211a47e5e36439cc0f900f002",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [],
"verifier_shares": [
[
"95f58cb93c37a03b87a5655488fff7484988e1f082f326894eedc766ab8465a8729988943dbf1127bece72d0a4a845f7396c89926429e79e973f37b2bc4e26cea45a8b68ccb4d1cd839a228c1695b75e2d2b22e95bb5757243b245c7ac002ed11047ec76e4181660be6685b2f93dfb52b7184fead6081fc42e4bbba1ef6d3e84",
"6c0a7346c3c85fc45c5a9aab770008b760881a25ab1e89a3b0d87a4562deb9edb4e1e4e0e2762540d693dd56469fa190ff5890d597bfc0e363e0bda4a2acb243be7aac8058e28b453d3703df1ca61725b3ec4db86e1f19c224226005677ffcc1c3737e95d95616ea9cb504757a00404a5fee380211a47e5e36439cc0f900f002"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,50 @@
{
"agg_param": "",
"agg_result": null,
"agg_shares": [],
"chunk_length": 2,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 5,
"operations": [
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": false
}
],
"reports": [
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbf47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f62def334c7f96a411ac6fd7e371e8a12204f1d5fc39099668c05163af0920df13c5037c7ff445c426ca35ed34904b335bdee38b9cbf06b75b7ea6fd4eb53dd89ecec8c468354b53db7d539c3e68d0077be8cab0be8e919a82ec87649845dd584124ea5e3b4d3ce268621b4d1e9012f39c404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": null,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [],
"public_share": "0699017bb24c65181d958448ce8e2c173c91161c41b7326d6da095d8f479eae6c3737e95d95616ea9cb504757a00404a5fee380211a47e5e36439cc0f900f002",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [],
"verifier_shares": [
[
"95f58cb93c37a03b87a5655488fff748a72b008764dec4dd1a8987149133ea13729988943dbf1127bece72d0a4a845f73ca64899d9555250bf6832041c060884a45a8b68ccb4d1cd839a228c1695b75e2d2b22e95bb5757243b245c7ac002ed10799017bb24c65181d958448ce8e2c173c91161c41b7326d6da095d8f479eae6",
"6c0a7346c3c85fc45c5a9aab770008b7f9fdc112738bddd680a89728321d3a41b4e1e4e0e2762540d693dd56469fa19096eaa73be1ed264375b3054df7a84ecebe7aac8058e28b453d3703df1ca61725b3ec4db86e1f19c224226005677ffcc1c3737e95d95616ea9cb504757a00404a5fee380211a47e5e36439cc0f900f002"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,46 @@
{
"agg_param": "",
"agg_result": null,
"agg_shares": [],
"chunk_length": 2,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 5,
"operations": [
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": false
}
],
"reports": [
{
"input_shares": [
"0bc33b18788b18bcf18237224441fd12b1b4413faf2a370602f1413a4c66b61739bf42cc98f49a3e0184b1a6c30ecdedbf47eb2c834389c435afe71f5d7e3d44dc206faf81791f5e0713a2e6b7871682c31ff8ceb49d12b8725242e3ba03df8c83960dbbc545b556d9019e198b028f96e1ecab09b3f32995f1a77c63335af43584a9997fc045cacfc36314da79c0a9f62def334c7f96a411ac6fd7e371e8a12204f1d5fc39099668c05163af0920df13c5037c7ff445c426ca35ed34904b335bdee38b9cbf06b75b7ea6fd4eb53dd89ecec8c468354b53db7d539c3e68d0077be8cab0be8e919a82ec87649845dd584124ea5e3b4d3ce268621b4d1e9012f39c404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": null,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [],
"public_share": "0799017bb24c65181d958448ce8e2c173c91161c41b7326d6da095d8f479eae6c3737e95d95616ea9cb504757a00404a5fee380211a47e5e36439cc0f900f002",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"0000000000000000000000000000000000000000000000000000000000000000"
],
"verifier_shares": [
[
"95f58cb93c37a03b87a5655488fff748a72b008764dec4dd1a8987149133ea13729988943dbf1127bece72d0a4a845f73ca64899d9555250bf6832041c060884a45a8b68ccb4d1cd839a228c1695b75e2d2b22e95bb5757243b245c7ac002ed10799017bb24c65181d958448ce8e2c173c91161c41b7326d6da095d8f479eae6"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,256 @@
{
"agg_param": "",
"agg_result": [
256,
257,
258,
259,
260,
261,
262,
263,
264,
265
],
"agg_shares": [
"cebb3e866894424c6e27640c703bd8a4ce48071536afcc0f84b6167551013066cdc5fc5a2de542e693bee262a74cbe59178be6d6d2dcf77210023bc3dc5906576009764c8559bdb204215f1683485b41d4e8ceb1b495877a958cd52dfb0478d69b3f39f22380b722fed73fe56d91f37753a4cd65e1f6a897d365198f80e996b28814b6d8c6dd1de31650fb686e2b787212020b3f5b45bb4b5cf402cee6a956c3",
"3345c179976bbdb375d89bf38fc4275b34b8f8eac95033f05f49e98aaefecf99363b03a5d21abd1950411d9d58b341a6ed7519292d23088dd3fdc43c23a6f9a8a5f789b37aa6424ddfdea0e97cb7a4be3218314e4b6a78854e732ad204fb87296cc1c60ddc7f48dde527c01a926e0c88b55c329a1e095768109ae6707f16694d81ec49273922e21ccdaf049791d4878df8fef4c0a4ba44b4870bfd311956a93c"
],
"chunk_length": 9,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 10,
"max_measurement": 255,
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 1,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 2,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 2,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"9348d89d1ef86196ec81d653ef6b135792fcd108a6a98e3afae8ac31069e2c8b93d50c83315d5776ee0ec16144bf895374eca561d92096a03bb74783ae3ba173f263056265dc11a16933f6bde71e3992036aa81772eccdf31f1aba7608ac8a1f672581f117bab882cece9f47a95c163a7e67dccd1ffd42ef1a7f6f3944ad874e3072385a2e0b68a55e0608c2ecadb4dc0608973760c1873104aa6c501e63564b116c04a3501d3639081b2fa6d7dd290b56b3dc3ad4deedf16e9e820588f40012a0fe7360b9a09a24aec8ba186db576e92e1ecf23026855e10624f968fbe5f191bd75de31fcff23cc3318053c44feee6f581c19051607c1a01b2651b5922f4102c76784317a4d3749d1bb0cc7c5c4917ad92f69b45f6bf15de0babac42e9e7732d2b6376557c23a0ab83440cacfa92e0a9fc1f730f92a849403665853539f8752a8e0bcc4b026c89afa79848004c44e85ee9d13e82833a940674ca40938ff04fdfc97d69bf69a608e821b8b21c27c092b419cf1667240ecf432852fd29261e8a45f49cf6da3976e0a2b31e3f7526a226882bd0a98ce097a0caecf31673d8292ba3ebcc7d200f3a794fd1a72995f8f42d3b3b7dfaaddbddcba7f3fe51e24fa184bd6005c7b372be65bb13ee80b30a6ee2e1dba09de0365536542a5ea0acd3ba8e661f1e2f83f0aaef91dc66e0e24daa428cf845af1fe855f9d9da0ccc27580594534ec9f4ba458e2b10ba20637e1878e702f876a20e49d1a69167ec39bb30a6d78258c4656f15d708053f87e874435e5376ed2aa6e46f06aac295668fff565c9a93996aa21d08b1fa58ccbf67cfab75e3970bbb8ee975b4f86e055fd1029faa8927bd73aae0b9c70e0f57796107945f9f329eb26b763b134fa5891807bfb9d8f7cd9dbd5600b3f41225456e223ca9511e00d137165c1cc86b1787770274b2d890ebdc8b5348256f4503ad7539af303780a551514ccb282dcd734a9eb19d1bbdfe2bbde114e96ae8f1f2338bf18f3f2d054f731ec595a393a2cafd2240feea5523c08c1a5b540bbc738dac59a173ab0a9ab7901a862b49a32d518856e45a4013ad5545eb9ad187cda61c29c46004c316e6bf95b24d1d5ce110f041332dbb83f03d8fee0fd748d23c484350d67444997a15eb4d7a35200ceb10b066ea2fdf70083114b8f69328c8357436e433924fa3f17d58ced6c6d4c3b0ff8ea980018b6156be5fabc198f09bd565137067f4763b1824c5c544fb506cd1b4be9a33c401776772a4d7432f086c5a96845dff7111e4c2c5e000c40ab6d78ab3ebcf85da80708c66845a5f53deeae967695f57e0578d8a92a7ce95664f2823104db6494631380be8fe801172aab96b07a0d8e95e840ccca107809a0b52b1988f700d26315f5edb57c018027787e34c8fe3f667f673f96c970f8bac2aa316e5aa3276709994e72c5b0a1b68238b2f734095f242840cc43d451219913719512f5b5ebb1ede096a912104403ed5f97e19f524719d8fbb72ab13720b08dd8778b94cfe52d2e0cdcabc320df81646a913cd3c57ba50240ab074e614a6b7fc00b4abcb13fac5acee6f19385b8da9a42cef9e9358f30e8567854cd6eb6b4c3fdee16ab22fe3995383031a9cc0620b84916f4311c957278d77b87ee08c8eda83385e3523c7f439d70c0030f8124c29304f75ae5f5f00fb7c71510964dd9947ecedcc099dddbe4f14537ae07f9eb3e39ed0e5ab2c97a0134c8aea6c85b42f54511379e6a03f73315a6e562f4d6ac0f5095b9438eeb3f9577ef4de5f175531470b4d0f1a77b9b8233eeb87feabe0f1cc93a0615494646bb22d2e22db256ca8ae9740c5b02ee2a5f5a37d947eaec2d804dcdd2f199a15c4f69e2e9fa433a3c997343c3615b72bd13de7300c511dae4a9cf8245f1a3150e8f6754becd21d3ccff4e5cfb10e563aa7fd49b205799d0032fcda0252d848bef3dc521f1947791bb96e8fd0c95f54f128de095a4f7a705c3460d94879f4acbdb89d68e621f4f5594bbd71a2f18112b6aa55b13f29b5a64a0871ab041f1038ffdf4f3b70cff896f1a6f35a6ef5e9bdd39980e7b93eb1ef8e1af8b2becee2878ec85a0ba05120bb15b5f5f224d777c98263a238fbb8b3aed66415a4c1d6ae3402a821793e65968b1fbb0ec02b8bbfe34c9fc954451f14678fb3b5d4e4e134477e142cc7101366171bb0ecb3f2ff3783100b54be4ea35a0fc0faf890c134779a4dfdf6409630c096aedffca5e5588bf792ce976f06d6937385c245cdc8757e33a676e24ccca62261f9377f59727c5d0a7289adb30110844dd57244c51f5005803b258805f08ccb380dba7568bf4b140f9a40da87b2a2ad9ecc13d276adffa44407574b5ad2ea31a9d06226cf55dc1bd4d6b19c2d6196ac8f32a002f582e58013630c85e1323491d487c62beb9501c2771f5a53c38811bf56de099121ea4639ab6d35aea652cfcb40aeaf501775fc813255f1ead914ac4929e10832c89c5ecf593923cc125c48bd5983e4f88d278e7e00be2d2dfe26f6255b32a2ddc4be543350fcfa99ac61c73e19d658f60e097b81fbabe3d6f1e399f63500e2dd9da979d9debdea1ac78f69852d086569d6dd0d3e13b144c951e01f120abddb735a33d682c648d8c2862de1343a4ae89fb61b183cba2bdcc5f4b73ccfeb5440176e21c758bae61e091b3db0bde5acc5cf026e7b1010b65a74bcc844a4f6039697dca70b24f9d3ead917e1fb20a17aacc7955f149059394800efe28f6c7b7edbaed2155ba289629c540a607e2b1fb18595c438e8fb6aad7cbe4a16d63ddfb890f9ab95b2c7eef7c227ff1e35ad9c86808650029e0ad6026c8f47126f3c550cffe1b286b35d5c6dbb5ecd0dd8c4eb0f1998b7efaa80540b6c2cfe726343f8fb7a9ca9b7a9593c6500e6fdddca6d69a404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9
],
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"9a93bf2c783116c4240dccae7abef236f017adb1bc8f995a81e75c7c70001022f196a973644c16a21eeaa0cb37c494c85f83f79c9b49fdd05aab1341f41d021dce02d26e2c73943b4460ca5cd6c273c0f5f7443b3c8782d37dd9f1b953acd29c386a68fb0b80920bf64715f77930517d7636ef214b5238dde721b32f80f8dc908806929d97f409a10770fe227a0e2826b755aebf736c3e19c0a6ab44a2387296",
"676c40d387cee93bbff2335185410dc912e8524e437066a56218a3838fffefdd1269568c9bb3e95dc5155f34c83b6b37a57c086364b6022f8954ecbe0be2fde237fd2d91d38c6bc49f9f35a3293d8c3f1108bbc4c3787d2c66260e46ac532d63cf959704f47f6df4edb7ea0886cfae8292c910deb4adc722fcdd4cd07f07236f81f96d62680bf65edc8f01dd85f1d7d953aa51408c93c1e6235954bb5dc78d69"
],
"public_share": "b114abce23f5c7f9f770c3e4f2da2d19f8b1bfd39e768a4894e9443a471c05b25a1575e899105fa4b58696a8d2689885fccbeca678b81f9448dea9613066182e",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"dff45f49c28b7627a22d3456a0f974c0d7b6470b90cf7878bedb42f007363748"
],
"verifier_shares": [
[
"9fb52861af45115ed073d41907c3133bd723592655f9967b4c4b35edf14976b1a3cf201f5885f5146e784c6cc94590eb341b983d9234fcf00487b6f80860dd201a5e5de9a2a5d3698f1afd01f6028a91427326f9902fd91c9a9407ef41f0a1f6bbdc2dc82bef482cc0cb1e4f29afe2d9b539d4f79f8e978be7e03fea569d38ff25c29d5e79b7aab68fc1a586a398808dfdb80c5523e1f3d9c7c7c2004d24dd199cd27085297c83a649eca969a056a74dcfde2c3d08d5e61b7e94de50de6bf55c7f835cd874376405bbbabddf6db881a1acbb58d77348cbe53b60b5f4f2913156282fd5f6a88d3270bd10ee9e7e92a01d5bb24b603b5c2c63276deadec29bf8d48198716a87e01c078b12fcb6e6090b5af30e05bbaa22c74755fda4a1c54c7d077b9452d160a63fbcc15847d604da30c04a8078db89ce1b2ef3cbd118c76d12b4b114abce23f5c7f9f770c3e4f2da2d19f8b1bfd39e768a4894e9443a471c05b2",
"624ad79e50baeea1138c2be6f83cecc4d4a260f57e2f40f2c2c08cca60ddf652eef7b0eb2c007a85016c96b17559f96d4aa6dc012e45be6b492006c8dda2bdfcabf84b78cc66ed2c5db7a6e028bacca335957f44c1d5d6e55e2a7a03570dd1c9e8e721da7294ba5e8f42b05e904d325a014b3e4eaa41bddacc31fe257da020c5345e88ae5d3d3b8a38a974de635d526e6fa956cb06537343172539a7e57fc156bc8498768762002c3a7543eb4abce19bc0bc16096f068e3c2e9461dfd6940ce77633525b2287524d63748f090b29cd7fe85717519905410484298459211e62ac9403e74487b36502085b8897b356ad24a8da885f15dd78d1e364b654103b1112c9dcda9de679a81d8ff11d31ea69630a5db94d306b1c9af29cd9ae88b1ad90399deff43fae5ee1c45211e41a41564c10d214db4aa8fd47b6ebe86eed81f691555a1575e899105fa4b58696a8d2689885fccbeca678b81f9448dea9613066182e"
]
]
},
{
"input_shares": [
"9448d89d1ef86196ec81d653ef6b135792fcd108a6a98e3afae8ac31069e2c8b93d50c83315d5776ee0ec16144bf895374eca561d92096a03bb74783ae3ba173f263056265dc11a16933f6bde71e3992036aa81772eccdf31f1aba7608ac8a1f672581f117bab882cece9f47a95c163a7e67dccd1ffd42ef1a7f6f3944ad874e3072385a2e0b68a55e0608c2ecadb4dc0608973760c1873104aa6c501e63564b116c04a3501d3639081b2fa6d7dd290b56b3dc3ad4deedf16e9e820588f40012a0fe7360b9a09a24aec8ba186db576e92e1ecf23026855e10624f968fbe5f191bd75de31fcff23cc3318053c44feee6f581c19051607c1a01b2651b5922f4102c86784317a4d3749d1bb0cc7c5c4917ad82f69b45f6bf15de0babac42e9e7732d2b6376557c23a0ab83440cacfa92e0a9fc1f730f92a849403665853539f8752a8e0bcc4b026c89afa79848004c44e85ee9d13e82833a940674ca40938ff04fdfc97d69bf69a608e821b8b21c27c092b419cf1667240ecf432852fd29261e8a45f49cf6da3976e0a2b31e3f7526a226881bd0a98ce097a0caecf31673d8292ba3ebcc7d200f3a794fd1a72995f8f42d3b3b7dfaaddbddcba7f3fe51e24fa184bd6005c7b372be65bb13ee80b30a6ee2e1dba09de0365536542a5ea0acd3ba8e661f1e2f83f0aaef91dc66e0e24daa428cf845af1fe855f9d9da0ccc27580594535ec9f4ba458e2b10ba20637e1878e702f876a20e49d1a69167ec39bb30a6d78248c4656f15d708053f87e874435e5376ed2aa6e46f06aac295668fff565c9a93996aa21d08b1fa58ccbf67cfab75e3970bbb8ee975b4f86e055fd1029faa8927bd73aae0b9c70e0f57796107945f9f329eb26b763b134fa5891807bfb9d8f7cd9dbd5600b3f41225456e223ca9511e00d137165c1cc86b1787770274b2d890ebcc8b5348256f4503ad7539af303780a551514ccb282dcd734a9eb19d1bbdfe2bbde114e96ae8f1f2338bf18f3f2d054f731ec595a393a2cafd2240feea5523c08c1a5b540bbc738dac59a173ab0a9ab7901a862b49a32d518856e45a4013ad5555eb9ad187cda61c29c46004c316e6bf85b24d1d5ce110f041332dbb83f03d8fde0fd748d23c484350d67444997a15eb4d7a35200ceb10b066ea2fdf70083114b8f69328c8357436e433924fa3f17d58ced6c6d4c3b0ff8ea980018b6156be5fabc198f09bd565137067f4763b1824c5c544fb506cd1b4be9a33c401776772a4d7432f086c5a96845dff7111e4c2c5eff0b40ab6d78ab3ebcf85da80708c66844a5f53deeae967695f57e0578d8a92a7ce95664f2823104db6494631380be8fe801172aab96b07a0d8e95e840ccca107809a0b52b1988f700d26315f5edb57c018027787e34c8fe3f667f673f96c970f8bac2aa316e5aa3276709994e72c5b0a2b68238b2f734095f242840cc43d451219913719512f5b5ebb1ede096a912104403ed5f97e19f524719d8fbb72ab1371fb08dd8778b94cfe52d2e0cdcabc320df81646a913cd3c57ba50240ab074e614a6b7fc00b4abcb13fac5acee6f19385b8da9a42cef9e9358f30e8567854cd6eb6b4c3fdee16ab22fe3995383031a9cc0620b84916f4311c957278d77b87ee08c8eda83385e3523c7f439d70c0030f8124c29304f75ae5f5f00fb7c71510964dd8947ecedcc099dddbe4f14537ae07f9eb3e39ed0e5ab2c97a0134c8aea6c85b42f54511379e6a03f73315a6e562f4d6ac0f5095b9438eeb3f9577ef4de5f175531470b4d0f1a77b9b8233eeb87feabe0f1cc93a0615494646bb22d2e22db256ca8ae9740c5b02ee2a5f5a37d947eaec2d804dcdd2f199a15c4f69e2e9fa433a3c997343c3615b72bd13de7300c511dae4a9cf8245f1a3150e8f6754becd21d3ccff4e5cfb10e563aa7fd49b205799d0032fcda0252d848bef3dc521f1947791bb96e8fd0c95f54f128de095a4f7a705c3460d94879f4acbdb89d68e621f4f5594bbd71a2f18112b6aa55b13f29b5a64a0871ab041f1038ffdf4f3b70cff896f1a6f35a6ef5e9bdd39980e7b93eb1ef8e1af8b2becee2878ec85a0ba05120bb15b5f5f224d777c98263a238fbb8b3aed66415a4c1d6ae3402a821793e65968b1fbb0ec02b8bbfe34c9fc954451f14678fb3b5d4e4e134477e142cc7101366171bb0ecb3f2ff3783100b54be4ea35a0fc0faf890c134779a4dfdf6409630c096a97a6197087d67f439d0fa0b57cb74e755c245cdc8757e33a676e24ccca62261f54b98698081bed338a2ed800c2dfeeac57244c51f5005803b258805f08ccb38069cccb88ac013f8e48d6fd5b7380ffb5c13d276adffa44407574b5ad2ea31a9dccbe3b6abe0fe3017778afa4f212f8102a002f582e58013630c85e1323491d4888f2e5ec8826cf3380168d1dc1d0fe44e099121ea4639ab6d35aea652cfcb40a5442fbbc914c8d54dac74d40f1947bfd10832c89c5ecf593923cc125c48bd598c9938f8f63b1a95236dbbcc5f3555c652a2ddc4be543350fcfa99ac61c73e19d6bf7422b4ca3a427cc816f8af8e885a40e2dd9da979d9debdea1ac78f69852d04fc874e792397fffb6906388a9b06cf3ddb735a33d682c648d8c2862de1343a41c600e83ce2c7a9b169acb83991b7a0c440176e21c758bae61e091b3db0bde5a2de7658e857dafc45d768f6be2e71bd839697dca70b24f9d3ead917e1fb20a174ec68266a215bcfd9d47d127b7d910dfedbaed2155ba289629c540a607e2b1fb0f826676ff3bc7745eb66ca3bc4bcbac890f9ab95b2c7eef7c227ff1e35ad9c8c91c84b373298a0898f2ccc2d7095f12cffe1b286b35d5c6dbb5ecd0dd8c4eb0ff471010ba27ec4fdfdcb444bdbcdc88b7a9ca9b7a9593c6500e6fdddca6d69a404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"9b93bf2c783116c4240dccae7abef236f017adb1bc8f995a81e75c7c70001022f096a973644c16a21eeaa0cb37c494c85d83f79c9b49fdd05aab1341f41d021dcb02d26e2c73943b4460ca5cd6c273c0f1f7443b3c8782d37dd9f1b953acd29c336a68fb0b80920bf64715f77930517d7036ef214b5238dde721b32f80f8dc908106929d97f409a10770fe227a0e2826af55aebf736c3e19c0a6ab44a2387296",
"676c40d387cee93bbff2335185410dc912e8524e437066a56218a3838fffefdd1269568c9bb3e95dc5155f34c83b6b37a57c086364b6022f8954ecbe0be2fde237fd2d91d38c6bc49f9f35a3293d8c3f1108bbc4c3787d2c66260e46ac532d63cf959704f47f6df4edb7ea0886cfae8292c910deb4adc722fcdd4cd07f07236f81f96d62680bf65edc8f01dd85f1d7d953aa51408c93c1e6235954bb5dc78d69"
],
"public_share": "7fdfdfa378124b9ebe78100226ef5a66ec2fd5a9ef2f0a23a82fd1c8b9a758855a1575e899105fa4b58696a8d2689885fccbeca678b81f9448dea9613066182e",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"7d861395cb43eeeb626c6423898b9697537812f47991757a1bf0b1edb750e81b"
],
"verifier_shares": [
[
"9fb52861af45115ed073d41907c3133b852b7a572aa6645362ee0272edb59cb39416abe7cba678029042f372de1d573983abcd781432cbe4cf93c1608d6d2286b92ca8073290c97a3633b7e50da3fcc8c39feafda30a0306ef60bcc526bdba1ebbdc2dc82bef482cc0cb1e4f29afe2d9ac060f99702057057aa4b3c49250501307c54c73d8fa36a393e87e5adbba0e7935b975ca37cc89220827ce5e5f61467eafc8841e41f7ccb16afd076ea64a16fe399f1157f3388cd49936fd6b382a32919a781cdfe54ca374ba2fe3c00f5526c2df27b5aac85bf5035e7ea79af3f75ce2e22c9aa9e5b986d4ec7f5278f493c3e710f1d70c12939e386ebc08e6151fde8c81f49e82d330b7256bbeed2498fcf00582834b11ab02efe089b7545f09ae9b43a03cf0b365bff4e50540836aebe6569accfef8961a769c833c3a9fc8a8b25da07fdfdfa378124b9ebe78100226ef5a66ec2fd5a9ef2f0a23a82fd1c8b9a75885",
"624ad79e50baeea1138c2be6f83cecc42cce02b22fac7924b48c912aa1f3b602eef7b0eb2c007a85016c96b17559f96d7da8957a4bc34c0904f9fb69d273dbb0abf84b78cc66ed2c5db7a6e028bacca3c6c887551b5f589eb5b1bbc0f07b6281e8e721da7294ba5e8f42b05e904d325a226c47e6970ddffce332deb74efedc61345e88ae5d3d3b8a38a974de635d526e23f836e8d6519a88751dbd94dac9de10bc8498768762002c3a7543eb4abce19bd0e7790b564df57bacb943385d7a7e787633525b2287524d63748f090b29cd7f70c73597a024b1688b6b765c6af6e6419403e74487b36502085b8897b356ad249651d3094b54a16622b25c6d374c16eac9dcda9de679a81d8ff11d31ea69630afd7196d51b25991a6ba55375f93eb8fe9deff43fae5ee1c45211e41a41564c10d214db4aa8fd47b6ebe86eed81f691555a1575e899105fa4b58696a8d2689885fccbeca678b81f9448dea9613066182e"
]
]
},
{
"input_shares": [
"9448d89d1ef86196ec81d653ef6b135793fcd108a6a98e3afae8ac31069e2c8b94d50c83315d5776ee0ec16144bf895375eca561d92096a03bb74783ae3ba173f363056265dc11a16933f6bde71e3992046aa81772eccdf31f1aba7608ac8a1f682581f117bab882cece9f47a95c163a7f67dccd1ffd42ef1a7f6f3944ad874e3072385a2e0b68a55e0608c2ecadb4dc0708973760c1873104aa6c501e63564b126c04a3501d3639081b2fa6d7dd290b57b3dc3ad4deedf16e9e820588f40012a1fe7360b9a09a24aec8ba186db576e92f1ecf23026855e10624f968fbe5f191be75de31fcff23cc3318053c44feee6f591c19051607c1a01b2651b5922f4102c86784317a4d3749d1bb0cc7c5c4917ad92f69b45f6bf15de0babac42e9e7732d3b6376557c23a0ab83440cacfa92e0aa0c1f730f92a849403665853539f8752a9e0bcc4b026c89afa79848004c44e85ef9d13e82833a940674ca40938ff04fdfd97d69bf69a608e821b8b21c27c092b429cf1667240ecf432852fd29261e8a45f49cf6da3976e0a2b31e3f7526a226882bd0a98ce097a0caecf31673d8292ba3fbcc7d200f3a794fd1a72995f8f42d3b4b7dfaaddbddcba7f3fe51e24fa184bd7005c7b372be65bb13ee80b30a6ee2e1eba09de0365536542a5ea0acd3ba8e662f1e2f83f0aaef91dc66e0e24daa428d0845af1fe855f9d9da0ccc27580594535ec9f4ba458e2b10ba20637e1878e7030876a20e49d1a69167ec39bb30a6d78258c4656f15d708053f87e874435e5376fd2aa6e46f06aac295668fff565c9a93a96aa21d08b1fa58ccbf67cfab75e3971bbb8ee975b4f86e055fd1029faa8927cd73aae0b9c70e0f57796107945f9f32aeb26b763b134fa5891807bfb9d8f7cd9dbd5600b3f41225456e223ca9511e00e137165c1cc86b1787770274b2d890ebdc8b5348256f4503ad7539af303780a561514ccb282dcd734a9eb19d1bbdfe2bcde114e96ae8f1f2338bf18f3f2d054f831ec595a393a2cafd2240feea5523c09c1a5b540bbc738dac59a173ab0a9ab7a01a862b49a32d518856e45a4013ad5555eb9ad187cda61c29c46004c316e6bf95b24d1d5ce110f041332dbb83f03d8fee0fd748d23c484350d67444997a15eb5d7a35200ceb10b066ea2fdf70083114c8f69328c8357436e433924fa3f17d58ded6c6d4c3b0ff8ea980018b6156be5fbbc198f09bd565137067f4763b1824c5d544fb506cd1b4be9a33c401776772a4d7432f086c5a96845dff7111e4c2c5e000c40ab6d78ab3ebcf85da80708c66845a5f53deeae967695f57e0578d8a92a7de95664f2823104db6494631380be8fe901172aab96b07a0d8e95e840ccca107909a0b52b1988f700d26315f5edb57c028027787e34c8fe3f667f673f96c970f9bac2aa316e5aa3276709994e72c5b0a2b68238b2f734095f242840cc43d451229913719512f5b5ebb1ede096a912104503ed5f97e19f524719d8fbb72ab13720b08dd8778b94cfe52d2e0cdcabc320e081646a913cd3c57ba50240ab074e614b6b7fc00b4abcb13fac5acee6f19385b9da9a42cef9e9358f30e8567854cd6eb7b4c3fdee16ab22fe3995383031a9cc0620b84916f4311c957278d77b87ee08c9eda83385e3523c7f439d70c0030f8125c29304f75ae5f5f00fb7c71510964dd9947ecedcc099dddbe4f14537ae07f9ec3e39ed0e5ab2c97a0134c8aea6c85b43f54511379e6a03f73315a6e562f4d6ad0f5095b9438eeb3f9577ef4de5f175541470b4d0f1a77b9b8233eeb87feabe0f1cc93a0615494646bb22d2e22db256ca8ae9740c5b02ee2a5f5a37d947eaec2d804dcdd2f199a15c4f69e2e9fa433a3c997343c3615b72bd13de7300c511dae4a9cf8245f1a3150e8f6754becd21d3ccff4e5cfb10e563aa7fd49b205799d0032fcda0252d848bef3dc521f1947791bb96e8fd0c95f54f128de095a4f7a705c3460d94879f4acbdb89d68e621f4f5594bbd71a2f18112b6aa55b13f29b5a64a0871ab041f1038ffdf4f3b70cff896f1a6f35a6ef5e9bdd39980e7b93eb1ef8e1af8b2becee2878ec85a0ba05120bb15b5f5f224d777c98263a238fbb8b3aed66415a4c1d6ae3402a821793e65968b1fbb0ec02b8bbfe34c9fc954451f14678fb3b5d4e4e134477e142cc7101366171bb0ecb3f2ff3783100b54be4ea35a0fc0faf890c134779a4dfdf6409630c096a349b07fd9f2bfd2f576afb35bdb8315a5c245cdc8757e33a676e24ccca62261fa89ced7a49efb738bca957f5e8b7af9757244c51f5005803b258805f08ccb3802eedc6e5b099ec48aefc155ffbd1b334c13d276adffa44407574b5ad2ea31a9d51d60de7b279455c0832a4bd1deb9f9c2a002f582e58013630c85e1323491d48ffec8625e0b6ef3679432e784e339ac2e099121ea4639ab6d35aea652cfcb40a23000acb412f78de347882440490e97210832c89c5ecf593923cc125c48bd5985c753ede4039070df2cbecbea70482472a2ddc4be543350fcfa99ac61c73e19d140d15033573ac1a302d0821c3e570580e2dd9da979d9debdea1ac78f69852d095a9f77758af8250c431da31a9cbbc14ddb735a33d682c648d8c2862de1343a43260e8a12af2a5e2a029974be63074a6440176e21c758bae61e091b3db0bde5a302ee45bfab769b1f226ba86df223c7539697dca70b24f9d3ead917e1fb20a17d7c8f64e757569e86aaac8c57ad7ecbaedbaed2155ba289629c540a607e2b1fb537b27fffa0ade40caa6590d7730513e890f9ab95b2c7eef7c227ff1e35ad9c8677ef34bae9b8a881aa0c2f1c0806458cffe1b286b35d5c6dbb5ecd0dd8c4eb00be54af8c612cb3cbcf68bb47a2cd4f4b7a9ca9b7a9593c6500e6fdddca6d69a404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": [
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"9994bf2c783116c4240dccae7abef236ee18adb1bc8f995a81e75c7c70001022ee97a973644c16a21eeaa0cb37c494c85b84f79c9b49fdd05aab1341f41d021dc903d26e2c73943b4460ca5cd6c273c0eff8443b3c8782d37dd9f1b953acd29c316b68fb0b80920bf64715f77930517d6e37ef214b5238dde721b32f80f8dc907f07929d97f409a10770fe227a0e2826ad56aebf736c3e19c0a6ab44a2387296",
"676c40d387cee93bbff2335185410dc912e8524e437066a56218a3838fffefdd1269568c9bb3e95dc5155f34c83b6b37a57c086364b6022f8954ecbe0be2fde237fd2d91d38c6bc49f9f35a3293d8c3f1108bbc4c3787d2c66260e46ac532d63cf959704f47f6df4edb7ea0886cfae8292c910deb4adc722fcdd4cd07f07236f81f96d62680bf65edc8f01dd85f1d7d953aa51408c93c1e6235954bb5dc78d69"
],
"public_share": "689f5effeb07065e5dafaccc0ec5bc738843bcf4f62853d29c4cd8d36a68cf345a1575e899105fa4b58696a8d2689885fccbeca678b81f9448dea9613066182e",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
"verifier_messages": [
"d0ad2463cd1def9f35d3315e5a76d59ff82348c35d21d442943bac9a1543cca9"
],
"verifier_shares": [
[
"9fb52861af45115ed073d41907c3133b590ba596bc8be5fce2ae33365b3f49497e7669be217dd620bb47c7fee31b935e230001f0b64b01ede0c5513918812bc75dd969e20f56c35da89d3f489a4939c3032be030c26628f6bd4f80355b6abe4cfb2523546dd0a51841d13d4d3d09a0d43ee64ad6143b5529b60ad205aa55aedafe36cf9017e0f8ba2813fdd02d8291c9d81eed221a95386ff20f2c114077996aab4156caead3100acfefae8dc092e8f99ecffee0e1f010c3f60fcab853fbbb9b76f5def5b31c261d50e53b56c07f04f28381ec8ad0f389b202f3e9990c4d27c8b1aabb7f42b4325cad63ac7124f64fa1492cea831e9ca506268cbaf83d6e1bbce917495e45fa5b43c8286cff2250c611cb3684cfd37c2a204d008baaaea383168a9cae8abb955204314557f6f0e492bff074fc3a8a1770737aac2a3a3113033b689f5effeb07065e5dafaccc0ec5bc738843bcf4f62853d29c4cd8d36a68cf34",
"624ad79e50baeea1138c2be6f83cecc4e6aa6a34c2ad92a3231eebbb887860b5eef7b0eb2c007a85016c96b17559f96dd970825d65dac2538de2c90eb26cda4cabf84b78cc66ed2c5db7a6e028bacca310a73db718416d76b1ed4805abc33b1ce8e721da7294ba5e8f42b05e904d325a7bd41cf83c59d70a8f20e684b5f1a22b345e88ae5d3d3b8a38a974de635d526e99e609abac42457f7228d82624726048bc8498768762002c3a7543eb4abce19b2e048e329c4e281a214275dfe1ccc4577633525b2287524d63748f090b29cd7fc82759f5381a30f9ac1903bddd23560b9403e74487b36502085b8897b356ad241330573977feec8ff50200c8fc036eafc9dcda9de679a81d8ff11d31ea69630a62747a6810e0e2b0ee9487a356b1fb8c9deff43fae5ee1c45211e41a41564c10d214db4aa8fd47b6ebe86eed81f691555a1575e899105fa4b58696a8d2689885fccbeca678b81f9448dea9613066182e"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,282 @@
{
"agg_param": "",
"agg_result": [
45328,
76286,
26980
],
"agg_shares": [
"4733fead2a054ecae7b17263d4cc4943402e2bba86a189ac2b29d9038389fe9e46ac1de28446f8d29dc0b7c30997537a",
"12b58559f41a4351b110da0f64eea5099d3b9223dc376dc1136076ce79fec437f0cb384d29b9e44f002cedaf3111fc6d",
"b8c87cf8e0df6ee44a3db38cc74410b322c043229d260992a476b02d03783c292ff1a9d0510023dd45135b8cc457b017"
],
"chunk_length": 7,
"ctx": "736f6d65206170706c69636174696f6e",
"length": 3,
"max_measurement": 32000,
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 1,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 2,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 2,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 2,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"6a14c85f544f068acab76c6fa7f2a0e92ab3a2a60c96fc91970bf230fcd2f651b9c27edbea6c86584a270e2a11d02ab9cca0f135029ebe48e35a3847102b3148dce7f35e8ff742d13cfd627c9e64a711ad4083bc74c7f0d89477ae6562ec7701947f62da19e5ba9ad22cc952e30bbcf802a95c8001b2f90dac0f69849dc53e4c93c1de6bf9ad0678a54cf7c7124ec49e7b2848cd1db7a84dd14b78b6f90777367b387efcf41db85a4c195a35dd4e05df7becde89c6db579ce7becb4b9de57508700506f71abcbeee0cc0f924772e20b76803f54ec5f9dedcc1a209038b05496041963a28481620fdad82994d284d0f8bcfea65337de75dd5ed017c72ded11c99224abf222ac5d13be0ef0bdd674dc3040f1006f2a82d6cad61f32b2ba760a61f96f3f16dd3c850aa936a46d88388a2b55a81c4f9ff8064e440c2d8b69faff718fd2d881308b7b16b96c9c1a831fe4904ad40f5ec1be92dfb273d036e9566f814bdd43be58ca0db5098ed69fe25be0856aca84733dc1bfd049cdbf14c41a268ed55ce3b37a6e3dc9963d93ffb0d08a20af4176c12ea21ca85a15da2865f9e2b9cbc718da5b17f263b71198403c18f15e82a2fe7db7050bdc5ea6908b1fc0e09968a33fdb54c2a13ed4c375cb3c702ec0a57aca7118ce51569b2f14ff45ee7bb8176c830dd7dbad6151c06946182f402a6c1d27772f3ac9cb27900283fcfc43fe1f2a79134d852d9c79a208b813f4aba7a3399bb0d36984b8e69735f85218014af1d1d49b56c5f783213cdb1509d33ebd6f34434c12592021eddd02ad1ab23f3c3cc4f751a09341c3d271c6a7a097da8a3d001af515df75cf9018cb2596d32c20c1bdbbcae2af434c79035e943b9199c73c51eebe6d6e760d3320a6ec23e2b31ad0ddfdb019144718d9a1ec53573d77a54b4bcb05f81f71d5556fc3aecc1b3786a3e32d6f08e9a5ac718e9c28759023625c6c6a0dc3077a3835ef8ac4dee50e5195e904e9ce1bf45f99485263432f6b73ff59ae8b5244630a215c94a0e3309668840097d30e25413afc055b59274d03b516c019a556273014772cd79d48e830f921bb670f789b6c64d722af8ec46f5b6c05528243b85c33b51384f995683f1f6988463b2f60e6db57ec90ba526bed0875786a1abd5cdf0cb88c5a94aced52dc4611dc7f120fee2f895a614c556735fd3b01aa328e8146057341b71b0afda6209fbf492c60b88836cd16c7309585d696a1350753e423442d6ce7521ea9cd44303dc55c351a69370e32bb76ee0ea7325dd7f88a0158af9c3246ffacad3f932ec19b1eeb63042d73bc12ce06ef12412bfbf508d88251e194812201685dbf48a3b97d04cdbb25cc426dd15417e909eefac79a1ea3373fdfc823b0680e87a600ed4eace937bc0f88bd84f3953392ebe27e95a20217ab83d5f7d3888d3fa77f3fecef87d9bed3281d225d7c890309de7286217b3bf696ce110cccb1159f686c5eee9f9b59a7a07a237101fb079c94ca3823d15de0607f8b38afb3f32faed965654128a0d169e84be141c467627e590be1102b1be0f904be60b8cf6398e7358d767d896714dd37c7e616288d803d6fcb7343abc5aef30f8c193b3e7c7937dee8a029007a0b4a96bfefaf2469c4c5359648b507567130a82bd0e7da15c010f7a06c287ad61808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
],
"measurement": [
10000,
32000,
9
],
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"cda7548f63acc498a2907b76f1ee6d16c1d36393d73583390563480181d8548a55165f4b2cc2524677959296583271d3",
"5c3cd71dfc08c1c57d059e5a21fae1ad8abe306149bd7940fd1fd244d354ec675099bd1963e8f66f55b9f98f105ba924",
"e842d452a04a7aa1c369e62eed16b03bb6ea6b0bdf0c0386e17ce5b9abd2be0d6550e39a7055b64917b173d99672e507"
],
"public_share": "bc7bfb8a51feedaa6ab2debae9ae659362c635ef1e0e7e443c73c743238c9d25175734f051378792b6f7228e728d6117b7aa5e9af4f6a111ba84dbfac0f05f3cdb0741343d27927307838455c450ec76412590d40d88a87b4deba67fe61c175e",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf",
"verifier_messages": [
"25a6468b3d90c15982c50e0371477d0b8c1ef532c7e4bf16a0341b52848cfb9a"
],
"verifier_shares": [
[
"dee95536a684ff301ec8d1d87c8fb3838933669e77516302ea364e24389591d499b23adcf6e4cd0147625e655e02c58cbbf651ee42b7d1f9ff9e3acaaeb893a775368bf71e97921b68de5fb315b92404406d1886a92f5b5e81b23d1e520d5c1fbdbea652c33e9affb4f34ddd780d0eabf7802743c2cb24c1a5c9286fb6ba7ed18dfa2ae8ecd99c1dc26df9d2b1e17f8f23e6682be9f8d16dd65c7429269a1cce769b9090e645bb196737582ce1ca0d5c30a9f03d6a8ab5d1d439b2ddd84fbf76f107f6782c0a6b3d01c4dfa4700b71e2a77b5bc14775622e918ef8a7a44d267327437dc79f2945420833fe9de7b380c2927c3eee15d8a52d541a54762363cb53bc7bfb8a51feedaa6ab2debae9ae659362c635ef1e0e7e443c73c743238c9d25",
"90fd5721049f4b919b16d12ebd738f9250cae7ab60b3897d35c1cf92f49dc8a557125ddf4e892104c56d2f03667780ab4a74f49d0a42b8212117d1880236f519d9195d27659a6404b66ae608eb312b87e1abfa16c8e599696cac25de35bc12707f3b37b8ca33cb43a768bd209b429161844b46115f3451486621d0f8d94a484ba0e617734c6a55bf3a7351d38a9e987042c03c2b3e9d33bed74af2ed395f9f62623a9b3a8ab27385223f47b08b02d17081a2319e26caf127ec02a71e63b9d03bb031d53db59b9f21af6103baf5565c650ab3fac8f0a47721ed3c2b4052e75f2ed1f3898a32a55afae754ab8f2cf8f9364e517f045e070fc5ca694418893fbc51175734f051378792b6f7228e728d6117b7aa5e9af4f6a111ba84dbfac0f05f3c",
"941852a855dcb43d0e215df8c5fcbce92ad4f6ae4fef0b6a6de2db6b296c771415c6d42d0a821d7de18156ac588f0106413c7f71e980ad4ea2b1bce2dd93eac5620de3f7a620aced18bd449a8eb1718d820cdac311694fa061ff5e280e5ea62841e22d52e305fa024f0c3864400dbdb990fcb23103133c7ac150696e6d0d7ec1df112c36052fc5f93d2abd05d402737ba75fd78f2e0e944bde7686599d01870385294cbd9b731b40b6634bbd23f24c343054c30635c638f9482c09aebc975a63e4aedb856ee78eafd55317c64e4d6b66cfd441221ca36c26cdf077b045d04b1d5cb928119ad75cd7e99f3e33e7665a564340d5c1fc7af6dfbdfd86a07ac90525db0741343d27927307838455c450ec76412590d40d88a87b4deba67fe61c175e"
]
]
},
{
"input_shares": [
"6b14c85f544f068acab76c6fa7f2a0e92ab3a2a60c96fc91970bf230fcd2f651bac27edbea6c86584a270e2a11d02ab9cda0f135029ebe48e35a3847102b3148dbe7f35e8ff742d13cfd627c9e64a711ad4083bc74c7f0d89477ae6562ec7701947f62da19e5ba9ad22cc952e30bbcf803a95c8001b2f90dac0f69849dc53e4c92c1de6bf9ad0678a54cf7c7124ec49e7b2848cd1db7a84dd14b78b6f90777367b387efcf41db85a4c195a35dd4e05df7cecde89c6db579ce7becb4b9de57508700506f71abcbeee0cc0f924772e20b76703f54ec5f9dedcc1a209038b05496042963a28481620fdad82994d284d0f8bceea65337de75dd5ed017c72ded11c99224abf222ac5d13be0ef0bdd674dc3040f1006f2a82d6cad61f32b2ba760a61f96f3f16dd3c850aa936a46d88388a2b55a81c4f9ff8064e440c2d8b69faff718fc2d881308b7b16b96c9c1a831fe4904ac40f5ec1be92dfb273d036e9566f814bdd43be58ca0db5098ed69fe25be0856aca84733dc1bfd049cdbf14c41a268ed55ce3b37a6e3dc9963d93ffb0d08a20af4176c12ea21ca85a15da2865f9e2b9cbc718da5b17f263b71198403c18f15e8292fe7db7050bdc5ea6908b1fc0e09968933fdb54c2a13ed4c375cb3c702ec0a57aca7118ce51569b2f14ff45ee7bb8176c830dd7dbad6151c06946182f402a6c1d27772f3ac9cb27900283fcfc43fe1f3a79134d852d9c79a208b813f4aba7a3299bb0d36984b8e69735f85218014af1e1d49b56c5f783213cdb1509d33ebd6f44434c12592021eddd02ad1ab23f3c3cd4f751a09341c3d271c6a7a097da8a3d101af515df75cf9018cb2596d32c20c1cdbbcae2af434c79035e943b9199c73c61eebe6d6e760d3320a6ec23e2b31ad0ddfdb019144718d9a1ec53573d77a54b5bcb05f81f71d5556fc3aecc1b3786a3e32d6f08e9a5ac718e9c28759023625c6c6a0dc3077a3835ef8ac4dee50e5195e904e9ce1bf45f99485263432f6b73ff59ae8b5244630a215c94a0e3309668840097d30e25413afc055b59274d03b516c019a556273014772cd79d48e830f921bb670f789b6c64d722af8ec46f5b6c05528243b85c33b51384f995683f1f6988463b2f60e6db57ec90ba526bed0875786a1abd5cdf0cb88c5a94aced52dc4611dc7f120fee2f895a614c556735fd3b01aa328e8146057341b71b0afda6209fbf492c60b88836cd16c7309585d696a1350753e423442d6ce7521ea9cd44303dc55c351a69370e32bb76ee0ea7325dd7f88a0158af9c3246ffacad3f932ec19b1eeb63042d73bc12ce06ef12412bfbf508d88251e194812201685dbf48a3b97d00003481bd6f4773b311782cf53a25fdcea3373fdfc823b0680e87a600ed4eace21aeac14a6ed118985b0853f938549da217ab83d5f7d3888d3fa77f3fecef87da604dd6d4a9e77456668cd04d9e92c64bf696ce110cccb1159f686c5eee9f9b556e86ff4921b4b50690a67d121da397c0607f8b38afb3f32faed965654128a0d9169f4237722b57d13ba851b06b720ae0f904be60b8cf6398e7358d767d89671721aa66f8f9224e0787bda5ecc1df50bef30f8c193b3e7c7937dee8a029007a043b1f6b8739d70ad94d7f30f76866d7a130a82bd0e7da15c010f7a06c287ad61808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
],
"measurement": [
19342,
19615,
3061
],
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"4bcc548f63acc498a2907b76f1ee6d1660a36393d73583390563480181d8548a41225f4b2cc2524677959296583271d3",
"5c3cd71dfc08c1c57d059e5a21fae1ad8abe306149bd7940fd1fd244d354ec675099bd1963e8f66f55b9f98f105ba924",
"e842d452a04a7aa1c369e62eed16b03bb6ea6b0bdf0c0386e17ce5b9abd2be0d6550e39a7055b64917b173d99672e507"
],
"public_share": "177b21837165afd0469f82c9298fe864d89f8e710ae998077254ab93e12810fb175734f051378792b6f7228e728d6117b7aa5e9af4f6a111ba84dbfac0f05f3cdb0741343d27927307838455c450ec76412590d40d88a87b4deba67fe61c175e",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf",
"verifier_messages": [
"c1f102c9518cd8126996f3fa9c2a0e600916673ac72e7137b3627f5214e95252"
],
"verifier_shares": [
[
"dee95536a684ff301ec8d1d87c8fb383a542ade8f6ecbf6987265ce29633c276d831595e1db07e41848303d63470454ba406b16c1ebe6ec7e085ff2cd9c4839c49219073b522192d564144116deb71778ea5a0ce19c52bec91ce2baecc62e079e2abab0b30fd930c388980ce81593cdfcded2d811d3b4827c5c64111b7864f65b2e72fa15998962a45032cc4ba2daec3addb12ca33419363a7e86657289d7382d294e8d76a7b110b8ddbcabd53dc5b5c695e6c329287dda394b24e8a42209c87db5371c5fc3f53b062606189c462f0557392b4d49883e5b015816adca7466093f4e4cff73e7fbc57a4a0446a74e81b9122bbf7490b85ef75cc48129e050a72d2177b21837165afd0469f82c9298fe864d89f8e710ae998077254ab93e12810fb",
"90fd5721049f4b919b16d12ebd738f92c6b70d4d11f3de72ef0800dc63b96c5557125ddf4e892104c56d2f03667780ab368a13b798d38dcff3844c1e35d4e3efd9195d27659a6404b66ae608eb312b879838964ace265c8d3d9980487071e3a17f3b37b8ca33cb43a768bd209b4291615c108c3e17883421c3959efc95763968a0e617734c6a55bf3a7351d38a9e98702dbd12be86dd25b793b488ec6995a58f623a9b3a8ab27385223f47b08b02d1708dab29767888c97c5e02e38aaf3dbc9db031d53db59b9f21af6103baf5565c650f8f8d2273d5f2e4ebff9bc8c06b0e5dd1f3898a32a55afae754ab8f2cf8f9364e517f045e070fc5ca694418893fbc51175734f051378792b6f7228e728d6117b7aa5e9af4f6a111ba84dbfac0f05f3c",
"941852a855dcb43d0e215df8c5fcbce942c1dad83f92866077e81c478f79962615c6d42d0a821d7de18156ac588f0106bbc81185a576847d37107bd470e1d036620de3f7a620aced18bd449a8eb1718d0ed35bab9c8c8ab44cbf85c6eafda7d941e22d52e305fa024f0c3864400dbdb9b31a0a7033ed990cb2972586795de42cdf112c36052fc5f93d2abd05d402737b98e3556732e6b893c097580e3215295185294cbd9b731b40b6634bbd23f24c347641de17b77f8b7829056716be4f32d7e4aedb856ee78eafd55317c64e4d6b66aa35dcec3defb7e967c6ede8ee1472d95cb928119ad75cd7e99f3e33e7665a564340d5c1fc7af6dfbdfd86a07ac90525db0741343d27927307838455c450ec76412590d40d88a87b4deba67fe61c175e"
]
]
},
{
"input_shares": [
"6a14c85f544f068acab76c6fa7f2a0e92bb3a2a60c96fc91970bf230fcd2f651b9c27edbea6c86584a270e2a11d02ab9cca0f135029ebe48e35a3847102b3148dce7f35e8ff742d13cfd627c9e64a711ae4083bc74c7f0d89477ae6562ec7701957f62da19e5ba9ad22cc952e30bbcf802a95c8001b2f90dac0f69849dc53e4c92c1de6bf9ad0678a54cf7c7124ec49e7b2848cd1db7a84dd14b78b6f90777367b387efcf41db85a4c195a35dd4e05df7cecde89c6db579ce7becb4b9de57508710506f71abcbeee0cc0f924772e20b76803f54ec5f9dedcc1a209038b05496041963a28481620fdad82994d284d0f8bceea65337de75dd5ed017c72ded11c99224abf222ac5d13be0ef0bdd674dc3040f1006f2a82d6cad61f32b2ba760a61f96f3f16dd3c850aa936a46d88388a2b55a81c4f9ff8064e440c2d8b69faff718fc2d881308b7b16b96c9c1a831fe4904ad40f5ec1be92dfb273d036e9566f814bcd43be58ca0db5098ed69fe25be0856aca84733dc1bfd049cdbf14c41a268ed55ce3b37a6e3dc9963d93ffb0d08a20af3176c12ea21ca85a15da2865f9e2b9cbb718da5b17f263b71198403c18f15e8292fe7db7050bdc5ea6908b1fc0e09968a33fdb54c2a13ed4c375cb3c702ec0a57aca7118ce51569b2f14ff45ee7bb8176c830dd7dbad6151c06946182f402a6c1d27772f3ac9cb27900283fcfc43fe1f3a79134d852d9c79a208b813f4aba7a3299bb0d36984b8e69735f85218014af1d1d49b56c5f783213cdb1509d33ebd6f44434c12592021eddd02ad1ab23f3c3cd4f751a09341c3d271c6a7a097da8a3d001af515df75cf9018cb2596d32c20c1bdbbcae2af434c79035e943b9199c73c51eebe6d6e760d3320a6ec23e2b31ad0ddfdb019144718d9a1ec53573d77a54b4bcb05f81f71d5556fc3aecc1b3786a3e32d6f08e9a5ac718e9c28759023625c7c6a0dc3077a3835ef8ac4dee50e5195f904e9ce1bf45f99485263432f6b73ff59ae8b5244630a215c94a0e3309668840097d30e25413afc055b59274d03b516c019a556273014772cd79d48e830f921bb670f789b6c64d722af8ec46f5b6c05528243b85c33b51384f995683f1f6988463b2f60e6db57ec90ba526bed0875786a1abd5cdf0cb88c5a94aced52dc4611dc7f120fee2f895a614c556735fd3b01aa328e8146057341b71b0afda6209fbf492c60b88836cd16c7309585d696a1350753e423442d6ce7521ea9cd44303dc55c351a69370e32bb76ee0ea7325dd7f88a0158af9c3246ffacad3f932ec19b1eeb63042d73bc12ce06ef12412bfbf508d88251e194812201685dbf48a3b97d04d11bb24e90f4346743425b5720e9264ea3373fdfc823b0680e87a600ed4eace7291ff4631e5e0a910f9b2d50b000594217ab83d5f7d3888d3fa77f3fecef87d3cae184097816bf67ca8d10b979cc4e6bf696ce110cccb1159f686c5eee9f9b5d6b1c3da2b12170b695b53af23b9da6c0607f8b38afb3f32faed965654128a0dd4218938ea439b29b7d33dc75940948d0f904be60b8cf6398e7358d767d8967194f280197bb038c7eff1c42c8569c455ef30f8c193b3e7c7937dee8a029007a0b192d787f0b696ba87f35c5927713532130a82bd0e7da15c010f7a06c287ad61808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
],
"measurement": [
15986,
24671,
23910
],
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"2fbf548f63acc498a2907b76f1ee6d1620b76393d73583390563480181d8548ab2735f4b2cc2524677959296583271d3",
"5c3cd71dfc08c1c57d059e5a21fae1ad8abe306149bd7940fd1fd244d354ec675099bd1963e8f66f55b9f98f105ba924",
"e842d452a04a7aa1c369e62eed16b03bb6ea6b0bdf0c0386e17ce5b9abd2be0d6550e39a7055b64917b173d99672e507"
],
"public_share": "b3d82f8cb81a46b1eac54f1792db51bfb7609565cd7a351f78bdc7385a6567f3175734f051378792b6f7228e728d6117b7aa5e9af4f6a111ba84dbfac0f05f3cdb0741343d27927307838455c450ec76412590d40d88a87b4deba67fe61c175e",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf",
"verifier_messages": [
"3c0119723553ea41b47712f1290f1d817e251b7d2e0b21c306e34f327af1f083"
],
"verifier_shares": [
[
"dee95536a684ff301ec8d1d87c8fb383f3fb9e1b687dab6d703c684d72b48c9bb8e014d49d474a5cb60d500ba6a517489596012a1db5ca6e95212b94b9a4bc3caa743fc5b69f6092e03869e9669b5d202794cd75e9f2693cd461cffd51210003345062e225608b3b385a4e1728bb500c287a36c8bed5a01f276cc51c129dee988dfa2ae8ecd99c1dc26df9d2b1e17f8ff455ccd2f3111e3823a1cf30679931eb9d2802a26274ebd924c1fdb5563bb2e8bae6e0a6083655cb7ceb188425f7e604f2eb88e40e00e9959570c9424fd3efcebe405782605ab2e3215b3582b4edf98ef297bf6aa112e5ded5fa580f82b37af3c3eea8454528ce7377437361ee93ea55b3d82f8cb81a46b1eac54f1792db51bfb7609565cd7a351f78bdc7385a6567f3",
"90fd5721049f4b919b16d12ebd738f925c5f4a286960501398366f675b458cc957125ddf4e892104c56d2f03667780ab0c63decb5306462178fafc4e1cda028ed9195d27659a6404b66ae608eb312b8724f54e255cb0bce3c2eb210dafb7c06c7f3b37b8ca33cb43a768bd209b4291614561728943c5fe9326897a939b261390a0e617734c6a55bf3a7351d38a9e987023d6500f663ed493c40c979a2a517436623a9b3a8ab27385223f47b08b02d1705aafe1083afa33628e9283f116612cf8b031d53db59b9f21af6103baf5565c65501e1375829098e9a2a7d30b5bf74690d1f3898a32a55afae754ab8f2cf8f9364e517f045e070fc5ca694418893fbc51175734f051378792b6f7228e728d6117b7aa5e9af4f6a111ba84dbfac0f05f3c",
"941852a855dcb43d0e215df8c5fcbce925d8e7db00b011bdfdef93862f5af8df15c6d42d0a821d7de18156ac588f0106779b4cac915d7ac874e4a142b0d715b6620de3f7a620aced18bd449a8eb1718d3bc0a15e068cdb640f9cabdf39dd6e4f41e22d52e305fa024f0c3864400dbdb9b3de451c6c02f0da9b5bde31d1da36cddf112c36052fc5f93d2abd05d402737bb5149b7ac7a0886197e26e4ea2c4efd385294cbd9b731b40b6634bbd23f24c346ab48a38e9f52fec392cf977d0abed38e4aedb856ee78eafd55317c64e4d6b665b5641a702e93bf396f2c35d21e156db5cb928119ad75cd7e99f3e33e7665a564340d5c1fc7af6dfbdfd86a07ac90525db0741343d27927307838455c450ec76412590d40d88a87b4deba67fe61c175e"
]
]
}
],
"shares": 3,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,90 @@
{
"agg_param": "",
"agg_result": 100,
"agg_shares": [
"e3ad3d4d7d6f5765",
"8252c2b28190a89a"
],
"ctx": "736f6d65206170706c69636174696f6e",
"max_measurement": 255,
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"6dcfc878dd3eacabf0312e41ae665028c676e3809260f86d9f31aca7f2e0d1fc2e5fdb580c94b79b11375e88df48fc556839a4a7735871b5c83b1d93be82e65b13ace77f6202877a93b2633abb7965c32c1f799947f154699d284c9f5fe63f0d5a42f000eefa535d87d4b962d9684874577a9d69d32062c6d669ebf90d738656faf540f6ffba038c2bc7b775f9e5a9ab44b685e60b875ad6a48b49d7625fe79183b34ee6a2ef868b7d0d3e2bd99734e80be11e270cd4288fcaa75f3b39dac18aa665ce06e4486abfe31619deaf3808110a5a6dada60868497553f6db3f5f3e541038b098487b12f6c4efb91eab1f2468b61578ad0fbaa3fe9d48f100c6a5131df2a120019197dee361b0b1f658462fd1b9ce0428dde833377996648e4deddeef88cb4703a08850f060b07b1e0d8a7b3310d882823d841da2b173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 100,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"e3ad3d4d7d6f5765",
"8252c2b28190a89a"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"8ae6c9427194bcbd4f7ec37b2d71efde7103dba5d9ce9b82",
"771936bd8d6b4342fcd39293142d00ba0dbe587ac2359285"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,112 @@
{
"agg_param": "",
"agg_result": 100,
"agg_shares": [
"d34ed229c57767b4",
"8252c2b28190a89a",
"115f6b23b7f7efb0"
],
"ctx": "736f6d65206170706c69636174696f6e",
"max_measurement": 255,
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 2,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 2,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"0f1dec73d31bf11ae63ba5c89da8aa04f93239540c3147b647c40c31d90b79bfb038150fbdd4a6b4b937fe5d2b24e2e174871c905d486385db2826adfc6fb7e5fa420341e6fa2e51fc4a5eafc90cea5be7bd0f92d61a67ee8d4faa60c8547ca8020664d9a7e60228f5f465a00f124546c36d3a5868700e75c8836b777024e5df9b7372ee79956db824fd0077baa9fde616b700d0bcb0f91f001f246b4261caa4311ea8e96c3c80ff4e450af4d9641029100106abe28a6ea3f7964a792bc2d29de2f089ecf42c52a45568567393984b6301e23d34a93363990b6cadd2329cd154b0a7247d3f84ecfd9a224ed2d7640447026f305810d5c4f06d20c3941007a4c109a7fe5c8732e9e0853529f8dc2992ce9b8865b402a260ce1f7cbb395c0662634120e118f9eaeb61e5bbcbe5783e5cdea28690cef612bf572c97516e6446ee54",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
],
"measurement": 100,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"d34ed229c57767b4",
"8252c2b28190a89a",
"115f6b23b7f7efb0"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"d99ee7d52ac4e9beeb2f38e9afa7f0dcd36e585cfa22c7e0",
"771936bd8d6b4342fcd39293142d00ba0dbe587ac2359285",
"b247e26c45d0d2fed9a975ea2312fb7c0d6e746b87169a66"
]
]
}
],
"shares": 3,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,510 @@
{
"agg_param": "",
"agg_result": 1521,
"agg_shares": [
"8c349410658b977f",
"66d16bef99746880"
],
"ctx": "736f6d65206170706c69636174696f6e",
"max_measurement": 1337,
"operations": [
{
"operation": "shard",
"report_index": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 0,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 0,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 0,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 1,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 1,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 1,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 2,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 2,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 2,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 2,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 3,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 3,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 3,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 3,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 3,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 3,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 4,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 4,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 4,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 4,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 4,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 4,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 5,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 5,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 5,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 5,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 5,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 5,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 6,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 6,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 6,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 6,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 6,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 6,
"round": 1,
"success": true
},
{
"operation": "shard",
"report_index": 7,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_init",
"report_index": 7,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_init",
"report_index": 7,
"success": true
},
{
"operation": "verifier_shares_to_message",
"report_index": 7,
"round": 0,
"success": true
},
{
"aggregator_id": 0,
"operation": "verify_next",
"report_index": 7,
"round": 1,
"success": true
},
{
"aggregator_id": 1,
"operation": "verify_next",
"report_index": 7,
"round": 1,
"success": true
},
{
"aggregator_id": 0,
"operation": "aggregate",
"success": true
},
{
"aggregator_id": 1,
"operation": "aggregate",
"success": true
},
{
"operation": "unshard",
"success": true
}
],
"reports": [
{
"input_shares": [
"6dcfc878dd3eacabf0312e41ae665028c576e3809260f86d9f31aca7f2e0d1fc2e5fdb580c94b79b10375e88df48fc556739a4a7735871b5c83b1d93be82e65bd149a96161170734f3dbc83a516cfc9cd2059e8c0ef9a1aa13ace77f6202877a93b2633abb7965c372dcded49999a5819d284c9f5fe63f0d0567a2b21a2408e687d4b962d968487430a145d3f61dd86fd669ebf90d73865680a83c847eebf05c2bc7b775f9e5a9ab87840942a9005b3aa48b49d7625fe79158e5f9a445aecd9b7d0d3e2bd99734e802c6e3952d9bf6c6caa75f3b39dac18a2a61977151192acae31619deaf3808119351bcc301452a837553f6db3f5f3e54c51c7154123bbecfc4efb91eab1f2468a65a94e0de2e969a9d48f100c6a5131dc64a490d23c08d1261b0b1f658462fd164d5f046f24a4b997996648e4deddeef36f4f369583166f360b07b1e0d8a7b33f9efc96ac2b2a05bb173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 0,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"d48512026cf1f2af",
"2d7aedfd920e0d50"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"7fd2ce71f221a56a6c184ddbb15b0bafacc5b565940098fc",
"822d318e0cde5a9587dd2cfb8e20de292e59c3e7311f06da"
]
]
},
{
"input_shares": [
"6ecfc878dd3eacabf0312e41ae665028c576e3809260f86d9f31aca7f2e0d1fc2e5fdb580c94b79b10375e88df48fc556739a4a7735871b5c83b1d93be82e65bd149a96161170734f3dbc83a516cfc9cd2059e8c0ef9a1aa13ace77f6202877a93b2633abb7965c3cea670dbe6097a159d284c9f5fe63f0dda3875782f26015087d4b962d9684874927354624e30abedd669ebf90d7386568285912a40d3c8142bc7b775f9e5a9abd74814514d8479c2a48b49d7625fe791dd80c21ff1679e8f7d0d3e2bd99734e8b843ce930f4ee278caa75f3b39dac18a463e7ce937e87883e31619deaf3808117f373ed2695f5fb67553f6db3f5f3e54afd68fa23d8894eac4efb91eab1f246820a9c727ee219d749d48f100c6a5131d8eb35cbe7ebb791561b0b1f658462fd1004fdb3b25a36b4d7996648e4deddeefb8439d0b399d4ea460b07b1e0d8a7b3307c2ab4740ae7cf2b173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 1,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"d58512026cf1f2af",
"2d7aedfd920e0d50"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"7fd2ce71f221a56adcd6217f429ec5e299e963269ee22eff",
"822d318e0cde5a9587dd2cfb8e20de292e59c3e7311f06da"
]
]
},
{
"input_shares": [
"6ecfc878dd3eacabf1312e41ae665028c676e3809260f86da031aca7f2e0d1fc2f5fdb580c94b79b11375e88df48fc556839a4a7735871b5c93b1d93be82e65bd249a96161170734f4dbc83a516cfc9cd3059e8c0ef9a1aa13ace77f6202877a93b2633abb7965c3ea98d1dd5bac873f9d284c9f5fe63f0d75684163511eec9687d4b962d96848740281e6a8d6ea821fd669ebf90d738656e94efbd4664db0fa2bc7b775f9e5a9ab9fb6d652110118d7a48b49d7625fe791246e6104f302a15f7d0d3e2bd99734e807cf87b90e0fededcaa75f3b39dac18a6b79ac6928e8547be31619deaf3808116e0cdbffc35c2af57553f6db3f5f3e542983d97cc38568a4c4efb91eab1f2468f35175163bf76ce49d48f100c6a5131d759b702055ddcb3261b0b1f658462fd14d9fce0a08c020bf7996648e4deddeef4d16f253be96925960b07b1e0d8a7b33c9b171f65f3b34dab173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 1337,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"0d8b12026cf1f2af",
"2d7aedfd920e0d50"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"7fd2ce71f221a56a611917374bba070b6651bbbc0b29283c",
"822d318e0cde5a9587dd2cfb8e20de292e59c3e7311f06da"
]
]
},
{
"input_shares": [
"6ecfc878dd3eacabf1312e41ae665028c576e3809260f86d9f31aca7f2e0d1fc2e5fdb580c94b79b11375e88df48fc556839a4a7735871b5c83b1d93be82e65bd149a96161170734f3dbc83a516cfc9cd2059e8c0ef9a1aa13ace77f6202877a93b2633abb7965c3890bf773466131639d284c9f5fe63f0dbf8651a0d9185ec487d4b962d96848742cd504fe7f3f23a2d669ebf90d73865661eab57b00e14d562bc7b775f9e5a9ab29a327a3a8c196a7a48b49d7625fe7917eaf01f1bd3e290f7d0d3e2bd99734e8dd444176d2386fa4caa75f3b39dac18aebe8e67b273ca18ce31619deaf3808115b26593866a271db7553f6db3f5f3e54593876787b9304c3c4efb91eab1f246828f919152c1d94aa9d48f100c6a5131d75b938c80bc8210d61b0b1f658462fd1967dd456870087557996648e4deddeefb289d28a67d1bdc760b07b1e0d8a7b335e2b6554a8a86a2fb173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 99,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"378612026cf1f2af",
"2d7aedfd920e0d50"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"7fd2ce71f221a56af1441c5a52009454a302b6c45c0bdbe6",
"822d318e0cde5a9587dd2cfb8e20de292e59c3e7311f06da"
]
]
},
{
"input_shares": [
"6dcfc878dd3eacabf1312e41ae665028c576e3809260f86da031aca7f2e0d1fc2e5fdb580c94b79b11375e88df48fc556739a4a7735871b5c83b1d93be82e65bd149a96161170734f3dbc83a516cfc9cd2059e8c0ef9a1aa13ace77f6202877a93b2633abb7965c34a6c427860928ba89d284c9f5fe63f0d52b17c9ecd6c5bf887d4b962d9684874f5abfe4aa3d6063ed669ebf90d73865670c79c4941e51bb82bc7b775f9e5a9ab8a1dcbf2c06279faa48b49d7625fe791cfd8d5a3cfcea7ff7d0d3e2bd99734e89fac4772287d1da4caa75f3b39dac18a79f5f850c81754b1e31619deaf3808118ab10ab444667d727553f6db3f5f3e54c71c55e65858b389c4efb91eab1f2468c482f474b67c12a49d48f100c6a5131d149490db07527dcd61b0b1f658462fd1419adc52abc94b2a7996648e4deddeef8bcecf1f75d639a060b07b1e0d8a7b332767119f3a800a45b173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 42,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"fe8512026cf1f2af",
"2d7aedfd920e0d50"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"7fd2ce71f221a56a8ef52a9c68a1bcd755af465b9f819223",
"822d318e0cde5a9587dd2cfb8e20de292e59c3e7311f06da"
]
]
},
{
"input_shares": [
"6dcfc878dd3eacabf0312e41ae665028c576e3809260f86d9f31aca7f2e0d1fc2e5fdb580c94b79b10375e88df48fc556739a4a7735871b5c83b1d93be82e65bd149a96161170734f3dbc83a516cfc9cd2059e8c0ef9a1aa13ace77f6202877a93b2633abb7965c372dcded49999a5819d284c9f5fe63f0d0567a2b21a2408e687d4b962d968487430a145d3f61dd86fd669ebf90d73865680a83c847eebf05c2bc7b775f9e5a9ab87840942a9005b3aa48b49d7625fe79158e5f9a445aecd9b7d0d3e2bd99734e802c6e3952d9bf6c6caa75f3b39dac18a2a61977151192acae31619deaf3808119351bcc301452a837553f6db3f5f3e54c51c7154123bbecfc4efb91eab1f2468a65a94e0de2e969a9d48f100c6a5131dc64a490d23c08d1261b0b1f658462fd164d5f046f24a4b997996648e4deddeef36f4f369583166f360b07b1e0d8a7b33f9efc96ac2b2a05bb173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 0,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"d48512026cf1f2af",
"2d7aedfd920e0d50"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"7fd2ce71f221a56a6c184ddbb15b0bafacc5b565940098fc",
"822d318e0cde5a9587dd2cfb8e20de292e59c3e7311f06da"
]
]
},
{
"input_shares": [
"6dcfc878dd3eacabf0312e41ae665028c576e3809260f86d9f31aca7f2e0d1fc2e5fdb580c94b79b10375e88df48fc556739a4a7735871b5c83b1d93be82e65bd149a96161170734f3dbc83a516cfc9cd2059e8c0ef9a1aa13ace77f6202877a93b2633abb7965c372dcded49999a5819d284c9f5fe63f0d0567a2b21a2408e687d4b962d968487430a145d3f61dd86fd669ebf90d73865680a83c847eebf05c2bc7b775f9e5a9ab87840942a9005b3aa48b49d7625fe79158e5f9a445aecd9b7d0d3e2bd99734e802c6e3952d9bf6c6caa75f3b39dac18a2a61977151192acae31619deaf3808119351bcc301452a837553f6db3f5f3e54c51c7154123bbecfc4efb91eab1f2468a65a94e0de2e969a9d48f100c6a5131dc64a490d23c08d1261b0b1f658462fd164d5f046f24a4b997996648e4deddeef36f4f369583166f360b07b1e0d8a7b33f9efc96ac2b2a05bb173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 0,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"d48512026cf1f2af",
"2d7aedfd920e0d50"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"7fd2ce71f221a56a6c184ddbb15b0bafacc5b565940098fc",
"822d318e0cde5a9587dd2cfb8e20de292e59c3e7311f06da"
]
]
},
{
"input_shares": [
"6dcfc878dd3eacabf1312e41ae665028c576e3809260f86da031aca7f2e0d1fc2e5fdb580c94b79b11375e88df48fc556739a4a7735871b5c83b1d93be82e65bd149a96161170734f3dbc83a516cfc9cd2059e8c0ef9a1aa13ace77f6202877a93b2633abb7965c34a6c427860928ba89d284c9f5fe63f0d52b17c9ecd6c5bf887d4b962d9684874f5abfe4aa3d6063ed669ebf90d73865670c79c4941e51bb82bc7b775f9e5a9ab8a1dcbf2c06279faa48b49d7625fe791cfd8d5a3cfcea7ff7d0d3e2bd99734e89fac4772287d1da4caa75f3b39dac18a79f5f850c81754b1e31619deaf3808118ab10ab444667d727553f6db3f5f3e54c71c55e65858b389c4efb91eab1f2468c482f474b67c12a49d48f100c6a5131d149490db07527dcd61b0b1f658462fd1419adc52abc94b2a7996648e4deddeef8bcecf1f75d639a060b07b1e0d8a7b332767119f3a800a45b173f09c3f275002",
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
],
"measurement": 42,
"nonce": "000102030405060708090a0b0c0d0e0f",
"out_shares": [
"fe8512026cf1f2af",
"2d7aedfd920e0d50"
],
"public_share": "",
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
"verifier_messages": [
""
],
"verifier_shares": [
[
"7fd2ce71f221a56a8ef52a9c68a1bcd755af465b9f819223",
"822d318e0cde5a9587dd2cfb8e20de292e59c3e7311f06da"
]
]
}
],
"shares": 2,
"verify_key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

View file

@ -0,0 +1,8 @@
{
"binder": "62696e64657220737472696e67",
"derived_seed": "b62ef0a2778190792d4d42d8c167ba20e0c37a3f319ba79645829c427d70eea5",
"dst": "646f6d61696e2073657061726174696f6e20746167",
"expanded_vec_field128": "b62ef0a2778190792d4d42d8c167ba20e0c37a3f319ba79645829c427d70eea56d92fef65a07b17a0438e25452cdc7f15f63caf0e8a2a3c72ac69524729e64e03c7ec3a3afa7eb21cb6da6abf0a3b73630a91a5fa05dcbd33da3476f1c8bf4fd66fe5a80dd04bc95f0f02cb8fc9035b9e16e3a5c373bf81c820af513e0c832ca672c66dcc3b302fb8b27a48f09e0a843f5caf87b3c6c1c4b6765b5923e1d152c2e695601abbc69dbe810860fb30e871a2549861110672335ce50ee632264cbb21f62595298d1d1ad9303b84664801e52112989dfce93f0f9dc833ee0f4a0672ffe47cb0a13f80f9e9b7a2e267db7f7890ccd064bf2458cd4e27162d13e60dbc1b6cae71635a3e603f2c15d1c64a12d4e8235f7bf0a8efe6bb15f3e2adae06f7dd1c4d63ac6cecae731250f73c063c6e59aef630a7b6f4bc64bddadc8b8a479bfdb64ea31e6ab44540a52a8d3399d64a060d50190d66cac1335d739e5f8d508201058a2e0cc1ed90e23cfdc7a253f24710ef3b1604688606386dcc4c90e8476be9daac3271ac51301868df71a719a5f32184145d70fec31b4693d527f53875a2ea013523d3daa33bc49c22f66c9ae70dd7f06f227f50515ea9ab1fbe0162cf761e596d8999809cf672cd2d82b22231f841c36e494d7e44f7c6f07e29758b1b73ce95b202325116f04067a54aa767eab2e00ce55b3abcd5c3d5b05040a6bf5d4ba8a61267004bb82b12d43b08fed8f9aced3e833a58fc01004526631b0f4192d8754a397e1096511ee23761a29fcd6511ad2e5020683ca877e4075fe6bc5907f7df1ed4b6c97e0f897d781e850da0cf584842c124cdb6011fe8660e3b8c354cd659985332ea158ffcba83253d39803fa7efb9fcd02cea38089f239f68404814973",
"length": 40,
"seed": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,54 @@
# live-conformance/dred — Opus deep redundancy, decoded exactly
The corpus of [`extensions/opus-dred.md`](../../extensions/opus-dred.md) §9: the integer profile
`dred-int/1` of the deep redundancy (DRED) of draft-ietf-mlcodec-opus-dred-07, decoded from Opus
packets, and streams of packets under seeded loss patterns, each with a record of its
reconstruction and a player's log that presents it.
**Feature equivalence.** A conforming implementation, given the draft's weights file (§4.1),
reaches the outcome each vector states:
- each **payload vector** (`payloads`): its `packet`, in hexadecimal, carries DRED (`outcome`
`"dred"`), carries none (`"none"`), or is refused (`{"refuse": code}`). For one that carries
DRED, `dred` states its `frame_offset`, its header (`q0`, `dq`, `extended` or `null`,
`indicator`, `qmax`), its `dred_offset` (§3.3 step 3), its `latents`, the SHA-256 of its integers
(`symbols_sha256`, §9), its `rows`, the SHA-256 of every row (`features_sha256`) and row 0 itself
(`newest`, 20 features at `2^16`);
- each **case** (`cases`) over a **stream** (`streams`, by name): the stream is its `objects` (each
received packet as a `WAI1` envelope of `wai.audio.opus.packet` in hexadecimal, `null` where the
packet was lost), its `frame_ticks` (one packet's duration in units of 2.5 ms) and its `loss`
pattern (`seed`, `enter`, `stay`, §5.1). The case gives the `record` of its reconstruction
(`weights_sha256`, `lost`, `slots`, `output`, §5.4) and the `player`'s log, each entry the text
of a signed `wai-player` record (synthesis §10.3). Its `outcome` is `"accept"`, or `refuse` with
the code and where, `["record"]` or `["player", i]` (§5.5, §7.2).
The file also states the profile's identities: `tables_sha256` (§4.2), and under `lowering` the
constant `exp_c0` and the two activation tables' digests (§4.5) and the two graphs' identities
(§4.6). An implementation that reaches another outcome, code, place, digest, row or identity does
not conform.
**The weights are not here.** The corpus names the draft's weights file by its SHA-256 and holds
no copy. `fetch.sh <dir>` fetches it from the location the draft gives ([DRED-Weights], draft
§7.1) and checks the digest; `fetch.sh <dir> vectors` also fetches the draft's test vectors, which
the measurement of §6 reads (`wai-rs/tests/dred_exact_measure.rs`) and this corpus does not.
**Provenance.** Generated here: `wai_dred_vectors gen <dir> <weights>` writes `vectors.json` from
fixed seeds. Every packet is written by the generator: a code-3 packet of one 20 ms Silk wideband
frame, the frame empty (length 0, RFC 6716 §3.2.1), and the DRED extension in its padding (the
experimental ID 126 with its prefix for one stream, ID 32 for the other). Its DRED indices are
drawn from the draft's own distributions, by decoding a stream of SHA-256 output with §3.3's
coefficient rule at `q0`, and requantized to each chunk's quantizer; the generator drops a final
latent the decoder would not read (draft §3) until the payload decodes to exactly what it holds.
Each loss pattern's seed, and the player's key, is SHA-256 of a fixed label; times are constants;
Ed25519 signing is deterministic (RFC 8032). So every byte is the same on every machine. No
recorded speech: the latents are drawn, not encoded from audio, so the features they decode to
describe no real utterance. The generator asserts that each vector reaches the outcome it states,
and that the corpus gives every reason of §8, before it writes.
**Checks.** `wai_dred_vectors verify <dir> <weights>` and `wai-rs/tests/dred_exact.rs` regenerate
the corpus byte for byte and require no other file here but this README and `fetch.sh`.
`../dred_verify.py`, written from the extension's text and sharing no code with wai-rs, recomputes
every outcome, digest and row in its own integer arithmetic, and requires every mutated copy of
the corpus to fail:
python3 -I live-conformance/dred_verify.py live-conformance/dred <weights-file>

View file

@ -0,0 +1,40 @@
#!/usr/bin/env bash
#
# fetch.sh <dir> [vectors]
#
# Fetch the files of draft-ietf-mlcodec-opus-dred-07 that the corpus names by digest and does not
# hold, into <dir>, and check each against the SHA-256 the draft states (§7.1):
#
# dred_unquantized_weights.bin the decoder weights ([DRED-Weights]): the profile's parameter set
# dred_testvectors.tar.gz the conformance test vectors ([DRED-Test-Vectors]), with
# `vectors`, unpacked into <dir>/dred_testvectors/ (the
# measurement of extensions/opus-dred.md §6 reads them)
#
# A file already in <dir> with the right digest is not fetched again. A digest that does not match
# fails, and the file is removed. The locations are the draft's own references.
set -euo pipefail
dir=${1:?usage: fetch.sh <dir> [vectors]}
base="https://media.xiph.org/opus/ietf/dred_material"
mkdir -p "$dir"
sha() { if command -v sha256sum >/dev/null; then sha256sum "$1" | cut -d' ' -f1; else shasum -a 256 "$1" | cut -d' ' -f1; fi; }
get() {
local name=$1 want=$2
if [ -f "$dir/$name" ] && [ "$(sha "$dir/$name")" = "$want" ]; then return 0; fi
curl -sSfL --retry 3 -o "$dir/$name.part" "$base/$name"
local got
got=$(sha "$dir/$name.part")
if [ "$got" != "$want" ]; then
rm -f "$dir/$name.part"
echo "fetch.sh: $name has SHA-256 $got, not $want" >&2
exit 1
fi
mv "$dir/$name.part" "$dir/$name"
}
get dred_unquantized_weights.bin 394f0ecf19926cebd678019dc94a54c88ae078340c16325069707f286cdf28a6
if [ "${2:-}" = vectors ]; then
get dred_testvectors.tar.gz 0af7a068783d9d1397a67ed7896615d0777fb69fa258e4f192dea4f61226ad31
if [ ! -d "$dir/dred_testvectors" ]; then
tar -xzf "$dir/dred_testvectors.tar.gz" -C "$dir"
fi
fi
echo "fetch.sh: $dir holds the pinned files"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
# live-conformance/robustness — robustness evidence for soft bindings
The corpus of [`extensions/robustness-evidence.md`](../../extensions/robustness-evidence.md) §13:
- `corpus/<name>.json`: the corpus documents (§3), each the JCS text of its document, so the
SHA-256 of the file is the document's digest: `conformance`, three pictures of 256 × 256 whose
samples this directory holds; `tent64-spectral`, `tent64-leaves` and `tent64-clips`, the
measurement sets of synthesis §7.5.8, by their samples' digests.
- `frames/<SHA-256>.rgb`: the samples of the conformance pictures, raw RGB8, each file named by
the SHA-256 of its bytes.
- `records/<name>.json`: the signed records, each its JCS text: `conformance.json`, the record
over the conformance corpus; `conformance-claim.json`, the claim of what that record shows
survived; `tent64-spectral.json`, `tent64-leaves.json` and `tent64-clips.json`, the records of
`wai-mark:tent64` over the measurement sets (§10); and `tent64-claim.json`, its claim, which is
synthesis §7.5.8's list.
- `vectors.json`: `algorithm`, the term and digest of `wai-mark:tent64`; `harness`, the term of
§6; and `cases`, each with its `policy` (`evidence`: `reproduced` or `stated`), the
algorithms the verifier `implements`, its `records` in order as JSON texts, the `corpora` it
was handed with them (`record`, the record's position, and a `file` of this directory or a
`text`), the `samples` it holds (each a SHA-256, the file `frames/<SHA-256>.rgb`), and what a
verifier gives it.
**Robustness equivalence.** For each case, a conforming verifier reaches the outcome it states:
- `refuse`: the `reason` of §12 and the `record`, the position of the record refused;
- `accept`: the `statements` of §9.3, one per record, exactly as written.
A verifier that reaches another outcome, reason, record or statement does not conform.
**Provenance.** `wai_robustness_vectors gen` writes every file from fixed seeds: the
conformance pictures are two dead-leaves pictures (`synthesis_mark::leaves`, seeds 200 and 201)
and a spectral one (`wai.generate.spectral`'s generator with its committed model, the prompt "a
lighthouse at dusk", seed 200), each 256 × 256; the measurement sets are the synthesis corpus's
(`live-conformance/synthesis-mark/`); every key is SHA-256 of `wai-robustness corpus key` and an
index; Ed25519 signing is deterministic. The records' tables are the harness's (§6), run by the
generator. No picture comes from outside the repository.
The records of `wai-mark:tent64` are reproduced by the generator, which makes the measurement
sets; their samples, 25 MB, are not in this directory, so a verifier that does not make them
reads those records as stated, and checks their tables against
`../synthesis-mark/battery.json`, which `wai_synthesis_mark_vectors` wrote: the same counts,
measured by another program.
From `wai/wai-rs`, the reference regenerates and checks the corpus; from this directory's
parent, the second implementation checks it:
```
cargo run --release --no-default-features --features robustness --bin wai_robustness_vectors -- verify ../live-conformance/robustness
python3 -I robustness_verify.py robustness
```

View file

@ -0,0 +1 @@
{"items":[{"frames":1,"height":256,"name":"leaves-200","samples":"cbddd7f4f223ea3528744921f8fdc8144a4ffba31651b0d88ac1495947c76c6c","width":256},{"frames":1,"height":256,"name":"leaves-201","samples":"51459d630f3e52d54cc774b6ff930b1dd75b63a7111bae6cd903edc3926378bf","width":256},{"frames":1,"height":256,"name":"spectral-200","samples":"a3e26ad85ab54a7ac01bbfabe0763637817df2934b6492b6cba7f8d5a055f598","width":256}],"kind":"wai-robustness-corpus","media":"image","name":"conformance","negatives":[{"frames":1,"height":256,"name":"leaves-200","samples":"cbddd7f4f223ea3528744921f8fdc8144a4ffba31651b0d88ac1495947c76c6c","width":256},{"frames":1,"height":256,"name":"leaves-201","samples":"51459d630f3e52d54cc774b6ff930b1dd75b63a7111bae6cd903edc3926378bf","width":256},{"frames":1,"height":256,"name":"spectral-200","samples":"a3e26ad85ab54a7ac01bbfabe0763637817df2934b6492b6cba7f8d5a055f598","width":256}]}

View file

@ -0,0 +1 @@
{"items":[{"frames":8,"height":256,"name":"clip-leaves-a","samples":"ebb22a22ab7fc77e8963d105e80827665fae5a0f2636f9bd243ef5652f641b87","width":256},{"frames":8,"height":256,"name":"clip-leaves-b","samples":"746dd1112f0526636b04275f9298514a8b0206688620924c347b99efd5755ad6","width":256},{"frames":8,"height":256,"name":"clip-spectral-a","samples":"e6e19fc5f6762038759f73926ad769f71f1e6097d4397bfab166446aebd771e4","width":256},{"frames":8,"height":256,"name":"clip-spectral-b","samples":"b0271efbc891c3ee10b38ce300aa1c8368159f9e991b5d14545f52db30a9dec1","width":256}],"kind":"wai-robustness-corpus","media":"video","name":"tent64-clips","negatives":[{"frames":8,"height":256,"name":"clip-leaves-a","samples":"ebb22a22ab7fc77e8963d105e80827665fae5a0f2636f9bd243ef5652f641b87","width":256},{"frames":8,"height":256,"name":"clip-leaves-b","samples":"746dd1112f0526636b04275f9298514a8b0206688620924c347b99efd5755ad6","width":256},{"frames":8,"height":256,"name":"clip-spectral-a","samples":"e6e19fc5f6762038759f73926ad769f71f1e6097d4397bfab166446aebd771e4","width":256},{"frames":8,"height":256,"name":"clip-spectral-b","samples":"b0271efbc891c3ee10b38ce300aa1c8368159f9e991b5d14545f52db30a9dec1","width":256}]}

View file

@ -0,0 +1 @@
{"items":[{"frames":1,"height":512,"name":"leaves-00","samples":"2b6b701c701e3e8ba095930ea9d2ff710b39c29506088119148fc79816cfdb73","width":512},{"frames":1,"height":512,"name":"leaves-01","samples":"d0d20def61c791dcacfc600978d2ee3b9c3d38feb406362de2639fcdf8cc12c9","width":512},{"frames":1,"height":512,"name":"leaves-02","samples":"5ebc85750ea27200e32114b3b0414ce36149c97e4bb185cd23d557386344c25b","width":512},{"frames":1,"height":512,"name":"leaves-03","samples":"259c77f197ffe5a8289dbb516e4487177dcd63a39bfaf96609eb46c69016c3be","width":512},{"frames":1,"height":512,"name":"leaves-04","samples":"c28a4768a8857687882f80a7c3274af75afb40e24332d181e7ff8dde0c02592a","width":512},{"frames":1,"height":512,"name":"leaves-05","samples":"a0b21451bcc1b645767227171796b3d5cd8daa91655f1ba38f7c49a860fc2d10","width":512},{"frames":1,"height":512,"name":"leaves-06","samples":"0fb190f8f7745a1ea810e7eb05013b17e83c862236c9ffc66ec75a2695ba65b5","width":512},{"frames":1,"height":512,"name":"leaves-07","samples":"09d3e9c111344a113de818f560437e72af644b82e7d9a1c068815a3213f389d1","width":512},{"frames":1,"height":512,"name":"leaves-08","samples":"858cda4268180f3fd66d6defbdbd43e276b3608276ed59231cd6f6b5bc1a35c9","width":512},{"frames":1,"height":512,"name":"leaves-09","samples":"d9a149edb490f026c2830c67c0e4c9f468e70e634f616d7b935b377e37b3a095","width":512},{"frames":1,"height":512,"name":"leaves-10","samples":"3a04bc1eed3dfb9637e213176249d29010c9527584fca4d9d5f2d322bbf173b2","width":512},{"frames":1,"height":512,"name":"leaves-11","samples":"916f61baec002d682da40a44f676a7610ee3bebe34e62d38bd2b280dcd5da022","width":512},{"frames":1,"height":512,"name":"leaves-12","samples":"0e0f5a789e2d1358ac32843d04f5d475fd8d2d4fcf8a42908607680f4def1390","width":512},{"frames":1,"height":512,"name":"leaves-13","samples":"957bc3f174634ad26431d702b4f13bdd9222888ffc1adcdd7f619155f62497d4","width":512},{"frames":1,"height":512,"name":"leaves-14","samples":"d2432c4cc913cf85b17315bcea3fcd873f92953610d054b3683a83f52d24bf04","width":512},{"frames":1,"height":512,"name":"leaves-15","samples":"2b75c0347c1186a423de27a9b0fa84af3ae4ee7aa22b7639367040e0a99ec2b4","width":512}],"kind":"wai-robustness-corpus","media":"image","name":"tent64-leaves","negatives":[{"frames":1,"height":512,"name":"leaves-00","samples":"2b6b701c701e3e8ba095930ea9d2ff710b39c29506088119148fc79816cfdb73","width":512},{"frames":1,"height":512,"name":"leaves-01","samples":"d0d20def61c791dcacfc600978d2ee3b9c3d38feb406362de2639fcdf8cc12c9","width":512},{"frames":1,"height":512,"name":"leaves-02","samples":"5ebc85750ea27200e32114b3b0414ce36149c97e4bb185cd23d557386344c25b","width":512},{"frames":1,"height":512,"name":"leaves-03","samples":"259c77f197ffe5a8289dbb516e4487177dcd63a39bfaf96609eb46c69016c3be","width":512},{"frames":1,"height":512,"name":"leaves-04","samples":"c28a4768a8857687882f80a7c3274af75afb40e24332d181e7ff8dde0c02592a","width":512},{"frames":1,"height":512,"name":"leaves-05","samples":"a0b21451bcc1b645767227171796b3d5cd8daa91655f1ba38f7c49a860fc2d10","width":512},{"frames":1,"height":512,"name":"leaves-06","samples":"0fb190f8f7745a1ea810e7eb05013b17e83c862236c9ffc66ec75a2695ba65b5","width":512},{"frames":1,"height":512,"name":"leaves-07","samples":"09d3e9c111344a113de818f560437e72af644b82e7d9a1c068815a3213f389d1","width":512},{"frames":1,"height":512,"name":"leaves-08","samples":"858cda4268180f3fd66d6defbdbd43e276b3608276ed59231cd6f6b5bc1a35c9","width":512},{"frames":1,"height":512,"name":"leaves-09","samples":"d9a149edb490f026c2830c67c0e4c9f468e70e634f616d7b935b377e37b3a095","width":512},{"frames":1,"height":512,"name":"leaves-10","samples":"3a04bc1eed3dfb9637e213176249d29010c9527584fca4d9d5f2d322bbf173b2","width":512},{"frames":1,"height":512,"name":"leaves-11","samples":"916f61baec002d682da40a44f676a7610ee3bebe34e62d38bd2b280dcd5da022","width":512},{"frames":1,"height":512,"name":"leaves-12","samples":"0e0f5a789e2d1358ac32843d04f5d475fd8d2d4fcf8a42908607680f4def1390","width":512},{"frames":1,"height":512,"name":"leaves-13","samples":"957bc3f174634ad26431d702b4f13bdd9222888ffc1adcdd7f619155f62497d4","width":512},{"frames":1,"height":512,"name":"leaves-14","samples":"d2432c4cc913cf85b17315bcea3fcd873f92953610d054b3683a83f52d24bf04","width":512},{"frames":1,"height":512,"name":"leaves-15","samples":"2b75c0347c1186a423de27a9b0fa84af3ae4ee7aa22b7639367040e0a99ec2b4","width":512}]}

View file

@ -0,0 +1 @@
{"items":[{"frames":1,"height":512,"name":"spectral-00","samples":"881354453d8a45b7be42aadae089fc3b0e1f03009fa9466a904a4a62cac3d07a","width":512},{"frames":1,"height":512,"name":"spectral-01","samples":"53b54a973eb397975d6f8eabb9dab06f1184d7792c63c767fa816033d9f84e76","width":512},{"frames":1,"height":512,"name":"spectral-02","samples":"0da0f5a46dc827bb131109cea0f5956fd6c0d0dcf3c257864df33f2679ab4944","width":512},{"frames":1,"height":512,"name":"spectral-03","samples":"df6ab6dfc3d000fadd053b209ef5e3f92e0f8833359506519292df69d68d40c4","width":512},{"frames":1,"height":512,"name":"spectral-04","samples":"6e991149f26547177effa0934659883db2057c3b139420750435c9377133ef7b","width":512},{"frames":1,"height":512,"name":"spectral-05","samples":"06cfd98ba86b6f57f6b0d02702a77bc06c9cdfe4414d851d2a87ddc8e44d2ff6","width":512},{"frames":1,"height":512,"name":"spectral-06","samples":"22154fc1bf531de2ea9cbcfc6c9463606a2b0d955b7f6dc4e7842b5d7dced832","width":512},{"frames":1,"height":512,"name":"spectral-07","samples":"615481ad30f54972febf1d9d3c4b477ad35b6c4261f14fce4d4227e3541dfbfb","width":512},{"frames":1,"height":512,"name":"spectral-08","samples":"cc67508b0b3d22b8a43f07f11abbf0054f693cf0c0dbc1ce1e995a8a3f571364","width":512},{"frames":1,"height":512,"name":"spectral-09","samples":"02b6275d3cf529e6fd4a1efd72d8263579f06aa9a4f7470b6c8eb90888b926f7","width":512},{"frames":1,"height":512,"name":"spectral-10","samples":"dc474acb062a584ab643cf02c2a06c463386e0de738982872369264dde7757ed","width":512},{"frames":1,"height":512,"name":"spectral-11","samples":"a93a519c139635ad8563fbc5f19ba8514c0d4ddd2984bf90a3d2fcfffebf4515","width":512},{"frames":1,"height":512,"name":"spectral-12","samples":"4cd6340262a6e6cd14f114ca28c81409fc38757d226ca99071cdbb371b42d8e0","width":512},{"frames":1,"height":512,"name":"spectral-13","samples":"f1781791a93f437278aec85b811dbab9eca8d78ea82a829c8f1bb9b23f0002b7","width":512},{"frames":1,"height":512,"name":"spectral-14","samples":"634fa5e64811d8ef160d288bb260444947370250d48aa9ec28eaee2917329603","width":512},{"frames":1,"height":512,"name":"spectral-15","samples":"6b4e0483dcbf87c0968dbacb9d1e222df5531d7ba59c361e2438067c105dffed","width":512}],"kind":"wai-robustness-corpus","media":"image","name":"tent64-spectral","negatives":[{"frames":1,"height":512,"name":"spectral-00","samples":"881354453d8a45b7be42aadae089fc3b0e1f03009fa9466a904a4a62cac3d07a","width":512},{"frames":1,"height":512,"name":"spectral-01","samples":"53b54a973eb397975d6f8eabb9dab06f1184d7792c63c767fa816033d9f84e76","width":512},{"frames":1,"height":512,"name":"spectral-02","samples":"0da0f5a46dc827bb131109cea0f5956fd6c0d0dcf3c257864df33f2679ab4944","width":512},{"frames":1,"height":512,"name":"spectral-03","samples":"df6ab6dfc3d000fadd053b209ef5e3f92e0f8833359506519292df69d68d40c4","width":512},{"frames":1,"height":512,"name":"spectral-04","samples":"6e991149f26547177effa0934659883db2057c3b139420750435c9377133ef7b","width":512},{"frames":1,"height":512,"name":"spectral-05","samples":"06cfd98ba86b6f57f6b0d02702a77bc06c9cdfe4414d851d2a87ddc8e44d2ff6","width":512},{"frames":1,"height":512,"name":"spectral-06","samples":"22154fc1bf531de2ea9cbcfc6c9463606a2b0d955b7f6dc4e7842b5d7dced832","width":512},{"frames":1,"height":512,"name":"spectral-07","samples":"615481ad30f54972febf1d9d3c4b477ad35b6c4261f14fce4d4227e3541dfbfb","width":512},{"frames":1,"height":512,"name":"spectral-08","samples":"cc67508b0b3d22b8a43f07f11abbf0054f693cf0c0dbc1ce1e995a8a3f571364","width":512},{"frames":1,"height":512,"name":"spectral-09","samples":"02b6275d3cf529e6fd4a1efd72d8263579f06aa9a4f7470b6c8eb90888b926f7","width":512},{"frames":1,"height":512,"name":"spectral-10","samples":"dc474acb062a584ab643cf02c2a06c463386e0de738982872369264dde7757ed","width":512},{"frames":1,"height":512,"name":"spectral-11","samples":"a93a519c139635ad8563fbc5f19ba8514c0d4ddd2984bf90a3d2fcfffebf4515","width":512},{"frames":1,"height":512,"name":"spectral-12","samples":"4cd6340262a6e6cd14f114ca28c81409fc38757d226ca99071cdbb371b42d8e0","width":512},{"frames":1,"height":512,"name":"spectral-13","samples":"f1781791a93f437278aec85b811dbab9eca8d78ea82a829c8f1bb9b23f0002b7","width":512},{"frames":1,"height":512,"name":"spectral-14","samples":"634fa5e64811d8ef160d288bb260444947370250d48aa9ec28eaee2917329603","width":512},{"frames":1,"height":512,"name":"spectral-15","samples":"6b4e0483dcbf87c0968dbacb9d1e222df5531d7ba59c361e2438067c105dffed","width":512}]}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"algorithm":"wai-mark:tent64","algorithm_digest":"4e1bd9f2cac9420fc276434751a3fb9b2b0916128f200bf147009a86168be7d6","evidence":["8fc55defb78b6690b74e03b9cfaaf6ba502304e4bff77148bf5ce9d046b4ecdc"],"issued_at":"2026-10-22T09:00:00Z","kind":"wai-robustness-claim","sig":"ff9ac34690763fa0a4e54703b579f5301742edaf561019302fd8acdbead69dba97376bf732ef06294c28e1f386bc91ca9043f4480de1ce6ef677613da3d76b09","signer_pubkey":"42beefb73cbbe9063aef43732bae5add4da55b2a9e5f9701edb9e86242ff9b21","survives":[{"media":"image","params":[16],"transform":"wai-attack:int-motion"},{"media":"image","params":[1,2],"transform":"wai-attack:scale"},{"media":"image","params":[],"transform":"wai-attack:mirror"},{"media":"image","params":[],"transform":"wai-attack:rotate-90"},{"media":"image","params":[16],"transform":"wai-attack:noise"},{"media":"image","params":[4,5],"transform":"wai-attack:gamma"},{"media":"image","params":[5,4],"transform":"wai-attack:gamma"},{"media":"image","params":[3,2],"transform":"wai-attack:contrast"},{"media":"image","params":[32,1],"transform":"wai-attack:brightness"},{"media":"image","params":[1],"transform":"wai-attack:denoise3"}]}

View file

@ -0,0 +1 @@
{"algorithm":"wai-mark:tent64","algorithm_digest":"4e1bd9f2cac9420fc276434751a3fb9b2b0916128f200bf147009a86168be7d6","battery":[{"attack":"none","params":[],"seed":0,"transform":"wai-attack:none"},{"attack":"int-motion-q16","params":[16],"seed":1,"transform":"wai-attack:int-motion"},{"attack":"scale-1/2","params":[1,2],"seed":2,"transform":"wai-attack:scale"},{"attack":"crop-2%","params":[2],"seed":3,"transform":"wai-attack:crop"},{"attack":"mirror","params":[],"seed":4,"transform":"wai-attack:mirror"},{"attack":"rotate-90","params":[],"seed":5,"transform":"wai-attack:rotate-90"},{"attack":"rotate-1","params":[65526,1144,0],"seed":6,"transform":"wai-attack:rotate"},{"attack":"noise-16","params":[16],"seed":7,"transform":"wai-attack:noise"},{"attack":"gamma-4/5","params":[4,5],"seed":8,"transform":"wai-attack:gamma"},{"attack":"gamma-5/4","params":[5,4],"seed":9,"transform":"wai-attack:gamma"},{"attack":"contrast-3/2","params":[3,2],"seed":10,"transform":"wai-attack:contrast"},{"attack":"brightness-32","params":[32,1],"seed":11,"transform":"wai-attack:brightness"},{"attack":"denoise3","params":[1],"seed":12,"transform":"wai-attack:denoise3"}],"binding_type":"watermark","corpus":"363cd7a8267c1b340ddb8d095174a3e87ecbb66b8de84e922c68a4d80dab3379","harness":"wai-robustness-harness:1","issued_at":"2026-10-22T09:00:00Z","kind":"wai-robustness","media":"image","sig":"52c23916234135b64601ecb95a0baea73820060e758a52b779df79813aaf823f18adf71dbcd11b7a67a0ae32a5a67600241346cb63abe84ea9663a09c3694803","signer_pubkey":"670eebd5881bea34f6bc1709bc66bdf57061640efc8c89448454445363aedf75","table":[{"attack":"none","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"int-motion-q16","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"scale-1/2","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"crop-2%","balanced_accuracy":[1,2],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[0,1],"survived":0,"tpr_at_1pct_fpr":[0,1],"trials":3,"wrong":0},{"attack":"mirror","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"rotate-90","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"rotate-1","balanced_accuracy":[1,2],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[0,1],"survived":0,"tpr_at_1pct_fpr":[0,1],"trials":3,"wrong":0},{"attack":"noise-16","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"gamma-4/5","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"gamma-5/4","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"contrast-3/2","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"brightness-32","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0},{"attack":"denoise3","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":3,"survival":[1,1],"survived":3,"tpr_at_1pct_fpr":[1,1],"trials":3,"wrong":0}],"values":["030615f9ee08eb87","03d4a6a4685e0027","03c1cd09c0204c42"]}

View file

@ -0,0 +1 @@
{"algorithm":"wai-mark:tent64","algorithm_digest":"4e1bd9f2cac9420fc276434751a3fb9b2b0916128f200bf147009a86168be7d6","evidence":["efdaebdded9d4ade7e0b8fdbd9807373be3af3f83724c2e0133a28b02a5eb9cb","826a13f003e53197ed3042660bc89c4aa4f52f52d27a0ecbb07179e97bca3dbc","0d7a27ea74c39b111b0c97b0ab14646b6e1f82443ca1ea3608e0b3917b9a20dc"],"issued_at":"2026-10-22T09:00:00Z","kind":"wai-robustness-claim","sig":"36165039b2618447a59bb324a2095c3f86ef64c52b40a3b250d56ae2ddde4e357c55a84f29f947760ecc7d853843c509250ba313613365d8baa06adefd3c8f0b","signer_pubkey":"42beefb73cbbe9063aef43732bae5add4da55b2a9e5f9701edb9e86242ff9b21","survives":[{"media":"image","params":[4],"transform":"wai-attack:int-motion"},{"media":"image","params":[8],"transform":"wai-attack:int-motion"},{"media":"image","params":[16],"transform":"wai-attack:int-motion"},{"media":"image","params":[32],"transform":"wai-attack:int-motion"},{"media":"image","params":[48],"transform":"wai-attack:int-motion"},{"media":"image","params":[8],"transform":"wai-attack:staged-base"},{"media":"image","params":[1],"transform":"wai-attack:denoise3"},{"media":"image","params":[4],"transform":"wai-attack:denoise3"},{"media":"image","params":[3,4],"transform":"wai-attack:scale"},{"media":"image","params":[1,2],"transform":"wai-attack:scale"},{"media":"image","params":[3,2],"transform":"wai-attack:scale"},{"media":"image","params":[],"transform":"wai-attack:upscale2"},{"media":"image","params":[3,4],"transform":"wai-attack:aspect"},{"media":"image","params":[16],"transform":"wai-attack:half-then-int-motion"},{"media":"image","params":[],"transform":"wai-attack:mirror"},{"media":"image","params":[],"transform":"wai-attack:rotate-90"},{"media":"image","params":[4],"transform":"wai-attack:noise"},{"media":"image","params":[16],"transform":"wai-attack:noise"},{"media":"image","params":[32,0],"transform":"wai-attack:brightness"},{"media":"image","params":[32,1],"transform":"wai-attack:brightness"},{"media":"image","params":[1,2],"transform":"wai-attack:contrast"},{"media":"image","params":[3,2],"transform":"wai-attack:contrast"},{"media":"image","params":[],"transform":"wai-attack:local-blur"},{"media":"video","params":[8],"transform":"wai-attack:clip-int-motion"},{"media":"video","params":[24],"transform":"wai-attack:clip-int-motion"},{"media":"video","params":[],"transform":"wai-attack:frame-drop"},{"media":"video","params":[],"transform":"wai-attack:one-frame"},{"media":"video","params":[1,2],"transform":"wai-attack:scale"},{"media":"video","params":[16],"transform":"wai-attack:noise"}]}

View file

@ -0,0 +1 @@
{"algorithm":"wai-mark:tent64","algorithm_digest":"4e1bd9f2cac9420fc276434751a3fb9b2b0916128f200bf147009a86168be7d6","battery":[{"attack":"none","params":[],"seed":0,"transform":"wai-attack:none"},{"attack":"clip-int-motion-q8","params":[8],"seed":1,"transform":"wai-attack:clip-int-motion"},{"attack":"clip-int-motion-q24","params":[24],"seed":2,"transform":"wai-attack:clip-int-motion"},{"attack":"frame-drop","params":[],"seed":3,"transform":"wai-attack:frame-drop"},{"attack":"one-frame","params":[],"seed":4,"transform":"wai-attack:one-frame"},{"attack":"scale-1/2","params":[1,2],"seed":5,"transform":"wai-attack:scale"},{"attack":"noise-16","params":[16],"seed":6,"transform":"wai-attack:noise"}],"binding_type":"watermark","corpus":"1514e7d4cfcd93c3386b5707b0103908fafa2e86ddcffc16d762e96649b23b79","harness":"wai-robustness-harness:1","issued_at":"2026-10-22T09:00:00Z","kind":"wai-robustness","media":"video","sig":"1bbdf577439758833aaa5e458437f968379a618345dab1964ff9dc3c912f3f83c764458c8b9158354ff962657291086b8b5892d42d9c595bf54b0a76baf5ab03","signer_pubkey":"670eebd5881bea34f6bc1709bc66bdf57061640efc8c89448454445363aedf75","table":[{"attack":"none","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":4,"survival":[1,1],"survived":4,"tpr_at_1pct_fpr":[1,1],"trials":4,"wrong":0},{"attack":"clip-int-motion-q8","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":4,"survival":[1,1],"survived":4,"tpr_at_1pct_fpr":[1,1],"trials":4,"wrong":0},{"attack":"clip-int-motion-q24","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":4,"survival":[1,1],"survived":4,"tpr_at_1pct_fpr":[1,1],"trials":4,"wrong":0},{"attack":"frame-drop","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":4,"survival":[1,1],"survived":4,"tpr_at_1pct_fpr":[1,1],"trials":4,"wrong":0},{"attack":"one-frame","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":4,"survival":[1,1],"survived":4,"tpr_at_1pct_fpr":[1,1],"trials":4,"wrong":0},{"attack":"scale-1/2","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":4,"survival":[1,1],"survived":4,"tpr_at_1pct_fpr":[1,1],"trials":4,"wrong":0},{"attack":"noise-16","balanced_accuracy":[1,1],"false_positive_rate":[0,1],"false_positives":0,"negatives":4,"survival":[1,1],"survived":4,"tpr_at_1pct_fpr":[1,1],"trials":4,"wrong":0}],"values":["03bb3cfa94424bff","034102f5c82d7f5d","03684fc7c08217c6","036174ca28b996ce"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,948 @@
#!/usr/bin/env python3
"""Second implementation of extensions/robustness-evidence.md (`wai.media.robustness`), over the
corpus `live-conformance/robustness/`.
Written from the extension's text. It shares no code with wai-rs: it reads every record as §2
has it read (strict JSON, the encodings of jwp-receipts §2.4.3, rates read last as exact
fractions), applies the transforms of §4, runs the harness of §6 with `wai-mark:tent64` as the
synthesis corpus's second implementation has it (_wai_mark.py, written from synthesis §7.5),
and rerun end to end on the samples the corpus holds, requires the conformance record's table
bit for bit. It verifies every signature with WAI's strict Ed25519 rule
(claim-conformance/_ed25519.py) and every link hash with BLAKE3 written from its specification
(claim-conformance/_blake3.py). It reads §12's codes from the extension, checks the records of
`wai-mark:tent64` against the synthesis corpus's battery.json — a measurement another program
wrote — and the claim against synthesis §7.5.8's text.
python3 -I robustness_verify.py <live-conformance/robustness>
It gives every case the outcome, the reason, the record and the statements the corpus states,
and checks that every reason of §12 refuses a case. Then it mutates copies of the corpus and
requires every copy to fail, and drops each of its own checks in turn and requires the corpus
to catch the weakened verifier. Exit status 0 only if all of that holds. Python 3.8 or later;
standard library only.
"""
import copy
import hashlib
import json
import math
import os
import re
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
sys.path.insert(0, os.path.join(HERE, "..", "claim-conformance"))
import _wai_mark as M # noqa: E402 (synthesis §7.5, written from the extension's text)
import _ed25519 as ED # noqa: E402
from _blake3 import blake3 # noqa: E402
WAI = os.path.join(HERE, "..")
EXTENSION = os.path.join(WAI, "extensions", "robustness-evidence.md")
SYNTHESIS = os.path.join(WAI, "extensions", "synthesis.md")
SIGN_DOMAIN = b"wai:robustness\x01" # §2
LINK_DOMAIN = b"wai:robustness-link\x01" # §2
RECORD, CLAIM, CORPUS = "wai-robustness", "wai-robustness-claim", "wai-robustness-corpus"
HARNESS = "wai-robustness-harness:1" # §6
MAX_INT = (1 << 53) - 1
FRAME_CAP, ITEM_CAP = 1 << 26, 1 << 30 # §9.1
RECORD_MEMBERS = ["kind", "algorithm", "algorithm_digest", "binding_type", "media", "corpus", "values", "battery",
"harness", "table", "issued_at", "signer_pubkey", "sig"]
ROW_MEMBERS = ["attack", "trials", "survived", "wrong", "negatives", "false_positives", "survival",
"false_positive_rate", "balanced_accuracy", "tpr_at_1pct_fpr"]
RATES = ["survival", "false_positive_rate", "balanced_accuracy", "tpr_at_1pct_fpr"]
CLAIM_MEMBERS = ["kind", "algorithm", "algorithm_digest", "survives", "evidence", "issued_at", "signer_pubkey", "sig"]
WHITE_SPACE = set("\t\n\x0b\x0c\r \x85\xa0           "
" 

   ")
# A check named here is left out: the verifier weakened on purpose, to show the corpus catches it.
SKIP = set()
class Refuse(Exception):
def __init__(self, reason):
super().__init__(reason)
self.reason = reason
class Bad(Exception):
"""A record that does not read: `record_malformed`."""
class Number:
"""A JSON number that is not an unsigned integer of §2: kept, so that a rate member holding
one is `rate_not_exact` and any other member holding one is `record_malformed`."""
def need(c, reason=None):
if not c:
raise Refuse(reason) if reason else Bad()
def sha(b):
return hashlib.sha256(b).digest()
# ---------------------------------------------------------------- §2 reading
def strict_json(text):
"""RFC 8259, no member named twice, no boolean, no unpaired surrogate, at most 32 levels;
a number that is not an unsigned integer of at most 2^53 − 1 is kept as a Number."""
def pairs(ps):
d = {}
for k, x in ps:
if k in d:
raise Bad()
d[k] = x
return d
def no(s):
raise Bad()
def integer(s):
if s.startswith("-"):
return Number()
n = int(s)
return n if n <= MAX_INT else Number()
try:
v = json.loads(text, object_pairs_hook=pairs, parse_float=lambda s: Number(), parse_int=integer, parse_constant=no)
except (ValueError, RecursionError):
raise Bad()
def walk(x, depth):
if isinstance(x, (dict, list)):
need(depth <= 32)
for y in (x.values() if isinstance(x, dict) else x):
walk(y, depth + 1)
elif isinstance(x, str):
need(not any(0xD800 <= ord(c) <= 0xDFFF for c in x))
elif isinstance(x, bool):
raise Bad()
walk(v, 1)
return v
def subset(x):
"""§2's values: strings, unsigned integers, null, and arrays and objects of them."""
if x is None or isinstance(x, str):
return True
if isinstance(x, bool) or isinstance(x, Number):
return False
if isinstance(x, int):
return 0 <= x <= MAX_INT
if isinstance(x, list):
return all(subset(y) for y in x)
if isinstance(x, dict):
return all(subset(y) for y in x.values())
return False
def jstr(s):
out = ['"']
for c in s:
o = ord(c)
if c == '"':
out.append('\\"')
elif c == "\\":
out.append("\\\\")
elif c == "\b":
out.append("\\b")
elif c == "\f":
out.append("\\f")
elif c == "\n":
out.append("\\n")
elif c == "\r":
out.append("\\r")
elif c == "\t":
out.append("\\t")
elif o < 0x20:
out.append("\\u%04x" % o)
else:
out.append(c)
out.append('"')
return "".join(out)
def jcs(v):
"""RFC 8785 over strings, unsigned integers, null, arrays and objects."""
if v is None:
return "null"
if isinstance(v, bool) or isinstance(v, Number):
raise Bad()
if isinstance(v, int):
return str(v)
if isinstance(v, str):
return jstr(v)
if isinstance(v, list):
return "[" + ",".join(jcs(x) for x in v) + "]"
keys = sorted(v, key=lambda k: k.encode("utf-16-be"))
return "{" + ",".join(jstr(k) + ":" + jcs(v[k]) for k in keys) + "}"
def link_hash(v):
return blake3(LINK_DOMAIN + jcs(v).encode("utf-8"))
def signing_bytes(v):
return SIGN_DOMAIN + jcs({k: x for k, x in v.items() if k != "sig"}).encode("utf-8")
def is_uint(x):
return isinstance(x, int) and not isinstance(x, bool) and 0 <= x <= MAX_INT
def is_hex(x, n=None):
return (isinstance(x, str) and len(x) % 2 == 0 and all(c in "0123456789abcdef" for c in x)
and (n is None or len(x) == 2 * n))
def is_term(s):
return (isinstance(s, str) and 1 <= len(s.encode("utf-8")) <= 2048
and not any(c in WHITE_SPACE or ord(c) < 0x20 or 0x7F <= ord(c) <= 0x9F for c in s))
def date_time(s):
"""RFC 3339 date-time, the day within its month (jwp-receipts §2.4.3)."""
if not (isinstance(s, str) and len(s) >= 20 and s.isascii()):
return False
if not all(s[i].isdigit() for i in (0, 1, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 17, 18)):
return False
if not (s[4] == "-" and s[7] == "-" and s[10] in "Tt" and s[13] == ":" and s[16] == ":"):
return False
yr, mo, da, hh, mi, ss = int(s[0:4]), int(s[5:7]), int(s[8:10]), int(s[11:13]), int(s[14:16]), int(s[17:19])
leap = yr % 4 == 0 and (yr % 100 != 0 or yr % 400 == 0)
days = [31, 29 if leap else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if not (1 <= mo <= 12 and 1 <= da <= days[mo - 1] and hh <= 23 and mi <= 59 and ss <= 60):
return False
i = 19
if i < len(s) and s[i] == ".":
j = i + 1
while j < len(s) and s[j].isdigit():
j += 1
if j == i + 1:
return False
i = j
rest = s[i:]
if rest in ("Z", "z"):
return True
return (len(rest) == 6 and rest[0] in "+-" and rest[1:3].isdigit() and rest[3] == ":" and rest[4:6].isdigit()
and int(rest[1:3]) <= 23 and int(rest[4:6]) <= 59)
def exact(v, names):
need(isinstance(v, dict) and set(v) == set(names))
return v
def read_frame(text, kind, names):
v = strict_json(text)
exact(v, names)
need(v["kind"] == kind)
need(is_hex(v["signer_pubkey"], 32) and is_hex(v["sig"], 64))
need(date_time(v["issued_at"]))
return v
def check_signature(v):
if "signature" in SKIP:
return
r = ED.verify(bytes.fromhex(v["signer_pubkey"]), signing_bytes(v), bytes.fromhex(v["sig"]))
if r:
raise Refuse(r)
def rate(x):
"""§7: [n, d], 1 <= d, n <= d, in lowest terms."""
ok = (isinstance(x, list) and len(x) == 2 and all(is_uint(y) for y in x) and x[1] >= 1 and x[0] <= x[1]
and math.gcd(x[0], x[1]) == 1)
if not ok and "exact-rates" not in SKIP:
raise Refuse("rate_not_exact")
return tuple(x) if isinstance(x, list) else x
def read_evidence(text):
"""§2 and §5: the record, every member but the rates, then the rates, then the signature."""
v = read_frame(text, RECORD, RECORD_MEMBERS)
rest = copy.deepcopy(v)
if isinstance(rest["table"], list):
for r in rest["table"]:
if isinstance(r, dict):
for k in RATES:
r.pop(k, None)
need(subset(rest))
need(v["binding_type"] in ("watermark", "fingerprint"))
need(isinstance(v["values"], list) and all(is_hex(x) and x != "" for x in v["values"]))
need(isinstance(v["battery"], list))
for a in v["battery"]:
exact(a, ["attack", "transform", "params", "seed"])
need(is_term(a["attack"]) and is_term(a["transform"]) and isinstance(a["params"], list)
and all(is_uint(p) for p in a["params"]) and is_uint(a["seed"]))
need(isinstance(v["table"], list))
for r in v["table"]:
exact(r, ROW_MEMBERS)
need(is_term(r["attack"]) and all(is_uint(r[k]) for k in ROW_MEMBERS[1:6]))
need(is_term(v["algorithm"]) and is_hex(v["algorithm_digest"], 32) and v["media"] in ("image", "video")
and is_hex(v["corpus"], 32) and is_term(v["harness"]))
rates = []
for r in v["table"]:
rates.append(tuple(None if (k == "tpr_at_1pct_fpr" and r[k] is None) else rate(r[k]) for k in RATES))
check_signature(v)
return v, rates
def read_claim(text):
v = read_frame(text, CLAIM, CLAIM_MEMBERS)
need(subset(v))
need(isinstance(v["survives"], list) and len(v["survives"]) >= 1)
for c in v["survives"]:
exact(c, ["media", "transform", "params"])
need(c["media"] in ("image", "video") and is_term(c["transform"]) and isinstance(c["params"], list)
and all(is_uint(p) for p in c["params"]))
need(len({jcs(c) for c in v["survives"]}) == len(v["survives"]))
need(isinstance(v["evidence"], list) and all(is_hex(e, 32) for e in v["evidence"]))
need(len(set(v["evidence"])) == len(v["evidence"]))
need(is_term(v["algorithm"]) and is_hex(v["algorithm_digest"], 32))
check_signature(v)
return v
# ---------------------------------------------------------------- §3 the corpus
def read_corpus(text):
"""§3: the document, or `corpus_malformed`."""
try:
v = strict_json(text)
exact(v, ["kind", "name", "media", "items", "negatives"])
need(subset(v) and v["kind"] == CORPUS and is_term(v["name"]) and v["media"] in ("image", "video"))
for k in ("items", "negatives"):
need(isinstance(v[k], list) and len(v[k]) >= 1)
for i in v[k]:
exact(i, ["name", "frames", "width", "height", "samples"])
need(is_term(i["name"]) and all(is_uint(i[x]) and i[x] >= 1 for x in ("frames", "width", "height"))
and is_hex(i["samples"], 32))
need(v["media"] == "video" or i["frames"] == 1)
need(i["frames"] * i["width"] * i["height"] * 3 <= MAX_INT)
need(len({i["name"] for i in v[k]}) == len(v[k]))
except Bad:
raise Refuse("corpus_malformed")
return v
# ---------------------------------------------------------------- §4 the transforms
def r(lo, hi):
return lambda x: lo <= x <= hi
# term: (parameter checks, media); a check per parameter, then any relation across them.
TRANSFORMS = {
"wai-attack:none": ([], None),
"wai-attack:int-motion": ([r(1, 255)], None),
"wai-attack:staged-base": ([r(1, 255)], None),
"wai-attack:denoise3": ([r(1, 16)], None),
"wai-attack:scale": ([r(1, 16), r(1, 16)], lambda p: p[0] <= 2 * p[1]),
"wai-attack:aspect": ([r(1, 16), r(1, 16)], lambda p: p[0] <= 2 * p[1]),
"wai-attack:upscale2": ([], None),
"wai-attack:half-then-int-motion": ([r(1, 255)], None),
"wai-attack:crop": ([r(0, 99)], None),
"wai-attack:mirror": ([], None),
"wai-attack:rotate-90": ([], None),
"wai-attack:rotate": ([r(0, 65536), r(0, 65536), r(0, 1)], None),
"wai-attack:noise": ([r(0, 255)], None),
"wai-attack:brightness": ([r(0, 255), r(0, 1)], None),
"wai-attack:contrast": ([r(1, 16), r(1, 16)], None),
"wai-attack:gamma": ([r(1, 6), r(1, 6)], None),
"wai-attack:local-blur": ([], None),
"wai-attack:clip-int-motion": ([r(1, 255)], None),
"wai-attack:frame-drop": ([], None),
"wai-attack:one-frame": ([], None),
}
VIDEO_ONLY = {"wai-attack:clip-int-motion", "wai-attack:frame-drop", "wai-attack:one-frame"}
def transform_ok(term, params):
"""§4: True for a registered transform whose parameters fit, None for an unregistered term;
`transform_invalid` otherwise."""
if term not in TRANSFORMS:
return None
checks, rel = TRANSFORMS[term]
ok = len(params) == len(checks) and all(c(p) for c, p in zip(checks, params)) and (rel is None or rel(params))
if not ok and "transform-ranges" not in SKIP:
raise Refuse("transform_invalid")
return True
def gamma_table(n, d):
"""§4 Gamma: the greatest y with y = 0 or (2y - 1)^d * 255^n <= 2^d * v^n * 255^d."""
t = []
for v in range(256):
rhs = 2 ** d * v ** n * 255 ** d
y = 0
while y < 255 and (2 * (y + 1) - 1) ** d * 255 ** n <= rhs:
y += 1
t.append(y)
return t
def per_frame(px, w, h, n, f):
"""Apply f(frame) -> (frame', w', h') to each of n frames."""
fb = w * h * 3
out, nw, nh = [], w, h
for i in range(n):
g, nw, nh = f(px[i * fb:(i + 1) * fb])
out.append(g)
return b"".join(out), nw, nh, n
def apply(term, p, px, w, h, n, seed):
"""§4: (samples, width, height, frames) of a registered transform applied at `seed`."""
empty = (b"", 0, 0, n)
if term == "wai-attack:none":
return px, w, h, n
if term == "wai-attack:int-motion":
return per_frame(px, w, h, n, lambda fr: (M.int_motion(fr, p[0]), w, h))
if term in ("wai-attack:staged-base", "wai-attack:half-then-int-motion") and (w < 2 or h < 2):
return empty
if term == "wai-attack:staged-base":
def staged(fr):
hw, hh = w // 2, h // 2
half = bytearray(hw * hh * 3)
for y in range(hh):
for x in range(hw):
for c in range(3):
s = sum(fr[((2 * y + dy) * w + 2 * x + dx) * 3 + c] for dy in (0, 1) for dx in (0, 1))
half[(y * hw + x) * 3 + c] = (s + 2) >> 2
return M.upscale2(M.int_motion(bytes(half), p[0]), hw, hh), 2 * hw, 2 * hh
return per_frame(px, w, h, n, staged)
if term == "wai-attack:denoise3":
def dn(fr):
for _ in range(p[0]):
fr = M.denoise3(fr, w, h)
return fr, w, h
return per_frame(px, w, h, n, dn)
if term == "wai-attack:scale":
nw, nh = w * p[0] // p[1], h * p[0] // p[1]
if nw == 0 or nh == 0:
return empty
return per_frame(px, w, h, n, lambda fr: (M.area(fr, w, h, nw, nh), nw, nh))
if term == "wai-attack:aspect":
nw = w * p[0] // p[1]
if nw == 0:
return empty
return per_frame(px, w, h, n, lambda fr: (M.area(fr, w, h, nw, h), nw, h))
if term == "wai-attack:upscale2":
return per_frame(px, w, h, n, lambda fr: (M.upscale2(fr, w, h), 2 * w, 2 * h))
if term == "wai-attack:half-then-int-motion":
nw, nh = w // 2, h // 2
return per_frame(px, w, h, n, lambda fr: (M.int_motion(M.area(fr, w, h, nw, nh), p[0]), nw, nh))
if term == "wai-attack:crop":
dx, dy = w * p[0] // 200, h * p[0] // 200
nw, nh = w - 2 * dx, h - 2 * dy
return per_frame(px, w, h, n, lambda fr: (b"".join(fr[(y * w + dx) * 3:(y * w + dx + nw) * 3] for y in range(dy, dy + nh)), nw, nh))
if term == "wai-attack:mirror":
return per_frame(px, w, h, n, lambda fr: (b"".join(fr[(y * w + x) * 3:(y * w + x) * 3 + 3]
for y in range(h) for x in range(w - 1, -1, -1)), w, h))
if term == "wai-attack:rotate-90":
return per_frame(px, w, h, n, lambda fr: (b"".join(fr[((h - 1 - xp) * w + yp) * 3:((h - 1 - xp) * w + yp) * 3 + 3]
for yp in range(w) for xp in range(h)), h, w))
if term == "wai-attack:rotate":
s = -p[1] if p[2] == 1 else p[1]
return per_frame(px, w, h, n, lambda fr: (M.rotate(fr, w, h, p[0], s), w, h))
if term == "wai-attack:noise":
st = M.stream(b"wai-mark:battery noise", seed)
return bytes(M.clamp(v + next(st) % (2 * p[0] + 1) - p[0]) for v in px), w, h, n
if term == "wai-attack:brightness":
b = -p[0] if p[1] == 1 else p[0]
return bytes(M.clamp(v + b) for v in px), w, h, n
if term == "wai-attack:contrast":
return bytes(M.clamp(128 + M.rnd((v - 128) * p[0], p[1])) for v in px), w, h, n
if term == "wai-attack:gamma":
t = gamma_table(p[0], p[1])
return bytes(t[v] for v in px), w, h, n
if term == "wai-attack:local-blur":
return per_frame(px, w, h, n, lambda fr: M.attack("local-blur", fr, w, h, seed))
if term == "wai-attack:frame-drop":
fb = w * h * 3
kept = list(range(0, n, 2))
return b"".join(px[i * fb:(i + 1) * fb] for i in kept), w, h, len(kept)
if term == "wai-attack:one-frame":
return px[:w * h * 3], w, h, 1
raise NotImplementedError(term)
# ---------------------------------------------------------------- the algorithm and §6
def tent64_digest():
"""synthesis §7.4: the definition's digest, as its text states it, which is the SHA-256 of
the synthesis corpus's scheme.json."""
s = " ".join(open(SYNTHESIS, encoding="utf-8").read().split())
m = re.search(r"and its digest is `([0-9a-f]{64})`", s)
stated = m.group(1) if m else None
with open(os.path.join(HERE, "synthesis-mark", "scheme.json"), "rb") as f:
computed = hashlib.sha256(f.read()).hexdigest()
return stated if stated == computed else None
TENT64 = M.SCHEME
TENT64_DIGEST = tent64_digest()
def value_ok(v):
"""§5 check 5: a payload of synthesis §7.2."""
b = bytes.fromhex(v)
return len(b) == 8 and b[0] <= 3
HARNESS_MEMO = {}
def run_harness(items, negatives, values, battery):
"""§6 for wai-mark:tent64: the counts of each attack, in order. `items` and `negatives` are
(samples, width, height, frames)."""
key = (tuple(sha(i[0]) for i in items), tuple(sha(i[0]) for i in negatives), tuple(values),
jcs([[a["transform"], a["params"], a["seed"]] for a in battery]))
if key in HARNESS_MEMO:
return HARNESS_MEMO[key]
marked = []
for (px, w, h, n), v in zip(items, values):
payload = bytes.fromhex(v)
marked.append((M.embed(px, w, h, n, payload)[0] if M.admits(w, h, n) else px, w, h, n))
rows = []
for a in battery:
t, p, s = a["transform"], a["params"], a["seed"]
survived = wrong = fp = 0
for (px, w, h, n), v in zip(marked, values):
got = M.detect(*apply(t, p, px, w, h, n, s))
if got is not None:
if got[0].hex() == v:
survived += 1
else:
wrong += 1
for px, w, h, n in negatives:
if M.detect(*apply(t, p, px, w, h, n, s)) is not None:
fp += 1
rows.append((len(items), survived, wrong, len(negatives), fp))
HARNESS_MEMO[key] = rows
return rows
# ---------------------------------------------------------------- §7 rates
def reduce_(n, d):
g = math.gcd(n, d) or 1
return (n // g, d // g)
def rates_of(trials, survived, negatives, fp):
sv = reduce_(survived, trials)
return (sv, reduce_(fp, negatives), reduce_(survived * negatives + (negatives - fp) * trials, 2 * trials * negatives),
sv if 100 * fp <= negatives else None)
# ---------------------------------------------------------------- §5 and §8 checks
def check_evidence(v, rates, corpus_text, case):
"""§5's checks 1 to 8: the record's status."""
battery, table = v["battery"], v["table"]
# 1.
need(len(battery) >= 1 and len({a["attack"] for a in battery}) == len(battery)
and all(a["seed"] < 2 ** 32 for a in battery), "battery_malformed")
reg = [transform_ok(a["transform"], a["params"]) for a in battery]
if "media" not in SKIP:
need(not any(ok and v["media"] == "image" and a["transform"] in VIDEO_ONLY for ok, a in zip(reg, battery)),
"battery_not_applicable")
# 2.
need(len(table) == len(battery) and all(r["attack"] == a["attack"] for r, a in zip(table, battery)), "table_malformed")
# 3.
neg = table[0]["negatives"]
if "counts" not in SKIP:
for row in table:
need(row["trials"] == len(v["values"]) and row["trials"] >= 1 and row["survived"] + row["wrong"] <= row["trials"]
and row["negatives"] >= 1 and row["negatives"] == neg and row["false_positives"] <= row["negatives"],
"table_inconsistent")
# 4.
if "rates" not in SKIP:
for row, rt in zip(table, rates):
need(rates_of(row["trials"], row["survived"], row["negatives"], row["false_positives"]) == rt, "rate_mismatch")
# 5.
registered = v["algorithm"] == TENT64
if registered:
need(v["algorithm_digest"] == TENT64_DIGEST and v["binding_type"] == "watermark", "algorithm_mismatch")
if "values" not in SKIP:
need(all(value_ok(x) for x in v["values"]), "values_invalid")
# 6.
if corpus_text is None:
return "stated"
doc = read_corpus(corpus_text)
if "corpus-digest" not in SKIP:
need(hashlib.sha256(jcs(doc).encode("utf-8")).hexdigest() == v["corpus"] and doc["media"] == v["media"], "corpus_mismatch")
need(len(doc["items"]) == len(v["values"]) and len(doc["negatives"]) == neg, "table_inconsistent")
# 7.
every = doc["items"] + doc["negatives"]
if "sizes" not in SKIP:
for i in every:
s = case["samples"].get(i["samples"])
need(s is None or len(s) == i["frames"] * i["width"] * i["height"] * 3, "samples_mismatch")
# 8.
held = all(i["samples"] in case["samples"] for i in every)
bounded = all(i["width"] * i["height"] * 3 <= FRAME_CAP and i["frames"] * i["width"] * i["height"] * 3 <= ITEM_CAP
for i in every)
runnable = registered and TENT64 in case["implements"]
if not (runnable and held and bounded and v["harness"] == HARNESS and all(reg)) or "rerun" in SKIP:
return "stated"
frames = lambda i: (case["samples"][i["samples"]], i["width"], i["height"], i["frames"]) # noqa: E731
got = run_harness([frames(i) for i in doc["items"]], [frames(i) for i in doc["negatives"]], v["values"], battery)
want = [(r["trials"], r["survived"], r["wrong"], r["negatives"], r["false_positives"]) for r in table]
need(got == want, "table_irreproducible")
return "reproduced"
def check_claim(v, held, require_reproduced):
"""§8: the claim's status."""
cited = []
for link in v["evidence"]:
need(link in held, "evidence_not_held")
h = held[link]
need(h["v"]["algorithm"] == v["algorithm"] and h["v"]["algorithm_digest"] == v["algorithm_digest"], "evidence_mismatch")
cited.append(h)
if require_reproduced:
need(all(h["status"] == "reproduced" for h in cited), "evidence_not_reproduced")
for c in v["survives"]:
measured = False
for h in cited:
if h["v"]["media"] != c["media"]:
continue
for a, row in zip(h["v"]["battery"], h["v"]["table"]):
if a["transform"] == c["transform"] and a["params"] == c["params"]:
measured = True
if "survival" not in SKIP:
need(row["survived"] == row["trials"] and row["wrong"] == 0 and row["false_positives"] == 0,
"claim_exceeds_evidence")
need(measured, "claim_unevidenced")
return "reproduced" if all(h["status"] == "reproduced" for h in cited) else "stated"
def verify_case(case):
"""§9.2: ("accept", statements) or ("refuse", reason, position)."""
held, out = {}, []
for i, text in enumerate(case["records"]):
try:
try:
kind = strict_json(text).get("kind")
except (Bad, AttributeError):
kind = None
if kind == RECORD:
v, rates = read_evidence(text)
status = check_evidence(v, rates, case["corpora"].get(i), case)
link = link_hash(v).hex()
held[link] = {"v": v, "status": status}
out.append({"kind": RECORD, "link": link, "status": status, "algorithm": v["algorithm"], "corpus": v["corpus"],
"attacks": len(v["battery"])})
elif kind == CLAIM:
v = read_claim(text)
status = check_claim(v, held, case["require_reproduced"])
out.append({"kind": CLAIM, "link": link_hash(v).hex(), "status": status, "algorithm": v["algorithm"],
"attacks": len(v["survives"])})
else:
raise Bad()
except Bad:
return ("refuse", "record_malformed", i)
except Refuse as e:
return ("refuse", e.reason, i)
return ("accept", out)
# ---------------------------------------------------------------- the corpus's cases
def load(corpus_dir):
files = {}
for root, _, names in os.walk(corpus_dir):
for n in names:
p = os.path.join(root, n)
rel = os.path.relpath(p, corpus_dir).replace(os.sep, "/")
if rel != "README.md":
with open(p, "rb") as f:
files[rel] = f.read()
return files
def case_of(c, files):
corpora = {}
for g in c["corpora"]:
corpora[g["record"]] = files[g["file"]].decode("utf-8") if "file" in g else g["text"]
samples = {}
for h in c["samples"]:
b = files.get("frames/%s.rgb" % h)
if b is not None and hashlib.sha256(b).hexdigest() == h:
samples[h] = b
return {"records": c["records"], "corpora": corpora, "samples": samples, "implements": c["implements"],
"require_reproduced": c["policy"]["evidence"] == "reproduced"}
def outcome(r):
if r[0] == "accept":
return {"outcome": "accept", "statements": r[1]}
return {"outcome": "refuse", "reason": r[1], "record": r[2]}
def check(doc, files, quiet=False, only=None):
fails = []
for c in doc["cases"]:
if only is not None and c["name"] not in only:
continue
got = outcome(verify_case(case_of(c, files)))
ok = got == c["expected"]
if not quiet:
print(("PASS" if ok else "FAIL") + " %s" % c["name"])
if not ok:
fails.append("%s: expected %s, got %s" % (c["name"], json.dumps(c["expected"])[:160], json.dumps(got)[:160]))
return fails
# ---------------------------------------------------------------- the corpus's files and texts
def reasons_of_extension():
s = open(EXTENSION, encoding="utf-8").read()
at = s.index("\n## 12. Reasons")
end = s.index("\n## 13.", at)
return re.findall(r"^\| `([a-z_]+)` \|", s[at:end], re.M)
def transforms_of_extension():
s = open(EXTENSION, encoding="utf-8").read()
at = s.index("\n## 4. The transforms")
end = s.index("\n## 5.", at)
return re.findall(r"^\| `(wai-attack:[a-z0-9-]+)` \|", s[at:end], re.M)
def synthesis_claims():
"""synthesis §7.5.8's claims: (pictures, clips), by name."""
s = open(SYNTHESIS, encoding="utf-8").read()
at = s.index("\n#### 7.5.8 ")
end = s.index("\n### 7.6", at)
t = " ".join(s[at:end].split())
m = re.search(r"For pictures, these attacks, each with the parameter measured: (.*?)\. For clips: (.*?)\.", t)
return re.findall(r"`([^`]+)`", m.group(1)), re.findall(r"`([^`]+)`", m.group(2))
ROTATIONS = {"rotate-0.5": [65534, 572, 0], "rotate-1": [65526, 1144, 0], "rotate-2": [65496, 2287, 0]}
def transform_of_name(name):
"""§10's table: a name of synthesis §7.5.7 as a transform and its parameters."""
m = re.fullmatch(r"(clip-int-motion|int-motion|staged-base|half-then-int-motion)-q(\d+)", name)
if m:
return "wai-attack:" + m.group(1), [int(m.group(2))]
m = re.fullmatch(r"(scale|aspect|contrast)-(\d+)/(\d+)", name)
if m:
return "wai-attack:" + m.group(1), [int(m.group(2)), int(m.group(3))]
m = re.fullmatch(r"crop-(\d+)%", name)
if m:
return "wai-attack:crop", [int(m.group(1))]
m = re.fullmatch(r"noise-(\d+)", name)
if m:
return "wai-attack:noise", [int(m.group(1))]
if name in ROTATIONS:
return "wai-attack:rotate", ROTATIONS[name]
if name == "denoise3":
return "wai-attack:denoise3", [1]
if name == "denoise3-x4":
return "wai-attack:denoise3", [4]
if name in ("brightness+32", "brightness-32"):
return "wai-attack:brightness", [32, 1 if name.endswith("-32") else 0]
if name in ("none", "upscale2", "mirror", "rotate-90", "local-blur", "frame-drop", "one-frame"):
return "wai-attack:" + name, []
raise ValueError(name)
def check_tent64(files):
"""§10: the records' batteries are synthesis §7.5.7's lists by §10's table and their seeds the
index; their tables and values are battery.json's; the claim is synthesis §7.5.8's list."""
fails = []
with open(os.path.join(HERE, "synthesis-mark", "battery.json"), encoding="utf-8") as f:
battery = json.load(f)
payload = {p["name"]: p["payload"] for p in battery["pictures"]}
lists = {"image": battery["image_attacks"], "video": battery["clip_attacks"]}
links = []
for name in ("tent64-spectral", "tent64-leaves", "tent64-clips"):
v = strict_json(files["records/%s.json" % name].decode("utf-8"))
links.append(link_hash(v).hex())
doc = strict_json(files["corpus/%s.json" % name].decode("utf-8"))
st = name[len("tent64-"):]
want_b = [{"attack": n, "transform": transform_of_name(n)[0], "params": transform_of_name(n)[1], "seed": i}
for i, n in enumerate(lists[v["media"]])]
if v["battery"] != want_b:
fails.append("%s: its battery is not synthesis 7.5.7's list" % name)
if v["values"] != [payload[i["name"]] for i in doc["items"]]:
fails.append("%s: its values are not battery.json's payloads" % name)
if hashlib.sha256(jcs(doc).encode()).hexdigest() != v["corpus"]:
fails.append("%s: its corpus file is not its corpus" % name)
for row in v["table"]:
t = next(x for x in battery["table"] if x["attack"] == row["attack"] and x["set"] == st)
u = next(x for x in battery["unmarked"] if x["attack"] == row["attack"] and x["set"] == st)
if (row["trials"], row["survived"], row["wrong"], row["negatives"], row["false_positives"]) != \
(t["trials"], t["detected"], t["wrong"], u["trials"], u["detections"]):
fails.append("%s %s: the row is not battery.json's" % (name, row["attack"]))
claim = strict_json(files["records/tent64-claim.json"].decode("utf-8"))
pics, clips = synthesis_claims()
want = ([{"media": "image", "transform": transform_of_name(n)[0], "params": transform_of_name(n)[1]} for n in pics]
+ [{"media": "video", "transform": transform_of_name(n)[0], "params": transform_of_name(n)[1]} for n in clips])
if claim["survives"] != want:
fails.append("the tent64 claim is not synthesis 7.5.8's list")
if claim["evidence"] != links:
fails.append("the tent64 claim does not cite the three records")
return fails
def check_files(doc, files):
"""The corpus documents are canonical, each frame file is named by its SHA-256, the records'
files are the texts the accepted cases verify, and nothing else is there."""
fails = []
for k, b in files.items():
if k.startswith("corpus/"):
if jcs(strict_json(b.decode("utf-8"))).encode("utf-8") != b:
fails.append("%s is not its JCS" % k)
elif k.startswith("frames/"):
if k != "frames/%s.rgb" % hashlib.sha256(b).hexdigest():
fails.append("%s is not named by its SHA-256" % k)
elif k.startswith("records/"):
pass
elif k != "vectors.json":
fails.append("an extra file: %s" % k)
by_name = {c["name"]: c for c in doc["cases"]}
want = {
"records/conformance.json": by_name["conformance_reproduced"]["records"][0],
"records/conformance-claim.json": by_name["conformance_claim_reproduced"]["records"][1],
"records/tent64-spectral.json": by_name["tent64_records_and_claim"]["records"][0],
"records/tent64-leaves.json": by_name["tent64_records_and_claim"]["records"][1],
"records/tent64-clips.json": by_name["tent64_records_and_claim"]["records"][2],
"records/tent64-claim.json": by_name["tent64_records_and_claim"]["records"][3],
}
for k, t in want.items():
if files.get(k) != t.encode("utf-8"):
fails.append("%s is not the text its accepted case verifies" % k)
for k in files:
if k.startswith("records/") and k not in want:
fails.append("an extra record: %s" % k)
return fails
# ---------------------------------------------------------------- mutations and weakened checks
def edit_case(doc, name, f):
d = copy.deepcopy(doc)
c = next(c for c in d["cases"] if c["name"] == name)
f(c)
return d, name
def edit_record(doc, name, i, f):
"""A case's record edited by f and left with its signature, which then fails, or with
rates and counts that no longer agree."""
def g(c):
v = json.loads(c["records"][i])
f(v)
c["records"][i] = json.dumps(v, separators=(",", ":"))
return edit_case(doc, name, g)
def mutations(doc, files):
"""Copies of the corpus, or of its files, with one defect each: (label, doc, files, case)."""
out = []
def m(label, pair, fs=None):
out.append((label, pair[0], fs if fs is not None else files, pair[1]))
m("a reproduced record's survived count changed", edit_record(doc, "conformance_reproduced", 0,
lambda v: v["table"][0].__setitem__("survived", 2)))
m("a reproduced record's seed changed", edit_record(doc, "conformance_reproduced", 0,
lambda v: v["battery"][7].__setitem__("seed", 99)))
m("a stated record's rate written as a decimal", edit_case(doc, "tent64_records_and_claim",
lambda c: c["records"].__setitem__(0, c["records"][0].replace('"survival":[1,1]', '"survival":1.0', 1))))
m("the claim given a stated record's corpus file from another set", edit_case(doc, "tent64_records_and_claim",
lambda c: c["corpora"][0].__setitem__("file", "corpus/tent64-leaves.json")))
m("the policy switched to require reproduced evidence", edit_case(doc, "tent64_records_and_claim",
lambda c: c["policy"].__setitem__("evidence", "reproduced")))
m("the samples dropped from a reproduced case", edit_case(doc, "conformance_reproduced", lambda c: c.__setitem__("samples", [])))
m("an accepted statement's status changed", edit_case(doc, "conformance_stated_without_samples",
lambda c: c["expected"]["statements"][0].__setitem__("status", "reproduced")))
m("a refusal's reason changed", edit_case(doc, "claim_crop_10_exceeds",
lambda c: c["expected"].__setitem__("reason", "claim_unevidenced")))
m("the claim's records reordered after it", edit_case(doc, "tent64_records_and_claim",
lambda c: c["records"].insert(0, c["records"].pop())))
frame = next(k for k in files if k.startswith("frames/"))
bad = dict(files)
bad[frame] = bytes([files[frame][0] ^ 1]) + files[frame][1:]
m("a frame file's first byte changed", (doc, "conformance_reproduced"), bad)
return out
CHECKS = {
"signature": "§2 the signature",
"exact-rates": "§7 rates as exact fractions",
"transform-ranges": "§4 the parameters' ranges",
"media": "§4 the transforms' media",
"counts": "§5 check 3 the counts",
"rates": "§5 check 4 the rates",
"values": "§5 check 5 the values",
"corpus-digest": "§5 check 6 the corpus digest",
"sizes": "§5 check 7 the samples' sizes",
"rerun": "§5 check 8 the rerun",
"survival": "§8 step 3 survival",
}
def main(corpus_dir):
fails = []
st = ED._self_test()
print(("PASS" if not st else "FAIL") + " Ed25519 strict rule self-test " + ",".join(st))
fails += ["ed25519 self-test"] if st else []
print(("PASS" if TENT64_DIGEST else "FAIL") + " wai-mark:tent64's digest, as synthesis 7.4 states it, is scheme.json's")
fails += [] if TENT64_DIGEST else ["the tent64 digest"]
reasons = reasons_of_extension()
print(("PASS" if len(reasons) == 21 else "FAIL") + " §12 read from the extension: %d reasons" % len(reasons))
fails += [] if len(reasons) == 21 else ["§12 does not read"]
listed = transforms_of_extension()
ok = listed == list(TRANSFORMS)
print(("PASS" if ok else "FAIL") + " §4 registers exactly the transforms this verifier implements")
fails += [] if ok else ["§4's transforms"]
files = load(corpus_dir)
doc = json.loads(files["vectors.json"])
fails += check(doc, files)
f = check_files(doc, files)
print(("PASS" if not f else "FAIL") + " the corpus documents, frames and records are what the cases verify, and nothing else is there")
fails += f
f = check_tent64(files)
print(("PASS" if not f else "FAIL") + " the tent64 records are synthesis 7.5.7's battery over battery.json's tallies, and the claim is synthesis 7.5.8's list")
fails += f
given = {c["expected"]["reason"] for c in doc["cases"] if c["expected"]["outcome"] == "refuse"}
missing = [x for x in reasons if x not in given]
unknown = sorted(given - set(reasons))
print(("PASS" if not missing and not unknown else "FAIL") + " every reason of §12 refuses a case, and no other reason does")
fails += ["no case gives %s" % x for x in missing] + ["a reason §12 does not list: %s" % x for x in unknown]
for label_, d, fs, case in mutations(doc, files):
caught = check(d, fs, quiet=True, only={case})
print(("PASS" if caught else "FAIL") + " mutated copy fails: %s%s" % (label_, " (%s)" % caught[0][:90] if caught else ""))
if not caught:
fails.append("a mutated copy verifies: %s" % label_)
for name, what in CHECKS.items():
SKIP.clear()
SKIP.add(name)
caught = check(doc, files, quiet=True)
SKIP.clear()
print(("PASS" if caught else "FAIL") + " a verifier without %s fails the corpus%s" % (what, " (%s)" % caught[0][:70] if caught else ""))
if not caught:
fails.append("the corpus does not catch a verifier without %s" % what)
for x in fails:
print("FAIL " + x)
print(("PASS" if not fails else "FAIL") + " robustness corpus: %d cases" % len(doc["cases"]))
return 1 if fails else 0
if __name__ == "__main__":
if len(sys.argv) != 2:
print("usage: robustness_verify.py <live-conformance/robustness>", file=sys.stderr)
sys.exit(2)
sys.exit(main(sys.argv[1]))

View file

@ -0,0 +1,55 @@
# live-conformance/splat — exact splats
The corpus of [`extensions/splat-exact.md`](../../extensions/splat-exact.md) §11: glTF 2.0 assets
that carry a `wai.splat.int_codec` object through `EXT_gaussian_splatting_compression_wai` (a
compression extension of `KHR_gaussian_splatting`), the origin's commitments to frames of
`wai-splat-render:i1` at canonical poses, origin claims, and sinks' view statements.
- `assets/<asset>.gltf` — an asset's JSON. Its buffer 0 is `assets/<scene>.bin`: the object's
`WAI1` envelope, then (where the asset carries it) the parameter set's one file. Its buffer 1,
where it has a commitment, is `assets/<asset>.commitment.json`, the commitment's JCS text. An
asset's buffers are named by `uri` beside it.
- `vectors.json` — the index. `held` maps a parameter set's SHA-256 to the committed file that
holds it (paths relative to `wai/`). Each case names its `asset`, the sets it holds (`held`),
the splat set's origin claim (`origin`, a text or `null`), its view statements (`statements`,
texts), and what a verifier gives it (`expect`): `refused` with its `reason` and its place
(`at`: `asset`, `commitment`, `view n`, `origin` or `statement n`), or `accepted` with the
statements of §9.3: the `object`'s content hash, the `attributes` digest, `n_gaussians`, each
canonical `frames` digest, and each statement's `canonical` and `class`.
**Exact-splat equivalence.** For each case, a conforming verifier reaches the outcome, place and
statements it states. Every code of §10 refuses a case. Among the refused cases are the negative
controls §11 names: `cluster_reordered` (frames committed with a tie of distance broken by the
greater index), `statement_frame` (a frame rendered without the low pass, which does not
recompute), `cluster_wrong_splats` (a commitment over another scene's attributes) and
`statement_pose` (a pose outside the pinned set claimed canonical).
**Provenance.** Generated here: `wai_splat_exact_vectors gen` writes every file. Its scenes:
- `shell` — the learned cloud of [`../../wai-rs/tests/vectors/int_splat/`](../../wai-rs/tests/vectors/int_splat/):
its payload `splat.wis1` and its synthesis `splat_gs.bin`, which `tools/wai_int_splat_export.py`
trained on a seeded procedural cloud (that directory's README states it). The set is held by
digest, not carried in the asset.
- `cluster` and `tiny` — authored here as integer attribute bytes: Gaussians placed by hand (a
pair at exactly equal distance from the first pose's eye, elongated and rotated ones, a zero
quaternion, one partly off the frame, one inside the near plane and one too wide on screen at
the fourth pose), and the rest drawn from a fixed SHA-256 stream. They are carried through the
identity set (§11): a one-layer `WHM1` network that decodes each latent value to one byte, so
the planes are coded as they are. `tiny13` and `tiny_negscale` are `tiny` with thirteen planes
and with a scale range below zero.
Every key is SHA-256 of the corpus's label and an index, every time is a constant, and Ed25519
signing is deterministic, so every file is the same bytes on every machine. No image, model or
text here comes from outside the repository.
```
cd ../../wai-rs
cargo run --no-default-features --features splat_exact --bin wai_splat_exact_vectors -- gen ../live-conformance/splat
cargo run --no-default-features --features splat_exact --bin wai_splat_exact_vectors -- verify ../live-conformance/splat
python3 -I ../live-conformance/splat_exact_verify.py ../live-conformance/splat
```
The second implementation decodes each payload with the repository's other second
implementations (`int-payload-conformance/int_payload_verify.py`'s parser and rANS decoder, and
`tools/wai_ops_check.py`'s `whm1/1` lowering and interpreter) and renders each view with its own
integer renderer. `--png DIR` writes each committed frame as a PNG.

Binary file not shown.

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"a1802d7eefbe02c6312fbeeaf79b1a0c9262ecc56538f3ff4ca32e3eac7a55bb4ece22da2aa6bee6cb0917cc7feda3152871bfd796feda32ffe57e08d11fa809","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster.commitment.json",
"byteLength": 1379
}
]
}

View file

@ -0,0 +1,116 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
}
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"a1802d7eefbe02c6312fbeeaf79b1a0c9262ecc56538f3ff4ca32e3eac7a55bb4ece22da2aa6bee6cb0917cc7feda3152871bfd796feda32ffe57e08d11fa809","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.3437652587890625,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_bounds.commitment.json",
"byteLength": 1379
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"a1802d7eefbe02c6312fbeeaf79b1a0c9262ecc56538f3ff4ca32e3eac7a55bb4ece22da2aa6bee6cb0917cc7feda3152871bfd796feda32ffe57e08d11fa809","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.spz",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_capability.commitment.json",
"byteLength": 1379
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"c659acd26a8418f36506fc51f61d893861f2380312b7bf13f18ec2f9ffcb0c93","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"2bd0b31cc1518d5acddbf8374ec41a836e1f5c69e30c9abdc316d6651eeba09ad0bceebe932ac5d065324f9d7924cb06880944e86230e84e649867157f98d00e","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_commitment_object.commitment.json",
"byteLength": 1379
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"033a37c9d29d7ea9675a0b4a3e269d74f2ab874b5a3b1425eec69bf3bad8b26f","sig":"8787a9f73dd13303662ed206f8ada1debe79f842a8acc0d154e43c9ed290fc850a7dd42e84c975db725d5598e9adbde6eca192fa13645e3735100eb11c46a905","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_commitment_set.commitment.json",
"byteLength": 1379
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"3cbe44f5201e61e4b929eb8bfd4c8d8dc857c301cbd06eaa88382f34dd5f5e29fa221c0e86f92a0d9bfc506cc737961c15efae153e286be766bdf474579f3d07","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"0000000000000000000000000000000000000000000000000000000000000000","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["196608","98304","131072"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 996
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_degenerate.commitment.json",
"byteLength": 996
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"a1802d7eefbe02c6312fbeeaf79b1a0c9262ecc56538f3ff4ca32e3eac7a55bb4ece22da2aa6bee6cb0917cc7feda3152871bfd796feda32ffe57e08d11fa809","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 4,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_mode.commitment.json",
"byteLength": 1379
}
]
}

View file

@ -0,0 +1,116 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "9912a9e7d88d3bb99abab32f1d865c0823e70ad127c517ede2946e1ec50e8953",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
}
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13752
},
{
"buffer": 0,
"byteOffset": 13752,
"byteLength": 657
}
],
"buffers": [
{
"uri": "cluster_noncanonical.bin",
"byteLength": 14412
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"a1802d7eefbe02c6312fbeeaf79b1a0c9262ecc56538f3ff4ca32e3eac7a55bb4ece22da2aa6bee6cb0917cc7feda3152871bfd796feda32ffe57e08d11fa809","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8b1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_object.commitment.json",
"byteLength": 1379
}
]
}

Binary file not shown.

View file

@ -0,0 +1,116 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "f2a1d6b2c416750e1221b814040929bc5b4f0e58e7ed80f3c8f0a6730697b638",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
}
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13739
},
{
"buffer": 0,
"byteOffset": 13740,
"byteLength": 657
}
],
"buffers": [
{
"uri": "cluster_pin.bin",
"byteLength": 14400
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:f1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"3bd5459ba25dd6584d9d956f97806604afe3c97b4301843ff3714ed4ffe9a21885b245fb408305f0fc56f08b66e95af859ea1eb5ce84cefcbb36eaa54961090b","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_renderer.commitment.json",
"byteLength": 1379
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"d662beb2b72c6900a6daf7eb17007d65d2fc063897307f955afb4494c811e5c2c2d8be1002da6508fae7b78321b1a0689f438997e82748738bc2e67417f9a509","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"b02f682d7167dae3f51de9ad8c5d4f07af5d3c8a335dd273e041f1f719868469","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"4b28def9f8b35fe3541bd9b232b4bf9c4280d10d57b6a6fe39e01e53a121e3c2","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_reordered.commitment.json",
"byteLength": 1379
}
]
}

View file

@ -0,0 +1 @@
{"attributes":"c643006a7cfa10e4559a262af2d349f3dfce01c10d07d66b349f33dedc7f802c","class":"captured","issued_at":"2026-10-22T09:00:00Z","kind":"wai-splat-commitment","object":"8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb","origin":null,"renderer":"wai-splat-render:i1","set":"252038ab37f69757d986653251b2caf6e67db31d8c98de6256244fc325a0addf","sig":"a1802d7eefbe02c6312fbeeaf79b1a0c9262ecc56538f3ff4ca32e3eac7a55bb4ece22da2aa6bee6cb0917cc7feda3152871bfd796feda32ffe57e08d11fa809","signer_pubkey":"85a065deefeee36c7b298d905f53c403249ce794c84151db860a5c3b668f01ae","views":[{"frame":"431c242d316c80ebbd14946124dba443722eea35c34751259315408f95a650b1","pose":{"eye":["0","0","262144"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"95a55286e44bf84976823e570e59873998ccbdf4cc0871ab82eb2eb7aae9684f","pose":{"eye":["196608","98304","131072"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"b77d2a535e23fd712921762ab6f7d0bd5da69c29de6fe5fd2e547d486d2ad570","pose":{"eye":["-196608","-65536","163840"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}},{"frame":"ca88c37d50f4076bc0a89c1b0cd36d01fe09282347e9d016d311460327507e96","pose":{"eye":["0","32768","124928"],"focal":80,"height":60,"target":["0","0","0"],"up":["0","65536","0"],"width":80}}]}

View file

@ -0,0 +1,126 @@
{
"asset": {
"version": "2.0"
},
"extensionsUsed": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"extensionsRequired": [
"KHR_gaussian_splatting",
"EXT_gaussian_splatting_compression_wai"
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"mode": 0,
"attributes": {
"POSITION": 0,
"KHR_gaussian_splatting:ROTATION": 1,
"KHR_gaussian_splatting:SCALE": 2,
"KHR_gaussian_splatting:OPACITY": 3,
"KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 4
},
"extensions": {
"KHR_gaussian_splatting": {
"kernel": "ellipse",
"colorSpace": "srgb_rec709_display",
"projection": "perspective",
"sortingMethod": "cameraDistance",
"extensions": {
"EXT_gaussian_splatting_compression_wai": {
"bufferView": 0,
"capability": "wai.splat.int_codec",
"object": "8a1b8c51ed6c09c8a3aed05c5e1eb6de00d8972038cf96eb079c3d1bdf4b4fbb",
"set": {
"sha256": "033a37c9d29d7ea9675a0b4a3e269d74f2ab874b5a3b1425eec69bf3bad8b26f",
"bufferView": 1
},
"commitment": 2
}
}
}
}
}
]
}
],
"accessors": [
{
"componentType": 5126,
"count": 40,
"type": "VEC3",
"min": [
-1.515625,
-1.359375,
-1.15625
],
"max": [
1.875,
1.34375,
1.8125
]
},
{
"componentType": 5126,
"count": 40,
"type": "VEC4"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
},
{
"componentType": 5126,
"count": 40,
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 40,
"type": "VEC3"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 13735
},
{
"buffer": 0,
"byteOffset": 13736,
"byteLength": 657
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 1379
}
],
"buffers": [
{
"uri": "cluster.bin",
"byteLength": 14396
},
{
"uri": "cluster_set.commitment.json",
"byteLength": 1379
}
]
}

Some files were not shown because too many files have changed in this diff Show more