/-- The unique `RingHom` from `ℤ√d` to a ring `R`, constructed by replacing `√d` with the provided
root. Conversely, this associates to every mapping `ℤ√d →+* R` a value of `√d` in `R`. -/
@[simps]
def lift {d : ℤ} : { r : R // r * r = ↑d } ≃ (ℤ√d →+* R) where
  toFun r :=
    { toFun := fun a => a.1 + a.2 * (r : R)
      map_zero' := by simp
      map_add' := fun a b => by
        simp only [add_re, Int.cast_add, add_im]
        ring
      map_one' := by simp
      map_mul' := fun a b => by
        have :
          (a.re + a.im * r : R) * (b.re + b.im * r) =
            a.re * b.re + (a.re * b.im + a.im * b.re) * r + a.im * b.im * (r * r) := by
          ring
        simp only [mul_re, Int.cast_add, Int.cast_mul, mul_im, this, r.prop]
        ring }
  invFun f := ⟨f sqrtd, by rw [← f.map_mul, dmuld, map_intCast]⟩
  left_inv r := by
    ext
    simp
  right_inv f := by
    -- Porting note: was `ext`
    refine hom_ext _ _ ?_
    

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
f : ℤ√d →+* R
⊢ ((fun r =>
          {
            toMonoidHom :=
              { toOneHom := { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) },
                map_mul' :=
                  (_ :
                    ∀ (a b : ℤ√d),
                      OneHom.toFun { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                          (a * b) =
                        OneHom.toFun { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } a *
                          OneHom.toFun { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                            b) },
            map_zero' := (_ : ↑0 + ↑0 * ↑r = 0),
            map_add' :=
              (_ :
                ∀ (a b : ℤ√d),
                  OneHom.toFun
                      (↑{ toOneHom := { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) },
                          map_mul' :=
                            (_ :
                              ∀ (a b : ℤ√d),
                                OneHom.toFun
                                    { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                                    (a * b) =
                                  OneHom.toFun
                                      { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } a *
                                    OneHom.toFun
                                      { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } b) })
                      (a + b) =
                    OneHom.toFun
                        (↑{ toOneHom := { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) },
                            map_mul' :=
                              (_ :
                                ∀ (a b : ℤ√d),
                                  OneHom.toFun
                                      { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                                      (a * b) =
                                    OneHom.toFun
                                        { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } a *
                                      OneHom.toFun
                                        { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                                        b) })
                        a +
                      OneHom.toFun
                        (↑{ toOneHom := { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) },
                            map_mul' :=
                              (_ :
                                ∀ (a b : ℤ√d),
                                  OneHom.toFun
                                      { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                                      (a * b) =
                                    OneHom.toFun
                                        { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } a *
                                      OneHom.toFun
                                        { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                                        b) })
                        b) })
        ((fun f => { val := f sqrtd, property := (_ : f sqrtd * f sqrtd = ↑d) }) f))
      sqrtd =
    f sqrtd

Next tactic:
simp