defmodule Grizzly.ZWave.CommandClasses.Security2Test do
  use ExUnit.Case, async: true

  alias Grizzly.ZWave.CommandClasses.Security2

  describe "key derivation" do
    test "network_key_expand/1" do
      network_key =
        <<0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
          0x4E, 0x4F>>

      expected_ccm_key =
        <<0xAF, 0x7F, 0x0A, 0x1E, 0xFC, 0xFE, 0x8F, 0x4B, 0x1F, 0xD2, 0x84, 0x5D, 0xD2, 0x85,
          0x6F, 0x7D>>

      expected_pstring =
        <<0xCC, 0xF8, 0xB4, 0x2A, 0x4F, 0x70, 0x21, 0x76, 0xAC, 0x2B, 0x91, 0x94, 0xDB, 0xBD,
          0xB8, 0x2C, 0x47, 0x43, 0x02, 0xFF, 0x12, 0xE1, 0xE8, 0x26, 0x64, 0x22, 0xF3, 0xAC,
          0x44, 0x89, 0x4B, 0x87>>

      expected_mpan_key =
        <<0xB8, 0x9D, 0xB1, 0x54, 0x3F, 0xD2, 0x82, 0x0E, 0xA9, 0x79, 0xC9, 0x6A, 0x30, 0x5A,
          0x23, 0x0B>>

      {ccm_key, pstring, mpan_key} = Security2.network_key_expand(network_key)

      assert expected_ccm_key == ccm_key
      assert expected_pstring == pstring
      assert expected_mpan_key == mpan_key
    end

    test "temp_key_extract/2" do
      ecdh_shared_secret =
        <<0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
          0x46, 0x47, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x40, 0x41, 0x42, 0x43,
          0x44, 0x45, 0x46, 0x47>>

      sender_pubkey =
        <<0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
          0x4E, 0x4F, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x48, 0x49, 0x4A, 0x4B,
          0x4C, 0x4D, 0x4E, 0x4F>>

      receiver_pubkey =
        <<0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
          0x4E, 0x4F, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x48, 0x49, 0x4A, 0x4B,
          0x4C, 0x4D, 0x4E, 0x4F>>

      expected_prk =
        <<0x74, 0x77, 0x8F, 0x89, 0xD4, 0xD8, 0x8C, 0x6E, 0x46, 0x59, 0x63, 0x4A, 0x88, 0xEA,
          0x98, 0x7A>>

      assert expected_prk ==
               Security2.temp_key_extract(ecdh_shared_secret, sender_pubkey, receiver_pubkey)
    end

    test "temp_key_expand/1" do
      prk =
        <<0x74, 0x77, 0x8F, 0x89, 0xD4, 0xD8, 0x8C, 0x6E, 0x46, 0x59, 0x63, 0x4A, 0x88, 0xEA,
          0x98, 0x7A>>

      expected_ccm_key =
        <<0x47, 0xDA, 0x9D, 0x15, 0x39, 0xEC, 0x73, 0xE5, 0xD2, 0xA0, 0xF7, 0x37, 0xDB, 0xF2,
          0x9B, 0x33>>

      expected_pstring =
        <<0x94, 0xA5, 0x3E, 0xB9, 0xA1, 0x2D, 0x7C, 0xD9, 0x49, 0xEA, 0x70, 0xFF, 0xB8, 0xA6,
          0xE7, 0x1E, 0xA6, 0xF7, 0x9C, 0xA7, 0xA0, 0x14, 0x5A, 0x08, 0xBA, 0xD5, 0x82, 0xAE,
          0xB0, 0x9B, 0xD2, 0x8B>>

      expected_mpan_key =
        <<0xC2, 0x8E, 0x57, 0x5F, 0x24, 0x6F, 0x59, 0xA4, 0xA5, 0x85, 0x0F, 0x20, 0x66, 0xF1,
          0x06, 0x2B>>

      assert {^expected_ccm_key, ^expected_pstring, ^expected_mpan_key} =
               Security2.temp_key_expand(prk)
    end
  end
end
