anchor.diff:  encrypt_and_send_chunk(
     #params{
        socket = Socket, rekey_interval = Seq,
  -     key = Key, iv = {IVSalt, _}, hash_algorithm = HashAlgorithm} = Params,
  +     key = Key, iv = {IVSalt, _}, hmac_algorithm = HmacAlgo} = Params,
     Seq, Cleartext) ->
       %%
       KeyLen = byte_size(Key),
       IVSaltLen = byte_size(IVSalt),
  -    Chunk = <<KeySalt:KeyLen/binary, IVSalt_1:IVSaltLen/binary, IVNo_1:48>> =
  -        crypto:strong_rand_bytes(KeyLen + IVSaltLen + 6),
  +    R = crypto:strong_rand_bytes(KeyLen + IVSaltLen + 6),
       case
           gen_tcp:send(
  -          Socket, encrypt_chunk(Params, Seq, [?REKEY_CHUNK, Chunk]))
  +          Socket, encrypt_chunk(Params, Seq, [?REKEY_CHUNK, R]))
       of
           ok ->
  -            Key_1 = hash_key(HashAlgorithm, Key, KeySalt),
  +            {Key_1, <<IVSalt_1:IVSaltLen/binary, IVNo_1:48>>} =
  +                hmac_key_iv(HmacAlgo, Key, R, KeyLen, IVSaltLen + 6),
               Params_1 = Params#params{key = Key_1, iv = {IVSalt_1, IVNo_1}},
               Result =
                   gen_tcp:send(Socket, encrypt_chunk(Params_1, 0, Cleartext)),
  
positive.code: 
  encrypt_chunk(
    #params{
       block_crypto = BlockCrypto,
       iv = {IVSalt, IVNo}, key = Key, tag_len = TagLen}, Seq, Cleartext) ->
      %%
      ChunkLen = iolist_size(Cleartext) + TagLen,
      AAD = <<Seq:32, ChunkLen:32>>,
      IVBin = <<IVSalt/binary, (IVNo + Seq):48>>,
      {Ciphertext, CipherTag} =
          crypto:block_encrypt(BlockCrypto, Key, IVBin, {AAD, Cleartext, TagLen}),
      Chunk = [Ciphertext,CipherTag],
      Chunk.
  
  decrypt_chunk(
    #params{
       block_crypto = BlockCrypto,
       iv = {IVSalt, IVNo}, key = Key, tag_len = TagLen} = Params, Seq, Chunk) ->
      %%
      ChunkLen = byte_size(Chunk),
  
negative.code: %% -------------------------------------------------------------------------
  
  init(Socket, Secret) ->
      Params = current_params(Socket),
      {PrivKey, R2, R3, Msg} = init_msg(Params, Secret),
      ok = gen_tcp:send(Socket, Msg),
      init(Params, Secret, PrivKey, R2, R3).
  
  init(
    #params{socket = Socket, iv = IVLen} = Params, Secret, PrivKey, R2, R3) ->
      %%
      {ok, InitMsg} = gen_tcp:recv(Socket, 0),
      IVSaltLen = IVLen - 6,
      try
          case init_msg(Params, Secret, PrivKey, R2, R3, InitMsg) of
              {#params{iv = <<IV2ASalt:IVSaltLen/binary, IV2ANo:48>>} =
                   SendParams,
               RecvParams, SendStartMsg} ->
                  ok = gen_tcp:send(Socket, SendStartMsg),
                  {ok, RecvStartMsg} = gen_tcp:recv(Socket, 0),
                  #params{
                     iv = <<IV2BSalt:IVSaltLen/binary, IV2BNo:48>>} =
                      RecvParams_1 =
                      start_msg(RecvParams, R2, R3, RecvStartMsg),
                  {SendParams#params{iv = {IV2ASalt, IV2ANo}},
                   RecvParams_1#params{iv = {IV2BSalt, IV2BNo}}}
          end
      catch
          error : Reason : Stacktrace->
              _ = trace({Reason, Stacktrace}),
              exit(connection_closed)
      end.
  
  
  
  init_msg(
    #params{
       public_key_type = PublicKeyType,
       public_key_params = PublicKeyParams,
       hmac_algorithm = HmacAlgo,
       aead_cipher = AeadCipher,
       key = KeyLen,
       iv = IVLen,
       tag_len = TagLen}, Secret) ->
      %%
      {PubKeyA, PrivKey} = crypto:generate_key(PublicKeyType, PublicKeyParams),
      RLen = KeyLen + IVLen,
      <<R1A:RLen/binary, R2A:RLen/binary, R3A:RLen/binary>> =
          crypto:strong_rand_bytes(3 * RLen),
      {Key1A, IV1A} = hmac_key_iv(HmacAlgo, R1A, Secret, KeyLen, IVLen),
      Plaintext = [R2A, R3A, PubKeyA],
      MsgLen = byte_size(R1A) + TagLen + iolist_size(Plaintext),
      AAD = [<<MsgLen:32>>, R1A],
      {Ciphertext, Tag} =
          crypto:block_encrypt(AeadCipher, Key1A, IV1A, {AAD, Plaintext, TagLen}),
      Msg = [R1A, Tag, Ciphertext],
      {PrivKey, R2A, R3A, Msg}.
  %%
  init_msg(
    #params{
       public_key_type = PublicKeyType,
       public_key_params = PublicKeyParams,
       hmac_algorithm = HmacAlgo,
       aead_cipher = AeadCipher,
       key = KeyLen,
       iv = IVLen,
       tag_len = TagLen,
       rekey_interval = RekeyInterval} = Params, Secret, PrivKey, R2A, R3A, Msg) ->
      %%
      RLen = KeyLen + IVLen,
      case Msg of
          <<R1B:RLen/binary, Tag:TagLen/binary, Ciphertext/binary>> ->
              {Key1B, IV1B} = hmac_key_iv(HmacAlgo, R1B, Secret, KeyLen, IVLen),
              MsgLen = byte_size(Msg),
              AAD = [<<MsgLen:32>>, R1B],
              case
                  crypto:block_decrypt(
                    AeadCipher, Key1B, IV1B, {AAD, Ciphertext, Tag})
              of
                  <<R2B:RLen/binary, R3B:RLen/binary, PubKeyB/binary>> ->
                      SharedSecret =
                          crypto:compute_key(
                            PublicKeyType, PubKeyB, PrivKey, PublicKeyParams),
                      %%
                      {Key2A, IV2A} =
                          hmac_key_iv(
                            HmacAlgo, SharedSecret, [R2A, R3B], KeyLen, IVLen),
                      SendParams = Params#params{key = Key2A, iv = IV2A},
                      %%
                      StartCleartext = [R2B, R3B, <<RekeyInterval:32>>],
                      StartMsgLen = TagLen + iolist_size(StartCleartext),
                      StartAAD = <<StartMsgLen:32>>,
                      {StartCiphertext, StartTag} =
                          crypto:block_encrypt(
                            AeadCipher, Key2A, IV2A,
                            {StartAAD, StartCleartext, TagLen}),
                      StartMsg = [StartTag, StartCiphertext],
                      %%
                      {Key2B, IV2B} =
                          hmac_key_iv(
                            HmacAlgo, SharedSecret, [R2B, R3A], KeyLen, IVLen),
                      RecvParams = Params#params{key = Key2B, iv = IV2B},
                      %%
                      {SendParams, RecvParams, StartMsg}
              end
      end.
  
  start_msg(
    #params{
       aead_cipher = AeadCipher,
       key = Key2B,
       iv = IV2B,
       tag_len = TagLen,
       rekey_interval = RekeyIntervalA} = RecvParams, R2A, R3A, Msg) ->
      %%
      case Msg of
          <<Tag:TagLen/binary, Ciphertext/binary>> ->
              KeyLen = byte_size(Key2B),
              IVLen = byte_size(IV2B),
              RLen = KeyLen + IVLen,
              MsgLen = byte_size(Msg),
              AAD = <<MsgLen:32>>,
              case
                  crypto:block_decrypt(
                    AeadCipher, Key2B, IV2B, {AAD, Ciphertext, Tag})
              of
                  <<R2A:RLen/binary, R3A:RLen/binary, RekeyIntervalB:32>>
                    when RekeyIntervalA =< (RekeyIntervalB bsl 2),
                         RekeyIntervalB =< (RekeyIntervalA bsl 2) ->
                      RecvParams#params{rekey_interval = RekeyIntervalB}
              end
      end.
  
  hmac_key_iv(HmacAlgo, MacKey, Data, KeyLen, IVLen) ->
      <<Key:KeyLen/binary, IV:IVLen/binary>> =
          crypto:hmac(HmacAlgo, MacKey, Data, KeyLen + IVLen),
      {Key, IV}.
  
  %% -------------------------------------------------------------------------
  %% net_kernel distribution handshake in progress
  