/-- The (additive) monoid equivalence between `ZMod k`
and the powers of a primitive root of unity `ζ`. -/
def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) :=
  AddEquiv.ofBijective
    (AddMonoidHom.liftOfRightInverse (Int.castAddHom <| ZMod k) _ ZMod.int_cast_rightInverse
      ⟨{  toFun := fun i => Additive.ofMul (⟨_, i, rfl⟩ : Subgroup.zpowers ζ)
          map_zero' := by simp only [zpow_zero]; rfl
          map_add' := by intro i j; simp only [zpow_add]; rfl }, fun i hi => by
        simp only [AddMonoidHom.mem_ker, CharP.int_cast_eq_zero_iff (ZMod k) k, AddMonoidHom.coe_mk,
          Int.coe_castAddHom] at hi ⊢
        obtain ⟨i, rfl⟩ := hi
        simp [zpow_mul, h.pow_eq_one, one_zpow, zpow_ofNat]⟩)
    (by
      constructor
      · rw [injective_iff_map_eq_zero]
        

Proof state:
case left
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
inst✝¹ : DivisionCommMonoid G
k l : ℕ
inst✝ : CommRing R
ζ : Rˣ
h✝ h : IsPrimitiveRoot ζ k
⊢ ∀ (a : ZMod k),
    ((AddMonoidHom.liftOfRightInverse (Int.castAddHom (ZMod k)) ZMod.cast
              (_ : Function.RightInverse ZMod.cast Int.cast))
            {
              val :=
                {
                  toZeroHom :=
                    {
                      toFun := fun i =>
                        Additive.ofMul
                          { val := (fun x => ζ ^ x) i, property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) },
                      map_zero' :=
                        (_ :
                          (fun i =>
                                Additive.ofMul
                                  { val := (fun x => ζ ^ x) i,
                                    property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) })
                              0 =
                            0) },
                  map_add' :=
                    (_ :
                      ∀ (i j : ℤ),
                        ZeroHom.toFun
                            {
                              toFun := fun i =>
                                Additive.ofMul
                                  { val := (fun x => ζ ^ x) i,
                                    property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) },
                              map_zero' :=
                                (_ :
                                  (fun i =>
                                        Additive.ofMul
                                          { val := (fun x => ζ ^ x) i,
                                            property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) })
                                      0 =
                                    0) }
                            (i + j) =
                          ZeroHom.toFun
                              {
                                toFun := fun i =>
                                  Additive.ofMul
                                    { val := (fun x => ζ ^ x) i,
                                      property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) },
                                map_zero' :=
                                  (_ :
                                    (fun i =>
                                          Additive.ofMul
                                            { val := (fun x => ζ ^ x) i,
                                              property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) })
                                        0 =
                                      0) }
                              i +
                            ZeroHom.toFun
                              {
                                toFun := fun i =>
                                  Additive.ofMul
                                    { val := (fun x => ζ ^ x) i,
                                      property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) },
                                map_zero' :=
                                  (_ :
                                    (fun i =>
                                          Additive.ofMul
                                            { val := (fun x => ζ ^ x) i,
                                              property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) })
                                        0 =
                                      0) }
                              j) },
              property :=
                (_ :
                  ∀ i ∈ AddMonoidHom.ker (Int.castAddHom (ZMod k)),
                    i ∈
                      AddMonoidHom.ker
                        {
                          toZeroHom :=
                            {
                              toFun := fun i =>
                                Additive.ofMul
                                  { val := (fun x => ζ ^ x) i,
                                    property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) },
                              map_zero' :=
                                (_ :
                                  (fun i =>
                                        Additive.ofMul
                                          { val := (fun x => ζ ^ x) i,
                                            property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) })
                                      0 =
                                    0) },
                          map_add' :=
                            (_ :
                              ∀ (i j : ℤ),
                                ZeroHom.toFun
                                    {
                                      toFun := fun i =>
                                        Additive.ofMul
                                          { val := (fun x => ζ ^ x) i,
                                            property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) },
                                      map_zero' :=
                                        (_ :
                                          (fun i =>
                                                Additive.ofMul
                                                  { val := (fun x => ζ ^ x) i,
                                                    property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) })
                                              0 =
                                            0) }
                                    (i + j) =
                                  ZeroHom.toFun
                                      {
                                        toFun := fun i =>
                                          Additive.ofMul
                                            { val := (fun x => ζ ^ x) i,
                                              property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) },
                                        map_zero' :=
                                          (_ :
                                            (fun i =>
                                                  Additive.ofMul
                                                    { val := (fun x => ζ ^ x) i,
                                                      property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) })
                                                0 =
                                              0) }
                                      i +
                                    ZeroHom.toFun
                                      {
                                        toFun := fun i =>
                                          Additive.ofMul
                                            { val := (fun x => ζ ^ x) i,
                                              property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) },
                                        map_zero' :=
                                          (_ :
                                            (fun i =>
                                                  Additive.ofMul
                                                    { val := (fun x => ζ ^ x) i,
                                                      property := (_ : ∃ y, (fun x => ζ ^ x) y = (fun x => ζ ^ x) i) })
                                                0 =
                                              0) }
                                      j) }) })
          a =
        0 →
      a = 0

Next tactic:
intro i hi