Theory Cyclic_Group_Ext
theory Cyclic_Group_Ext imports
CryptHOL.CryptHOL
"HOL-Number_Theory.Cong"
begin
context cyclic_group begin
lemma generator_pow_order: "❙g [^] order G = 𝟭"
proof(cases "order G > 0")
case True
hence fin: "finite (carrier G)" by(simp add: order_gt_0_iff_finite)
then have [symmetric]: "(λx. x ⊗ ❙g) ` carrier G = carrier G"
by(rule endo_inj_surj)(auto simp add: inj_on_multc)
then have "carrier G = (λ n. ❙g [^] Suc n) ` {..<order G}" using fin
by(simp add: carrier_conv_generator image_image)
then obtain n where n: "𝟭 = ❙g [^] Suc n" "n < order G" by auto
have "n = order G - 1" using n inj_onD[OF inj_on_generator, of 0 "Suc n"] by fastforce
with True n show ?thesis by auto
qed simp
lemma generator_pow_mult_order: "❙g [^] (order G * order G) = 𝟭"
using generator_pow_order
by (metis generator_closed nat_pow_one nat_pow_pow)
lemma pow_generator_mod: "❙g [^] (k mod order G) = ❙g [^] k"
proof(cases "order G > 0")
case True
obtain n where n: "k = n * order G + k mod order G" by (metis div_mult_mod_eq)
have "❙g [^] k = (❙g [^] order G) [^] n ⊗ ❙g [^] (k mod order G)"
by(subst n)(simp add: nat_pow_mult nat_pow_pow mult_ac)
then show ?thesis by(simp add: generator_pow_order)
qed simp
lemma pow_carrier_mod:
assumes "g ∈ carrier G"
shows "g [^] (k mod order G) = g [^] k"
using assms pow_generator_mod
by (metis generatorE generator_closed mod_mult_right_eq nat_pow_pow)
lemma pow_generator_mod_int: "❙g [^] ((k::int) mod order G) = ❙g [^] k"
proof(cases "order G > 0")
case True
obtain n :: int where n: "k = n * order G + k mod order G"
by (metis div_mult_mod_eq)
have "❙g [^] k = (❙g [^] order G) [^] n ⊗ ❙g [^] (k mod order G)"
apply(subst n)apply(simp add: int_pow_mult int_pow_pow mult_ac)
by (metis generator_closed int_pow_int int_pow_pow mult.commute)
then show ?thesis by(simp add: generator_pow_order)
qed simp
lemma pow_generator_eq_iff_cong:
"finite (carrier G) ⟹ ❙g [^] x = ❙g [^] y ⟷ [x = y] (mod order G)"
apply(subst (1 2) pow_generator_mod[symmetric])
by(auto simp add: cong_def order_gt_0_iff_finite intro: inj_onD[OF inj_on_generator])
lemma power_distrib:
assumes "h ∈ carrier G"
shows "❙g [^] (e :: nat) ⊗ h [^] e = (❙g ⊗ h ) [^] e"
(is "?lhs = ?rhs")
proof-
obtain x :: nat where x: "h = ❙g [^] x"
using assms generatorE by blast
hence "?lhs = ❙g [^] (e * (1 + x))"
by (simp add: nat_pow_mult mult.commute nat_pow_pow)
also have "... = (❙g [^] (1 + x)) [^] e"
by (metis generator_closed mult.commute nat_pow_pow)
ultimately show ?thesis
by (metis x One_nat_def generator_closed l_one monoid.nat_pow_Suc monoid_axioms nat_pow_0 nat_pow_mult)
qed
lemma neg_power_inverse:
assumes "g ∈ carrier G"
and "x < order G"
shows "g [^] (order G - (x :: nat)) = inv (g [^] x)"
proof-
have "inv (g [^] x) = g [^] (- int x)"
by (simp add: int_pow_int int_pow_neg assms)
moreover have "g [^] (order G - (x :: nat)) = g [^] (- int x)"
proof-
have "g [^] ((order G - (x :: nat)) mod (order G)) = g [^] ((- int x) mod (order G))"
proof-
have "(order G - (x :: nat)) mod (order G) = (- int x) mod (order G)"
using assms(2) zmod_zminus1_eq_if by auto
thus ?thesis
by (metis int_pow_int)
qed
thus ?thesis
proof -
have f1: "∀a. a [^] int 0 = 𝟭"
by simp
have f2: "∀n na. ((na::nat) + n) mod na = n mod na"
by simp
have f3: "∀a aa. aa ⊗ a [^] int 0 = aa ∨ aa ∉ carrier G"
by force
have f4: "∀i a aa. a [^] int 0 ⊗ aa [^] i = aa [^] (int 0 + i) ∨ aa ∉ carrier G"
by force
have "∀n a. a [^] int (n * 0) = a [^] (int 0 + int 0) ∨ a ∉ carrier G"
by simp
then have f5: "∀a aa. aa [^] int (order G) = a [^] int 0 ∨ aa ∉ carrier G"
using f4 f3 f2 f1 by (metis int_pow_closed int_pow_int mod_mult_self2 pow_carrier_mod)
have "∀n na. int (n - na) = - int na + int n ∨ ¬ na ≤ n"
by auto
then show ?thesis
using f5 f3 by (metis assms(1) assms(2) int_pow_closed int_pow_int int_pow_mult less_imp_le_nat)
qed
qed
ultimately show ?thesis by simp
qed
lemma int_nat_pow: assumes "a ≥ 0" shows "(❙g [^] (int (a ::nat))) [^] (b::int) = ❙g [^] (a*b)"
using assms
proof(cases "a >0")
case True
show ?thesis
using int_pow_pow by blast
next case False
have "(❙g [^] (int (a ::nat))) [^] (b::int) = 𝟭" using False by simp
also have "❙g [^] (a*b) = 𝟭" using False by simp
ultimately show ?thesis by simp
qed
lemma pow_gen_mod_mult:
shows"(❙g [^] (a::nat) ⊗ ❙g [^] (b::nat)) [^] ((c::int)*int (d::nat)) = (❙g [^] a ⊗ ❙g [^] b) [^] ((c*int d) mod (order G))"
proof-
have "(❙g [^] (a::nat) ⊗ ❙g [^] (b::nat)) ∈ carrier G" by simp
then obtain n :: nat where n: "❙g [^] n = (❙g [^] (a::nat) ⊗ ❙g [^] (b::nat))"
by (simp add: monoid.nat_pow_mult)
also obtain r where r: "r = c*int d" by simp
have 1: "(❙g [^] (a::nat) ⊗ ❙g [^] (b::nat)) [^] ((c::int)*int (d::nat)) = (❙g [^] n) [^] r" using n r by simp
also have 2:"... = (❙g [^] n) [^] (r mod (order G))" using pow_generator_mod_int pow_generator_mod
by (metis int_nat_pow int_pow_int mod_mult_right_eq zero_le)
also have 3:"... = (❙g [^] a ⊗ ❙g [^] b) [^] ((c*int d) mod (order G))" using r n by simp
ultimately show ?thesis using 1 2 3 by simp
qed
lemma cyclic_group_commute: assumes "a ∈ carrier G" "b ∈ carrier G" shows "a ⊗ b = b ⊗ a"
(is "?lhs = ?rhs")
proof-
obtain n :: nat where n: "a = ❙g [^] n" using generatorE assms by auto
also obtain k :: nat where k: "b = ❙g [^] k" using generatorE assms by auto
ultimately have "?lhs = ❙g [^] n ⊗ ❙g [^] k" by simp
then have "... = ❙g [^] (n + k)" by(simp add: nat_pow_mult)
then have "... = ❙g [^] (k + n)" by(simp add: add.commute)
then show ?thesis by(simp add: nat_pow_mult n k)
qed
lemma cyclic_group_assoc:
assumes "a ∈ carrier G" "b ∈ carrier G" "c ∈ carrier G"
shows "(a ⊗ b) ⊗ c = a ⊗ (b ⊗ c)"
(is "?lhs = ?rhs")
proof-
obtain n :: nat where n: "a = ❙g [^] n" using generatorE assms by auto
obtain k :: nat where k: "b = ❙g [^] k" using generatorE assms by auto
obtain j :: nat where j: "c = ❙g [^] j" using generatorE assms by auto
have "?lhs = (❙g [^] n ⊗ ❙g [^] k) ⊗ ❙g [^] j" using n k j by simp
then have "... = ❙g [^] (n + (k + j))" by(simp add: nat_pow_mult add.assoc)
then show ?thesis by(simp add: nat_pow_mult n k j)
qed
lemma l_cancel_inv:
assumes "h ∈ carrier G"
shows "(❙g [^] (a :: nat) ⊗ inv (❙g [^] a)) ⊗ h = h"
(is "?lhs = ?rhs")
proof-
have "?lhs = (❙g [^] int a ⊗ inv (❙g [^] int a)) ⊗ h" by simp
then have "... = (❙g [^] int a ⊗ (❙g [^] (- a))) ⊗ h" using int_pow_neg[symmetric] by simp
then have "... = ❙g [^] (int a - a) ⊗ h" by(simp add: int_pow_mult)
then have "... = ❙g [^] ((0:: int)) ⊗ h" by simp
then show ?thesis by (simp add: assms)
qed
lemma inverse_split:
assumes "a ∈ carrier G" and "b ∈ carrier G"
shows "inv (a ⊗ b) = inv a ⊗ inv b"
by (simp add: assms comm_group.inv_mult cyclic_group_commute group_comm_groupI)
lemma inverse_pow_pow:
assumes "a ∈ carrier G"
shows "inv (a [^] (r::nat)) = (inv a) [^] r"
proof -
have "a [^] r ∈ carrier G"
using assms by blast
then show ?thesis
by (simp add: assms nat_pow_inv)
qed
lemma l_neq_1_exp_neq_0:
assumes "l ∈ carrier G"
and "l ≠ 𝟭"
and "l = ❙g [^] (t::nat)"
shows "t ≠ 0"
proof(rule ccontr)
assume "¬ (t ≠ 0)"
hence "t = 0" by simp
hence "❙g [^] t = 𝟭" by simp
then show "False" using assms by simp
qed
lemma order_gt_1_gen_not_1:
assumes "order G > 1"
shows "❙g ≠ 𝟭"
proof(rule ccontr)
assume "¬ ❙g ≠ 𝟭"
hence "❙g = 𝟭" by simp
hence g_pow_eq_1: "❙g [^] n = 𝟭" for n :: nat by simp
hence "range (λn :: nat. ❙g [^] n) = {𝟭}" by auto
hence "carrier G ⊆ {𝟭}" using generator by auto
hence "order G < 1"
by (metis inj_onD inj_on_generator lessThan_iff g_pow_eq_1 assms less_one neq0_conv)
with assms show "False" by simp
qed
lemma power_swap: "((❙g [^] (α0::nat)) [^] (r::nat)) = ((❙g [^] r) [^] α0)"
(is "?lhs = ?rhs")
proof-
have "?lhs = ❙g [^] (α0 * r)" using nat_pow_pow mult.commute by auto
hence "... = ❙g [^] (r * α0)" by(metis mult.commute)
thus ?thesis using nat_pow_pow by auto
qed
lemma gen_power_0:
fixes r :: nat
assumes "❙g [^] r = 𝟭"
and "r < order G"
shows "r = 0"
using assms inj_onD inj_on_generator by fastforce
lemma group_eq_pow_eq_mod:
fixes a b :: nat
assumes "❙g [^] a = ❙g [^] b"
and "order G > 0"
shows "[a = b] (mod order G)"
proof(cases "a > b")
case True
have "❙g [^] a ⊗ inv (❙g [^] b) = 𝟭"
using assms by simp
hence "❙g [^] (a - b) = 𝟭"
by (smt True add_Suc_right assms diff_add_inverse generator_closed group.l_cancel_one' group_l_invI l_inv_ex less_imp_Suc_add nat_pow_closed nat_pow_mult)
hence "❙g [^] ((a - b) mod (order G)) = 𝟭" using pow_generator_mod by auto
thus ?thesis using gen_power_0
using assms(1) assms(2) order_gt_0_iff_finite pow_generator_eq_iff_cong by blast
next
case False
have "❙g [^] a ⊗ inv (❙g [^] b) = 𝟭"
using assms by simp
hence "❙g [^] (b - a) = 𝟭"
by (metis (no_types, lifting) False Group.group.axioms(1) Units_eq add_diff_inverse_nat assms(1) generator_closed group_l_invI l_inv_ex l_neq_1_exp_neq_0 monoid.Units_l_cancel nat_pow_closed nat_pow_mult r_one)
hence "❙g [^] ((b - a) mod (order G)) = 𝟭" using pow_generator_mod by simp
thus ?thesis using gen_power_0
using assms(1) assms(2) order_gt_0_iff_finite pow_generator_eq_iff_cong by blast
qed
end
end