theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      simp only [mem_divisorsAntidiagonal, Nat.mul_eq_zero, Ne.def]
      constructor
      · ring
      rw [Nat.mul_eq_zero] at *
      apply not_or_of_not ha hb
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      dsimp only
      rw [hf.map_mul_of_coprime cop.coprime_mul_right.coprime_mul_right_right,
        hg.map_mul_of_coprime cop.coprime_mul_left.coprime_mul_left_right]
      ring
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ ⟨⟨c1, c2⟩, ⟨d1, d2⟩⟩ hab hcd h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at hab
      rcases hab with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at hcd
      simp only [Prod.mk.inj_iff] at h
      ext <;> dsimp only
      · trans Nat.gcd (a1 * a2) (a1 * b1)
        · rw [Nat.gcd_mul_left, cop.coprime_mul_left.coprime_mul_right_right.gcd_eq_one, mul_one]
        · rw [← hcd.1.1, ← hcd.2.1] at cop
          rw [← hcd.1.1, h.1, Nat.gcd_mul_left,
            cop.coprime_mul_left.coprime_mul_right_right.gcd_eq_one, mul_one]
      · trans Nat.gcd (a1 * a2) (a2 * b2)
        · rw [mul_comm, Nat.gcd_mul_left, cop.coprime_mul_right.coprime_mul_left_right.gcd_eq_one,
            mul_one]
        · rw [← hcd.1.1, ← hcd.2.1] at cop
          rw [← hcd.1.1, h.2, mul_comm, Nat.gcd_mul_left,
            cop.coprime_mul_right.coprime_mul_left_right.gcd_eq_one, mul_one]
      · trans Nat.gcd (b1 * b2) (a1 * b1)
        · rw [mul_comm, Nat.gcd_mul_right,
            cop.coprime_mul_right.coprime_mul_left_right.symm.gcd_eq_one, one_mul]
        · rw [← hcd.1.1, ← hcd.2.1] at cop
          rw [← hcd.2.1, h.1, mul_comm c1 d1, Nat.gcd_mul_left,
            cop.coprime_mul_right.coprime_mul_left_right.symm.gcd_eq_one, mul_one]
      · trans Nat.gcd (b1 * b2) (a2 * b2)
        · rw [Nat.gcd_mul_right, cop.coprime_mul_left.coprime_mul_right_right.symm.gcd_eq_one,
            one_mul]
        · rw [← hcd.1.1, ← hcd.2.1] at cop
          rw [← hcd.2.1, h.2, Nat.gcd_mul_right,
            cop.coprime_mul_left.coprime_mul_right_right.symm.gcd_eq_one, one_mul]
    · rintro ⟨b1, b2⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      use ((b1.gcd m, b2.gcd m), (b1.gcd n, b2.gcd n))
      simp only [exists_prop, Prod.mk.inj_iff, Ne.def, mem_product, mem_divisorsAntidiagonal]
      

Proof state:
case h
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
m n : ℕ
cop : Coprime m n
b1 b2 : ℕ
h : b1 * b2 = m * n ∧ ¬m * n = 0
⊢ ((gcd b1 m * gcd b2 m = m ∧ ¬m = 0) ∧ gcd b1 n * gcd b2 n = n ∧ ¬n = 0) ∧
    b1 = gcd b1 m * gcd b1 n ∧ b2 = gcd b2 m * gcd b2 n

Next tactic:
rw [← cop.gcd_mul _, ← cop.gcd_mul _, ← h.1, Nat.gcd_mul_gcd_of_coprime_of_mul_eq_mul cop h.1,
        Nat.gcd_mul_gcd_of_coprime_of_mul_eq_mul cop.symm _]