Skip to content

Conversation

Rob-Hague
Copy link
Contributor

Follow-up to 76e2475 (#534), this time for the constant Sike data.

In the same test app on top of the same branch:

before #534 after #534 now
untrimmed 6989 KB 6975 KB 6892 KB
trimmed 3993 KB 2791 KB 564 KB

i.e. the assembly trims nicely there with no cost to the untrimmed size.

As before, the source code was generated by reflecting over instances of the existing classes:

using Org.BouncyCastle.Pqc.Crypto.Sike;
using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;

P434 lc = new(isCompressed: true);

string[] bz2FieldNames =
[
    "ph2_path",
    "ph3_path",
    "A_gen",
    "B_gen",
    "XQB3",
    "A_basis_zero",
    "B_basis_zero",
    "B_gen_3_tors",
    "g_R_S_im",
    "g_phiR_phiS_re",
    "g_phiR_phiS_im",
    "Montgomery_RB1",
    "Montgomery_RB2",
    "threeinv",
    "u_entang",
    "u0_entang",
    "table_r_qr",
    "table_r_qnr",
    "table_v_qr",
    "table_v_qnr",
    "v_3_torsion",
    "T_tate3",
    "T_tate2_firststep_P",
    "T_tate2_P",
    "T_tate2_firststep_Q",
    "T_tate2_Q",
    "ph2_T",
    "ph3_T1",
    "ph3_T2",
];

FieldInfo[] fields = lc.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

using StreamWriter sw = new(@"C:\tmp\out.txt");
using IndentedTextWriter tw = new(sw);

tw.Indent++; //class
tw.WriteLine(); // to get tabs on next line

foreach (string fieldName in bz2FieldNames)
{
    FieldInfo field = fields.Single(f => f.Name == fieldName);

    if (field.FieldType == typeof(uint[]))
    {
        uint[] data = (uint[])field.GetValue(lc);

        int nonZeroDataLength = data.AsSpan().LastIndexOfAnyExcept(0u) + 1;

        tw.WriteLine($"private static readonly uint[] s_{field.Name} = new uint[{nonZeroDataLength}]");
        tw.WriteLine("{");
        tw.Indent++;

        foreach (uint[] chunk in data.Take(nonZeroDataLength).Chunk(8))
        {
            tw.Write("0x");
            tw.Write(string.Join(", 0x", chunk.Select(u => u.ToString("X8"))));
            tw.WriteLine(",");
        }

        tw.Indent--;
        tw.WriteLine("};");
        tw.WriteLine();
    }
    else if (field.FieldType == typeof(ulong[]))
    {
        ulong[] data = (ulong[])field.GetValue(lc);

        int nonZeroDataLength = data.AsSpan().LastIndexOfAnyExcept(0u) + 1;

        tw.WriteLine($"private static readonly ulong[] s_{field.Name} = new ulong[{nonZeroDataLength}]");
        tw.WriteLine("{");
        tw.Indent++;

        foreach (ulong[] chunk in data.Take(nonZeroDataLength).Chunk(4))
        {
            tw.Write("0x");
            tw.Write(string.Join(", 0x", chunk.Select(u => u.ToString("X16"))));
            tw.WriteLine(",");
        }

        tw.Indent--;
        tw.WriteLine("};");
        tw.WriteLine();
    }
    else if (field.FieldType == typeof(ulong[][]))
    {
        ulong[][] data = (ulong[][])field.GetValue(lc);

        tw.WriteLine($"private static readonly ulong[][] s_{field.Name} = new ulong[{data.Length}][]");
        tw.WriteLine("{");
        tw.Indent++;
        for (int i = 0; i < data.Length; i++)
        {
            int nonZeroDataLength = data[i].AsSpan().LastIndexOfAnyExcept(0u) + 1;

            tw.WriteLine($"new ulong[{nonZeroDataLength}]");
            tw.WriteLine("{");
            tw.Indent++;

            foreach (ulong[] chunk in data[i].Take(nonZeroDataLength).Chunk(4))
            {
                tw.Write("0x");
                tw.Write(string.Join(", 0x", chunk.Select(u => u.ToString("X16"))));
                tw.WriteLine(",");
            }

            tw.Indent--;
            tw.WriteLine("},");

        }
        tw.Indent--;
        tw.WriteLine("};");
        tw.WriteLine();
    }
    else if (field.FieldType == typeof(ulong[][][]))
    {
        ulong[][][] data = (ulong[][][])field.GetValue(lc);

        tw.WriteLine($"private static readonly ulong[][][] s_{field.Name} = new ulong[{data.Length}][][]");
        tw.WriteLine("{");
        tw.Indent++;
        for (int i = 0; i < data.Length; i++)
        {
            tw.WriteLine($"new ulong[{data[i].Length}][]");
            tw.WriteLine("{");
            tw.Indent++;

            for (int j = 0; j < data[i].Length; j++)
            {
                int nonZeroDataLength = data[i][j].AsSpan().LastIndexOfAnyExcept(0u) + 1;

                tw.WriteLine($"new ulong[{nonZeroDataLength}]");
                tw.WriteLine("{");
                tw.Indent++;

                foreach (ulong[] chunk in data[i][j].Take(nonZeroDataLength).Chunk(4))
                {
                    tw.Write("0x");
                    tw.Write(string.Join(", 0x", chunk.Select(u => u.ToString("X16"))));
                    tw.WriteLine(",");
                }

                tw.Indent--;
                tw.WriteLine("},");
            }

            tw.Indent--;
            tw.WriteLine("},");
        }
        tw.Indent--;
        tw.WriteLine("};");
        tw.WriteLine();
    }
    else
    {
        Debug.Fail(field.FieldType.ToString());
    }
}

This would complete #422

Follow-up to 76e247 (bcgit#534),
this time for the constant Sike data.

In the same test app on top of the same branch:

|           |  before bcgit#534 | after bcgit#534 |     now |
| --------- | ------------ | ---------- | ------- |
| untrimmed |      6989 KB |    6975 KB | 6892 KB |
|   trimmed |      3993 KB |    2791 KB |  564 KB |

i.e. the assembly now trims nicely with no cost to the untrimmed size.

As before, the source code was generated by reflecting over instances of the
existing classes:

  using Org.BouncyCastle.Pqc.Crypto.Sike;
  using System;
  using System.CodeDom.Compiler;
  using System.Diagnostics;
  using System.IO;
  using System.Linq;
  using System.Reflection;

  P434 lc = new(isCompressed: true);

  string[] bz2FieldNames =
  [
      "ph2_path",
      "ph3_path",
      "A_gen",
      "B_gen",
      "XQB3",
      "A_basis_zero",
      "B_basis_zero",
      "B_gen_3_tors",
      "g_R_S_im",
      "g_phiR_phiS_re",
      "g_phiR_phiS_im",
      "Montgomery_RB1",
      "Montgomery_RB2",
      "threeinv",
      "u_entang",
      "u0_entang",
      "table_r_qr",
      "table_r_qnr",
      "table_v_qr",
      "table_v_qnr",
      "v_3_torsion",
      "T_tate3",
      "T_tate2_firststep_P",
      "T_tate2_P",
      "T_tate2_firststep_Q",
      "T_tate2_Q",
      "ph2_T",
      "ph3_T1",
      "ph3_T2",
  ];

  FieldInfo[] fields = lc.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

  using StreamWriter sw = new(@"C:\tmp\out.txt");
  using IndentedTextWriter tw = new(sw);

  tw.Indent++; //class
  tw.WriteLine(); // to get tabs on next line

  foreach (string fieldName in bz2FieldNames)
  {
      FieldInfo field = fields.Single(f => f.Name == fieldName);

      if (field.FieldType == typeof(uint[]))
      {
          uint[] data = (uint[])field.GetValue(lc);

          int nonZeroDataLength = data.AsSpan().LastIndexOfAnyExcept(0u) + 1;

          tw.WriteLine($"private static readonly uint[] s_{field.Name} = new uint[{nonZeroDataLength}]");
          tw.WriteLine("{");
          tw.Indent++;

          foreach (uint[] chunk in data.Take(nonZeroDataLength).Chunk(8))
          {
              tw.Write("0x");
              tw.Write(string.Join(", 0x", chunk.Select(u => u.ToString("X8"))));
              tw.WriteLine(",");
          }

          tw.Indent--;
          tw.WriteLine("};");
          tw.WriteLine();
      }
      else if (field.FieldType == typeof(ulong[]))
      {
          ulong[] data = (ulong[])field.GetValue(lc);

          int nonZeroDataLength = data.AsSpan().LastIndexOfAnyExcept(0u) + 1;

          tw.WriteLine($"private static readonly ulong[] s_{field.Name} = new ulong[{nonZeroDataLength}]");
          tw.WriteLine("{");
          tw.Indent++;

          foreach (ulong[] chunk in data.Take(nonZeroDataLength).Chunk(4))
          {
              tw.Write("0x");
              tw.Write(string.Join(", 0x", chunk.Select(u => u.ToString("X16"))));
              tw.WriteLine(",");
          }

          tw.Indent--;
          tw.WriteLine("};");
          tw.WriteLine();
      }
      else if (field.FieldType == typeof(ulong[][]))
      {
          ulong[][] data = (ulong[][])field.GetValue(lc);

          tw.WriteLine($"private static readonly ulong[][] s_{field.Name} = new ulong[{data.Length}][]");
          tw.WriteLine("{");
          tw.Indent++;
          for (int i = 0; i < data.Length; i++)
          {
              int nonZeroDataLength = data[i].AsSpan().LastIndexOfAnyExcept(0u) + 1;

              tw.WriteLine($"new ulong[{nonZeroDataLength}]");
              tw.WriteLine("{");
              tw.Indent++;

              foreach (ulong[] chunk in data[i].Take(nonZeroDataLength).Chunk(4))
              {
                  tw.Write("0x");
                  tw.Write(string.Join(", 0x", chunk.Select(u => u.ToString("X16"))));
                  tw.WriteLine(",");
              }

              tw.Indent--;
              tw.WriteLine("},");

          }
          tw.Indent--;
          tw.WriteLine("};");
          tw.WriteLine();
      }
      else if (field.FieldType == typeof(ulong[][][]))
      {
          ulong[][][] data = (ulong[][][])field.GetValue(lc);

          tw.WriteLine($"private static readonly ulong[][][] s_{field.Name} = new ulong[{data.Length}][][]");
          tw.WriteLine("{");
          tw.Indent++;
          for (int i = 0; i < data.Length; i++)
          {
              tw.WriteLine($"new ulong[{data[i].Length}][]");
              tw.WriteLine("{");
              tw.Indent++;

              for (int j = 0; j < data[i].Length; j++)
              {
                  int nonZeroDataLength = data[i][j].AsSpan().LastIndexOfAnyExcept(0u) + 1;

                  tw.WriteLine($"new ulong[{nonZeroDataLength}]");
                  tw.WriteLine("{");
                  tw.Indent++;

                  foreach (ulong[] chunk in data[i][j].Take(nonZeroDataLength).Chunk(4))
                  {
                      tw.Write("0x");
                      tw.Write(string.Join(", 0x", chunk.Select(u => u.ToString("X16"))));
                      tw.WriteLine(",");
                  }

                  tw.Indent--;
                  tw.WriteLine("},");
              }

              tw.Indent--;
              tw.WriteLine("},");
          }
          tw.Indent--;
          tw.WriteLine("};");
          tw.WriteLine();
      }
      else
      {
          Debug.Fail(field.FieldType.ToString());
      }
  }
@peterdettman
Copy link
Collaborator

Merged, thanks again.

@Rob-Hague
Copy link
Contributor Author

Great, thanks

@Rob-Hague Rob-Hague deleted the sike branch May 24, 2024 07:01
hubot pushed a commit that referenced this pull request May 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants