274 changed files with 63921 additions and 410 deletions
214
.github/workflows/wai-conformance.yml
vendored
214
.github/workflows/wai-conformance.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
54
.github/workflows/wai-ops-gpu.yml
vendored
54
.github/workflows/wai-ops-gpu.yml
vendored
|
|
@ -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: |
|
||||
|
|
|
|||
|
|
@ -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=$?
|
||||
|
|
|
|||
|
|
@ -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
3
wai/.gitattributes
vendored
|
|
@ -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
|
||||
|
|
|
|||
273
wai/CHANGELOG.md
273
wai/CHANGELOG.md
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
182
wai/SPEC.md
182
wai/SPEC.md
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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` |
|
||||
|
|
|
|||
656
wai/extensions/exact-tonemap.md
Normal file
656
wai/extensions/exact-tonemap.md
Normal 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.
|
||||
|
|
@ -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" ]
|
||||
}
|
||||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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
589
wai/extensions/opus-dred.md
Normal 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.
|
||||
492
wai/extensions/pq-signatures.md
Normal file
492
wai/extensions/pq-signatures.md
Normal 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*.
|
||||
525
wai/extensions/robustness-evidence.md
Normal file
525
wai/extensions/robustness-evidence.md
Normal 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.
|
||||
614
wai/extensions/splat-exact.md
Normal file
614
wai/extensions/splat-exact.md
Normal 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.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
454
wai/extensions/telemetry-aggregation.md
Normal file
454
wai/extensions/telemetry-aggregation.md
Normal 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.
|
||||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
```
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
61
wai/live-conformance/aggregate/README.md
Normal file
61
wai/live-conformance/aggregate/README.md
Normal 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
|
||||
```
|
||||
89
wai/live-conformance/aggregate/vdaf-22/Prio3Count_0.json
Normal file
89
wai/live-conformance/aggregate/vdaf-22/Prio3Count_0.json
Normal 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"
|
||||
}
|
||||
111
wai/live-conformance/aggregate/vdaf-22/Prio3Count_1.json
Normal file
111
wai/live-conformance/aggregate/vdaf-22/Prio3Count_1.json
Normal 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"
|
||||
}
|
||||
329
wai/live-conformance/aggregate/vdaf-22/Prio3Count_2.json
Normal file
329
wai/live-conformance/aggregate/vdaf-22/Prio3Count_2.json
Normal 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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
96
wai/live-conformance/aggregate/vdaf-22/Prio3Histogram_0.json
Normal file
96
wai/live-conformance/aggregate/vdaf-22/Prio3Histogram_0.json
Normal 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"
|
||||
}
|
||||
125
wai/live-conformance/aggregate/vdaf-22/Prio3Histogram_1.json
Normal file
125
wai/live-conformance/aggregate/vdaf-22/Prio3Histogram_1.json
Normal 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"
|
||||
}
|
||||
732
wai/live-conformance/aggregate/vdaf-22/Prio3Histogram_2.json
Normal file
732
wai/live-conformance/aggregate/vdaf-22/Prio3Histogram_2.json
Normal 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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
256
wai/live-conformance/aggregate/vdaf-22/Prio3SumVec_0.json
Normal file
256
wai/live-conformance/aggregate/vdaf-22/Prio3SumVec_0.json
Normal 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"
|
||||
}
|
||||
282
wai/live-conformance/aggregate/vdaf-22/Prio3SumVec_1.json
Normal file
282
wai/live-conformance/aggregate/vdaf-22/Prio3SumVec_1.json
Normal 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"
|
||||
}
|
||||
90
wai/live-conformance/aggregate/vdaf-22/Prio3Sum_0.json
Normal file
90
wai/live-conformance/aggregate/vdaf-22/Prio3Sum_0.json
Normal 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"
|
||||
}
|
||||
112
wai/live-conformance/aggregate/vdaf-22/Prio3Sum_1.json
Normal file
112
wai/live-conformance/aggregate/vdaf-22/Prio3Sum_1.json
Normal 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"
|
||||
}
|
||||
510
wai/live-conformance/aggregate/vdaf-22/Prio3Sum_2.json
Normal file
510
wai/live-conformance/aggregate/vdaf-22/Prio3Sum_2.json
Normal 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"
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"binder": "62696e64657220737472696e67",
|
||||
"derived_seed": "b62ef0a2778190792d4d42d8c167ba20e0c37a3f319ba79645829c427d70eea5",
|
||||
"dst": "646f6d61696e2073657061726174696f6e20746167",
|
||||
"expanded_vec_field128": "b62ef0a2778190792d4d42d8c167ba20e0c37a3f319ba79645829c427d70eea56d92fef65a07b17a0438e25452cdc7f15f63caf0e8a2a3c72ac69524729e64e03c7ec3a3afa7eb21cb6da6abf0a3b73630a91a5fa05dcbd33da3476f1c8bf4fd66fe5a80dd04bc95f0f02cb8fc9035b9e16e3a5c373bf81c820af513e0c832ca672c66dcc3b302fb8b27a48f09e0a843f5caf87b3c6c1c4b6765b5923e1d152c2e695601abbc69dbe810860fb30e871a2549861110672335ce50ee632264cbb21f62595298d1d1ad9303b84664801e52112989dfce93f0f9dc833ee0f4a0672ffe47cb0a13f80f9e9b7a2e267db7f7890ccd064bf2458cd4e27162d13e60dbc1b6cae71635a3e603f2c15d1c64a12d4e8235f7bf0a8efe6bb15f3e2adae06f7dd1c4d63ac6cecae731250f73c063c6e59aef630a7b6f4bc64bddadc8b8a479bfdb64ea31e6ab44540a52a8d3399d64a060d50190d66cac1335d739e5f8d508201058a2e0cc1ed90e23cfdc7a253f24710ef3b1604688606386dcc4c90e8476be9daac3271ac51301868df71a719a5f32184145d70fec31b4693d527f53875a2ea013523d3daa33bc49c22f66c9ae70dd7f06f227f50515ea9ab1fbe0162cf761e596d8999809cf672cd2d82b22231f841c36e494d7e44f7c6f07e29758b1b73ce95b202325116f04067a54aa767eab2e00ce55b3abcd5c3d5b05040a6bf5d4ba8a61267004bb82b12d43b08fed8f9aced3e833a58fc01004526631b0f4192d8754a397e1096511ee23761a29fcd6511ad2e5020683ca877e4075fe6bc5907f7df1ed4b6c97e0f897d781e850da0cf584842c124cdb6011fe8660e3b8c354cd659985332ea158ffcba83253d39803fa7efb9fcd02cea38089f239f68404814973",
|
||||
"length": 40,
|
||||
"seed": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
|
||||
}
|
||||
6426
wai/live-conformance/aggregate/vectors.json
Normal file
6426
wai/live-conformance/aggregate/vectors.json
Normal file
File diff suppressed because one or more lines are too long
54
wai/live-conformance/dred/README.md
Normal file
54
wai/live-conformance/dred/README.md
Normal 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>
|
||||
40
wai/live-conformance/dred/fetch.sh
Executable file
40
wai/live-conformance/dred/fetch.sh
Executable 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"
|
||||
1531
wai/live-conformance/dred/vectors.json
Normal file
1531
wai/live-conformance/dred/vectors.json
Normal file
File diff suppressed because it is too large
Load diff
1014
wai/live-conformance/dred_verify.py
Normal file
1014
wai/live-conformance/dred_verify.py
Normal file
File diff suppressed because it is too large
Load diff
50
wai/live-conformance/robustness/README.md
Normal file
50
wai/live-conformance/robustness/README.md
Normal 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
|
||||
```
|
||||
1
wai/live-conformance/robustness/corpus/conformance.json
Normal file
1
wai/live-conformance/robustness/corpus/conformance.json
Normal 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}]}
|
||||
1
wai/live-conformance/robustness/corpus/tent64-clips.json
Normal file
1
wai/live-conformance/robustness/corpus/tent64-clips.json
Normal 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}]}
|
||||
|
|
@ -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}]}
|
||||
|
|
@ -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
Binary file not shown.
Binary file not shown.
|
|
@ -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"}]}
|
||||
1
wai/live-conformance/robustness/records/conformance.json
Normal file
1
wai/live-conformance/robustness/records/conformance.json
Normal 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"]}
|
||||
|
|
@ -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"}]}
|
||||
|
|
@ -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
1352
wai/live-conformance/robustness/vectors.json
Normal file
1352
wai/live-conformance/robustness/vectors.json
Normal file
File diff suppressed because one or more lines are too long
948
wai/live-conformance/robustness_verify.py
Normal file
948
wai/live-conformance/robustness_verify.py
Normal 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]))
|
||||
55
wai/live-conformance/splat/README.md
Normal file
55
wai/live-conformance/splat/README.md
Normal 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.
|
||||
BIN
wai/live-conformance/splat/assets/cluster.bin
Normal file
BIN
wai/live-conformance/splat/assets/cluster.bin
Normal file
Binary file not shown.
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
116
wai/live-conformance/splat/assets/cluster_bare.gltf
Normal file
116
wai/live-conformance/splat/assets/cluster_bare.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_bounds.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_bounds.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_capability.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_capability.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_commitment_object.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_commitment_object.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_commitment_set.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_commitment_set.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_degenerate.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_degenerate.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_mode.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_mode.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
wai/live-conformance/splat/assets/cluster_noncanonical.bin
Normal file
BIN
wai/live-conformance/splat/assets/cluster_noncanonical.bin
Normal file
Binary file not shown.
116
wai/live-conformance/splat/assets/cluster_noncanonical.gltf
Normal file
116
wai/live-conformance/splat/assets/cluster_noncanonical.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_object.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_object.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
wai/live-conformance/splat/assets/cluster_pin.bin
Normal file
BIN
wai/live-conformance/splat/assets/cluster_pin.bin
Normal file
Binary file not shown.
116
wai/live-conformance/splat/assets/cluster_pin.gltf
Normal file
116
wai/live-conformance/splat/assets/cluster_pin.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_renderer.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_renderer.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_reordered.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_reordered.gltf
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}}]}
|
||||
126
wai/live-conformance/splat/assets/cluster_set.gltf
Normal file
126
wai/live-conformance/splat/assets/cluster_set.gltf
Normal 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
Loading…
Reference in a new issue