diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 245c2fa..0e06a44 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -2,13 +2,14 @@ === [Unreleased] -==== Changed — evidence hash is platform-independent - -* The attestation evidence hash now feeds `+files_read+` to SHA-256 as an 8-byte -little-endian `+u64+`, like the other counts, instead of a platform-sized -`+usize+`. Hashes are unchanged on 64-bit platforms; 32-bit builds now agree -with them. The computation lives in `+attestation::evidence::evidence_hash+`, -with a known-answer test whose value comes from coreutils `+sha256sum+`. +==== Fixed — JCS numbers on decimal ties + +* `+ijson-jcs+` is bumped from 3a9a4ee to 03df9ed, which formats numbers with +`+ryu-js+` (ECMAScript `+Number::toString+`). The old pin printed RFC 8785 +Appendix B vector 0x43143ff3c1cb0959 as `+1424953923781206.3+`; JCS requires +`+1424953923781206.2+` (ties to even). Any report or attestation holding such a +float now hashes to the value other JCS implementations compute. A test in +`+crate::json+` pins the vector. ==== Fixed — KYAML keys holding a line separator diff --git a/Cargo.lock b/Cargo.lock index 4ba54d4..ac2c94d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2212,8 +2212,9 @@ dependencies = [ [[package]] name = "ijson-jcs" version = "0.1.0" -source = "git+https://github.com/hyperpolymath/ijson-jcs?rev=3a9a4ee326a968a32b2f152b4faec243a2d00765#3a9a4ee326a968a32b2f152b4faec243a2d00765" +source = "git+https://github.com/hyperpolymath/ijson-jcs?rev=03df9ed20c1a2e1d6d913b8b20cf0874651bb61a#03df9ed20c1a2e1d6d913b8b20cf0874651bb61a" dependencies = [ + "ryu-js", "serde", "serde_json", "thiserror 2.0.18", @@ -3710,6 +3711,12 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "ryu-js" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04d056b875a9d2e6cb9a61d127afee9ac5999b9f87bcb32079d1318e505be714" + [[package]] name = "same-file" version = "1.0.6" diff --git a/Cargo.toml b/Cargo.toml index 447a091..4f896d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # JCS (RFC 8785) for JSON artefacts: the estate tool behind JSON-POLICY rule # J-1. Not on crates.io, so pinned to a full commit SHA. -ijson-jcs = { git = "https://github.com/hyperpolymath/ijson-jcs", rev = "3a9a4ee326a968a32b2f152b4faec243a2d00765" } +ijson-jcs = { git = "https://github.com/hyperpolymath/ijson-jcs", rev = "03df9ed20c1a2e1d6d913b8b20cf0874651bb61a" } # Pure safe-Rust YAML (replaces serde_yaml + unsafe-libyaml, RUSTSEC-2024-0449). serde-saphyr = "2.0" regex = "1.10" diff --git a/src/json.rs b/src/json.rs index b6a7c2d..65eb5a4 100644 --- a/src/json.rs +++ b/src/json.rs @@ -61,6 +61,14 @@ mod tests { ); } + #[test] + fn numbers_follow_rfc_8785_on_decimal_ties() { + // RFC 8785 Appendix B: binary64 0x43143ff3c1cb0959 must print as + // ECMAScript does, choosing the even digit on a decimal tie. + let tie = f64::from_bits(0x4314_3ff3_c1cb_0959); + assert_eq!(to_canonical_string(&tie).unwrap(), "1424953923781206.2\n"); + } + #[test] fn rejects_integers_outside_i_json_range() { // I-JSON safe integers: [-(2^53 - 1), 2^53 - 1].