<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.0" />

Interleave

static class Interleave
using Org.BouncyCastle.Runtime.Intrinsics.X86; using System; using System.Runtime.Intrinsics.X86; namespace Org.BouncyCastle.Math.Raw { internal static class Interleave { private const ulong M32 = 1431655765; private const ulong M64 = 6148914691236517205; private const ulong M64R = 12297829382473034410; internal static uint Expand8to16(byte x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.IsEnabled) return System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x, 1431655765); uint num = (uint)((x | (x << 4)) & 3855); num = ((num | (num << 2)) & 13107); return (num | (num << 1)) & 21845; } internal static uint Expand16to32(ushort x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.IsEnabled) return System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x, 1431655765); uint num = (uint)((x | (x << 8)) & 16711935); num = ((num | (num << 4)) & 252645135); num = ((num | (num << 2)) & 858993459); return (num | (num << 1)) & 1431655765; } internal static ulong Expand32to64(uint x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.IsEnabled) return ((ulong)System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x >> 16, 1431655765) << 32) | System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x, 1431655765); x = Bits.BitPermuteStep(x, 65280, 8); x = Bits.BitPermuteStep(x, 15728880, 4); x = Bits.BitPermuteStep(x, 202116108, 2); x = Bits.BitPermuteStep(x, 572662306, 1); return (ulong)((((long)(x >> 1) & 1431655765) << 32) | ((long)x & 1431655765)); } internal static void Expand64To128(ulong x, ulong[] z, int zOff) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) { z[zOff] = System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x, 6148914691236517205); z[zOff + 1] = System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x >> 32, 6148914691236517205); } else { x = Bits.BitPermuteStep(x, 4294901760, 16); x = Bits.BitPermuteStep(x, 280375465148160, 8); x = Bits.BitPermuteStep(x, 67555025218437360, 4); x = Bits.BitPermuteStep(x, 868082074056920076, 2); x = Bits.BitPermuteStep(x, 2459565876494606882, 1); z[zOff] = (x & 6148914691236517205); z[zOff + 1] = ((x >> 1) & 6148914691236517205); } } internal static void Expand64To128(ulong x, Span<ulong> z) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) { z[0] = System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x, 6148914691236517205); z[1] = System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x >> 32, 6148914691236517205); } else { x = Bits.BitPermuteStep(x, 4294901760, 16); x = Bits.BitPermuteStep(x, 280375465148160, 8); x = Bits.BitPermuteStep(x, 67555025218437360, 4); x = Bits.BitPermuteStep(x, 868082074056920076, 2); x = Bits.BitPermuteStep(x, 2459565876494606882, 1); z[0] = (x & 6148914691236517205); z[1] = ((x >> 1) & 6148914691236517205); } } internal static void Expand64To128(ulong[] xs, int xsOff, int xsLen, ulong[] zs, int zsOff) { int num = xsLen; int num2 = zsOff + (xsLen << 1); while (--num >= 0) { num2 -= 2; Expand64To128(xs[xsOff + num], zs, num2); } } internal static void Expand64To128(ReadOnlySpan<ulong> xs, Span<ulong> zs) { int num = xs.Length; int num2 = xs.Length << 1; while (--num >= 0) { num2 -= 2; ulong x = xs[num]; int num3 = num2; Expand64To128(x, zs.Slice(num3, zs.Length - num3)); } } internal static ulong Expand64To128Rev(ulong x, out ulong low) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) { low = System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x >> 32, 12297829382473034410); return System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x, 12297829382473034410); } x = Bits.BitPermuteStep(x, 4294901760, 16); x = Bits.BitPermuteStep(x, 280375465148160, 8); x = Bits.BitPermuteStep(x, 67555025218437360, 4); x = Bits.BitPermuteStep(x, 868082074056920076, 2); x = Bits.BitPermuteStep(x, 2459565876494606882, 1); low = (ulong)((long)x & -6148914691236517206); return (ulong)((long)(x << 1) & -6148914691236517206); } internal static uint Shuffle(uint x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.IsEnabled) return System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x >> 16, 2863311530) | System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x, 1431655765); x = Bits.BitPermuteStep(x, 65280, 8); x = Bits.BitPermuteStep(x, 15728880, 4); x = Bits.BitPermuteStep(x, 202116108, 2); x = Bits.BitPermuteStep(x, 572662306, 1); return x; } internal static ulong Shuffle(ulong x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) return System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x >> 32, 12297829382473034410) | System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x, 6148914691236517205); x = Bits.BitPermuteStep(x, 4294901760, 16); x = Bits.BitPermuteStep(x, 280375465148160, 8); x = Bits.BitPermuteStep(x, 67555025218437360, 4); x = Bits.BitPermuteStep(x, 868082074056920076, 2); x = Bits.BitPermuteStep(x, 2459565876494606882, 1); return x; } internal static uint Shuffle2(uint x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.IsEnabled) return System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x >> 24, 2290649224) | System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x >> 16, 1145324612) | System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x >> 8, 572662306) | System.Runtime.Intrinsics.X86.Bmi2.ParallelBitDeposit(x, 286331153); x = Bits.BitPermuteStep(x, 61680, 12); x = Bits.BitPermuteStep(x, 13369548, 6); x = Bits.BitPermuteStep(x, 572662306, 1); x = Bits.BitPermuteStep(x, 202116108, 2); return x; } internal static ulong Shuffle2(ulong x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) return System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x >> 48, 9838263505978427528) | System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x >> 32, 4919131752989213764) | System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x >> 16, 2459565876494606882) | System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitDeposit(x, 1229782938247303441); x = Bits.BitPermuteStep(x, 4278255360, 24); x = Bits.BitPermuteStep(x, 264913582878960, 12); x = Bits.BitPermuteStep(x, 57421771435671756, 6); x = Bits.BitPermuteStep(x, 723401728380766730, 3); return x; } internal static uint Unshuffle(uint x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.IsEnabled) return (System.Runtime.Intrinsics.X86.Bmi2.ParallelBitExtract(x, 2863311530) << 16) | System.Runtime.Intrinsics.X86.Bmi2.ParallelBitExtract(x, 1431655765); x = Bits.BitPermuteStep(x, 572662306, 1); x = Bits.BitPermuteStep(x, 202116108, 2); x = Bits.BitPermuteStep(x, 15728880, 4); x = Bits.BitPermuteStep(x, 65280, 8); return x; } internal static ulong Unshuffle(ulong x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) return (System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x, 12297829382473034410) << 32) | System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x, 6148914691236517205); x = Bits.BitPermuteStep(x, 2459565876494606882, 1); x = Bits.BitPermuteStep(x, 868082074056920076, 2); x = Bits.BitPermuteStep(x, 67555025218437360, 4); x = Bits.BitPermuteStep(x, 280375465148160, 8); x = Bits.BitPermuteStep(x, 4294901760, 16); return x; } internal static ulong Unshuffle(ulong x, out ulong even) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) { even = System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x, 6148914691236517205); return System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x, 12297829382473034410); } ulong num = Unshuffle(x); even = (num & uint.MaxValue); return num >> 32; } internal static ulong Unshuffle(ulong x0, ulong x1, out ulong even) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) { even = (System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x0, 6148914691236517205) | (System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x1, 6148914691236517205) << 32)); return System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x0, 12297829382473034410) | (System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x1, 12297829382473034410) << 32); } ulong num = Unshuffle(x0); ulong num2 = Unshuffle(x1); even = ((num2 << 32) | (num & uint.MaxValue)); return (ulong)((long)(num >> 32) | ((long)num2 & -4294967296)); } internal static uint Unshuffle2(uint x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.IsEnabled) return (System.Runtime.Intrinsics.X86.Bmi2.ParallelBitExtract(x, 2290649224) << 24) | (System.Runtime.Intrinsics.X86.Bmi2.ParallelBitExtract(x, 1145324612) << 16) | (System.Runtime.Intrinsics.X86.Bmi2.ParallelBitExtract(x, 572662306) << 8) | System.Runtime.Intrinsics.X86.Bmi2.ParallelBitExtract(x, 286331153); x = Bits.BitPermuteStep(x, 202116108, 2); x = Bits.BitPermuteStep(x, 572662306, 1); x = Bits.BitPermuteStep(x, 61680, 12); x = Bits.BitPermuteStep(x, 13369548, 6); return x; } internal static ulong Unshuffle2(ulong x) { if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) return (System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x, 9838263505978427528) << 48) | (System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x, 4919131752989213764) << 32) | (System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x, 2459565876494606882) << 16) | System.Runtime.Intrinsics.X86.Bmi2.X64.ParallelBitExtract(x, 1229782938247303441); x = Bits.BitPermuteStep(x, 57421771435671756, 6); x = Bits.BitPermuteStep(x, 723401728380766730, 3); x = Bits.BitPermuteStep(x, 4278255360, 24); x = Bits.BitPermuteStep(x, 264913582878960, 12); return x; } internal static ulong Transpose(ulong x) { x = Bits.BitPermuteStep(x, 4042322160, 28); x = Bits.BitPermuteStep(x, 225176545447116, 14); x = Bits.BitPermuteStep(x, 47851476196393130, 7); return x; } } }