Theory Multiplication_Synthesization
theory Multiplication_Synthesization
imports
Multiplication
begin
text ‹
This is an experimental re-formalization of the multiplication protocol,
which differs from the original one in three aspects:
1) We use the writer transformer for automatic bookkeeping of simulation obligations in the privacy proof.
Since monad transformers are hard to deal with in HOL,
we combine (writer transformer + spmf monad) into writer\_spmf.
To ease the modelling, we allow heterogeneous message types in the binding operation,
a technicality that might disqualify it as a monad but, luckily, does not stop us from
using the built-in do-notation.
2) We wraps the adding of zero-sharing into a new operation called ``sharing flattening''.
The proof for the sharing flattening is then ``composed'' into the larger proof for multiplication.
3) The simulator is not manually defined but synthesized through @{command schematic_goal}.
›
type_synonym ('val, 'msg) writer_spmf = "('val × 'msg) spmf"
definition bind_writer_spmf :: "('val1, 'msg1) writer_spmf ⇒ ('val1 ⇒ ('val2, 'msg2) writer_spmf) ⇒ ('val2, ('msg1 × 'msg2)) writer_spmf" where
"bind_writer_spmf x f = bind_spmf x (λ(val1, msg1). map_spmf (λ(val2, msg2). (val2, (msg1, msg2))) (f val1))"
adhoc_overloading Monad_Syntax.bind bind_writer_spmf
definition flatten_sharingF :: "natL sharing ⇒ natL sharing spmf" where
"flatten_sharingF s = share_nat (reconstruct s)"
definition flatten_sharingR :: "Role ⇒ natL sharing ⇒ (natL sharing, natL) writer_spmf" where
"flatten_sharingR p s = do {
ζ ← zero_sharing;
let r = map_sharing2 (+) s ζ;
return_spmf (r, (get_party p ζ))
}"
definition flatten_sharingS :: "natL ⇒ natL ⇒ natL spmf" where
"flatten_sharingS inp outp = return_spmf (outp - inp)"
lemma flatten_sharing_spec:
"flatten_sharingR p x = do {
y ← flatten_sharingF x;
msg ← flatten_sharingS (get_party p x) (get_party p y);
return_spmf (y, msg)
}"
unfolding flatten_sharingR_def
unfolding flatten_sharingF_def
unfolding flatten_sharingS_def
apply simp
apply (fold zero_masking_eq_share_nat)
unfolding map_spmf_conv_bind_spmf
apply simp
done
definition aby3_mulR' :: "Role ⇒ natL ⇒ natL ⇒ (natL sharing, ((natL × natL) × (natL × natL)) × natL) writer_spmf" where
"aby3_mulR' p x y = do {
xs ← share_nat x;
ys ← share_nat y;
let xy = prod_sharing xs ys;
let xy_shift = shift_sharing xy;
let z_raw = map_sharing2 do_mul xy xy_shift;
(z, ζ_msg) ← flatten_sharingR p z_raw;
return_spmf (z, (((get_party p xs, get_party p ys), get_party p xy_shift), ζ_msg))
}"
definition aby3_mulF' :: "natL ⇒ natL ⇒ natL sharing spmf" where
"aby3_mulF' x y = share_nat (x * y)"
definition aby3_mulS' :: "natL ⇒ (((natL × natL) × (natL × natL)) × natL) spmf" where
"aby3_mulS' z = do {
x1 ← spmf_of_set UNIV;
x2 ← spmf_of_set UNIV;
y1 ← spmf_of_set UNIV;
y2 ← spmf_of_set UNIV;
let ζ = z - (x1 * y1 + x1 * y2 + x2 * y1);
return_spmf (((x1, y1), (x2, y2)), ζ)
}"
lemma set_spmf_share_nat:
"set_spmf (share_nat x) = {s. reconstruct s = x}"
unfolding share_nat_def
apply simp
unfolding vimage_def
apply simp
done
lemma reconstruct_share_nat':
"pred_spmf (λs. reconstruct s = x) (share_nat x)"
unfolding pred_spmf_def
apply auto
unfolding set_spmf_share_nat
apply simp
done
lemma share_nat_cong:
"x = y ⟹ (⋀s. reconstruct s = x ⟹ f s = g s) ⟹ bind_spmf (share_nat x) f = bind_spmf (share_nat y) g"
apply (rule bind_spmf_cong)
subgoal by simp
subgoal unfolding set_spmf_share_nat by simp
done
lemma return_ResSim:
"return_spmf (r, s) = bind_spmf (return_spmf s) (λmsg. return_spmf (r, msg))"
by simp
schematic_goal aby3_mul_spec:
"aby3_mulR' p x y =
bind_spmf (aby3_mulF' x y) (λz.
bind_spmf (?aby3_mulS' (get_party p z)) (λmsg.
return_spmf (z, msg)))"
unfolding aby3_mulR'_def
unfolding flatten_sharing_spec
unfolding aby3_mulF'_def
unfolding flatten_sharingF_def
apply simp
unfolding reconstruct_do_mul
apply simp
unfolding do_mul_def
apply simp
apply (simp cong: share_nat_cong)
unfolding share_nat_def_calc'[of p "prev_role p" "next_role p" x, simplified]
unfolding share_nat_def_calc'[of p "prev_role p" "next_role p" y, simplified]
unfolding pair_spmf_alt_def
apply simp
unfolding make_sharing'_sel[of p "prev_role p" "next_role p", simplified]
unfolding bind_commute_spmf[where q="share_nat _"]
apply (rule share_nat_cong[OF refl])
apply (subst return_ResSim)
apply (fold bind_spmf_assoc)
apply (rule refl)
done
end