コンテンツにスキップ

case04(再構築デモ): 攻撃の仕様 — 5/7

攻撃の設計 の手順を、具体的な制約に落とし込みます。実際のコードと実行は ② Colab で(制約ソルバ CP-SAT / OR-Tools を使います)。

前提(攻撃者が持っているもの)

  • 公表統計表(人数・中央値・平均、14行・うち7行は秘匿)。
  • 表ラベルの意味(「女性」「黒人女性」「既婚の成人」などのグループ定義)。これは公表表を読めば分かる一般知識。
  • 元の個票は持っていない

変数の置き方

  • 人を1人ずつ未知数にする。総人口の公表値から7人と分かる。
  • 各人 i に: 年齢(0〜115の整数)、女性黒人既婚(各 0/1)。
  • 対称性の除去: 年齢の昇順に並べる(age[0] ≤ age[1] ≤ …)。人の集合が同じなら並べ替えても同じデータなので、7! 通りの重複解を防ぐだけで、答えには影響しない。
  • 常識の制約: 未成年(18歳未満)は独身として記録される。

主なルール(公表行 → 制約)

  • 人数: 「そのグループに属する人数 = 公表値」。例: 女性は4人。
  • 平均 → 合計の区間: 公表値は小数第1位に丸め。ceil((mean−0.05)×count) ≤ 合計 ≤ floor((mean+0.05)×count)。例: 黒人女性 平均36.7×3人 → 合計は 110 の一択
  • 中央値 → 順序統計量: 年齢の昇順に並んでいるので、「グループの k 番目の人」の年齢を指せる。奇数人なら中央の人、偶数人なら中央2人の平均(2倍して整数で書く)。
  • 秘匿された行: 制約を1本も与えない(情報が無いだけ)。それでも解は一意に決まる。
CP-SAT で書くときの工夫
  • 変数どうしの掛け算は書けないので、「グループに属せば年齢、属さねば0」という補助変数を条件付きで定義して合計を作る。
  • 中央値は「i がグループの k 番目 = i はグループ員 かつ 先行するグループ員が k−1 人」という条件で表す。
  • 全解列挙enumerate_all_solutions)で解を数え尽くし、1通りかどうかを判定する。
攻撃仕様一覧(公表行ごと)
表番号 グループ 与える制約
1A 総人口 人数7/合計区間(平均38)/中央値30
2A 女性 人数4/合計区間(平均33.5)/中央値30
2B 男性 人数3/合計区間(平均44)/中央値30
2C 黒人 人数4/合計区間(平均48.5)/中央値51
2D 白人 人数3/合計区間(平均24)/中央値24
3B 既婚の成人 人数4/合計区間(平均54)/中央値51
4A 黒人女性 人数3/合計区間(平均36.7)/中央値36
3A,4B–4D,5A–5C 独身の成人・黒人男性 ほか 秘匿 → 制約なし

小さな問題だが本質は同じ

7人・7行の小さな問題なので、CP-SAT は一瞬で全解を数え尽くします。実際の国勢調査はブロック数・属性数が桁違いに大きくなりますが、「多数の正確な統計 → 個票が定まる」という構造は同じです。

→ 実行は ② 実装(Colab)、復元後の個票は 復元後テーブル、結果と対策は ③ 結果