anchor.diff:  -record(params,
           {socket,
            dist_handle,
  -         public_key_type,
  -         public_key_params,
  -         hmac_algorithm,
  -         aead_cipher,
  -         iv,
  -         key,
  -         tag_len,
  -         rekey_interval
  +         hmac_algorithm = sha256,
  +         aead_cipher = aes_gcm,
  +         iv = 12,
  +         key = 16,
  +         tag_len = 16,
  +         rekey_interval = 32768
           }).
   
  -current_params(Socket) ->
  -    #params{
  -       socket = Socket,
  -       public_key_type = ecdh,
  -       public_key_params = brainpoolP384t1,
  -       hmac_algorithm = sha256,
  -       aead_cipher = aes_gcm,
  -       iv = 12,
  -       key = 16,
  -       tag_len = 16,
  -       rekey_interval = 32768}.
  +-record(public_key_pair,
  +        {type = ecdh,
  +         params = brainpoolP384t1,
  +         public,
  +         private}).
  +
  +params(Socket) ->
  +    #params{socket = Socket}.
  +
  +
  +%% -------------------------------------------------------------------------
  +%% Keep the same public/private key pair during the node's lifetime
  +%% in the process state of a process linked to the acceptor process.
  +%% Create it the first time it is needed.
  +%%
  +
  +start_public_key_pair() ->
  +    spawn_link(
  +      fun () ->
  +              register(?MODULE, self()),
  +              public_key_pair(#public_key_pair{})
  +      end).
  +
  +public_key_pair(PKP) ->
  +    receive
  +        {Pid, Tag, public_key_pair} ->
  +            case PKP of
  +                #public_key_pair{
  +                   type = Type,
  +                   params = Params,
  +                   public = undefined} ->
  +                    %%
  +                    {Public, Private} = crypto:generate_key(Type, Params),
  +                    PKP_1 =
  +                        PKP#public_key_pair{
  +                          public = Public, private = Private},
  +                    Pid ! {Tag, PKP_1},
  +                    public_key_pair(PKP_1);
  +                #public_key_pair{} ->
  +                    Pid ! {Tag, PKP},
  +                    public_key_pair(PKP)
  +            end
  +    end.
  +
  +public_key_pair() ->
  +    Pid = whereis(?MODULE),
  +    Ref = erlang:monitor(process, Pid),
  +    Pid ! {self(), Ref, public_key_pair},
  +    receive
  +        {Ref, PKP} ->
  +            erlang:demonitor(Ref, [flush]),
  +            PKP;
  +        {'DOWN', Ref, process, Pid, Reason} ->
  +            error(Reason)
  +    end.
   
   %% -------------------------------------------------------------------------
   %% Erlang distribution plugin structure explained to myself
  
positive.code: %% blocks we have a deadlock.
  %%
  %% The init + start sequence tries to implement Password Encrypted
  %% Key Exchange using an ephemeral public/private keypair and the
  %% shared secret (the Cookie) to create session encryption keys
  %% that can not be re-created if the shared secret is compromized,
  %% which should create forward secrecy.
  %%
  %% All exchanged messages uses {packet, 2} i.e 16 bit size header.
  %%
  %% The init message contains a random number and encrypted: a public key
  %% and two random numbers.  The encryption is done with Key and IV hashed
  %% from the unencrypted random number and the shared secret.
  %%
  %% The exchanged epemeral public/private keypairs are used
  %% to create a shared key that is hashed with one of the encrypted
  %% random numbers from each side to create Key and IV for the session.
  %%
  %% The start message contains the two encrypted random numbers
  
negative.code: 
  init_msg(
    #params{
       hmac_algorithm = HmacAlgo,
       aead_cipher = AeadCipher,
       key = KeyLen,
       iv = IVLen,
       tag_len = TagLen}, PubKeyA, Secret) ->
      %%
      RLen = KeyLen + IVLen,
      <<R1A:RLen/binary, R2A:RLen/binary, R3A:RLen/binary>> =
          crypto:strong_rand_bytes(3 * RLen),
  