code: def dh_exchange(self, ctx: Context, ranks: typing.List[int]):
      if self._is_mock:
          return
      local_rank = ctx.local.rank
      dh = {}
      seeds = {}
      for rank in ranks:
          if rank == local_rank:
              continue
          dh[rank] = DiffieHellman()
          ctx.parties[rank].put(
              self._get_name(f"dh_pubkey"), dh[rank].get_public_key()
          )
      for rank in ranks:
          if rank == local_rank:
              continue
          public_key = ctx.parties[rank].get(
              self._get_name(f"dh_pubkey")
          )
          seeds[rank] = dh[rank].diffie_hellman(public_key)
      self._mixer = RandomMix(seeds, local_rank)
  
file_path: FATE/python/fate/arch/protocol/secure_aggregation/_secure_aggregation.py
imports: import typing
  import numpy
  from fate.arch import Context
  from fate.arch.protocol.diffie_hellman import DiffieHellman
  from fate_utils.secure_aggregation_helper import MixAggregate, RandomMix
label_desc: Use image node_id 3 for calling the SecureAggregatorClient obj's underlying member method code with example usage: obj.dh_exchange(ctx, ranks) without return types