using System.Runtime.InteropServices;
using System.Security.Cryptography;
namespace XFESystem.DriverOracle;
internal sealed class VectorCase
{
public const int Count = 65_537, GuardWords = 32, BlockThreads = 256;
public const long MaximumDeviceBytes = 4 * 1024 * 1024;
public uint Seed { get; }
public uint Poison { get; }
public uint[] A { get; } = new uint[Count];
public uint[] B { get; } = new uint[Count];
public uint[] Initial { get; } = new uint[Count + 2 * GuardWords];
public uint[] Expected { get; } = new uint[Count + 2 * GuardWords];
public long DeviceBytes => ((long)A.Length + B.Length + Initial.Length) * sizeof(uint);
public VectorCase(uint seed)
{
Seed = seed; Poison = 0xDEADBEEFu ^ seed;
for (int index = 0; index < Count; index++)
{
A[index] = unchecked((0xFFFFFF00u + (uint)index * 0x9E3779B9u) ^ seed);
B[index] = unchecked(0x10203040u + ((uint)index ^ seed) * 0x85EBCA6Bu);
Initial[GuardWords + index] = Poison;
Expected[GuardWords + index] = unchecked(A[index] + B[index]);
}
for (int index = 0; index < GuardWords; index++)
{
Initial[index] = Expected[index] = 0xCAFE0000u ^ seed ^ (uint)index;
Initial[GuardWords + Count + index] = Expected[GuardWords + Count + index] = unchecked(0xBADC0000u ^ (seed + (uint)index));
}
if (DeviceBytes >= MaximumDeviceBytes) throw new InvalidOperationException("The fixed test exceeds the device allocation bound.");
}
public object Verify(uint[] actual)
{
if (actual.Length != Expected.Length) throw new InvalidOperationException("Result length differs from the complete guarded allocation.");
for (int index = 0; index < actual.Length; index++)
if (actual[index] != Expected[index]) throw new InvalidOperationException($"GPU result/guard mismatch at allocation word {index}: expected {Expected[index]:x8}, received {actual[index]:x8}.");
int changed = Enumerable.Range(0, Count).Count(index => actual[GuardWords + index] != Poison);
if (changed == 0) throw new InvalidOperationException("The output remains poisoned.");
return new { AllElementsMatched = true, MatchedElements = Count, PrefixGuardWords = GuardWords,
SuffixGuardWords = GuardWords, PrefixGuardPassed = true, SuffixGuardPassed = true,
ChangedFromPoison = changed, Modulo32OverflowElements = Enumerable.Range(0, Count).Count(index => (ulong)A[index] + B[index] > uint.MaxValue),
ExpectedSha256 = Hash(Expected), ActualSha256 = Hash(actual), OutputBodySha256 = Hash(actual.AsSpan(GuardWords, Count)),
InputASha256 = Hash(A), InputBSha256 = Hash(B) };
}
public static string Hash(ReadOnlySpan<uint> data) => Convert.ToHexStringLower(SHA256.HashData(MemoryMarshal.AsBytes(data)));
public static int SelfTest()
{
int checks = 0;
foreach (uint seed in new[] { 0u, 1u, uint.MaxValue, 0x12345678u })
{
var vector = new VectorCase(seed); _ = vector.Verify((uint[])vector.Expected.Clone()); checks++;
foreach (int index in new[] { 0, GuardWords - 1, GuardWords, GuardWords + Count - 1, GuardWords + Count, vector.Expected.Length - 1 })
{
var bad = (uint[])vector.Expected.Clone(); bad[index] ^= 1;
bool rejected = false;
try { vector.Verify(bad); } catch (InvalidOperationException) { rejected = true; }
if (!rejected) throw new InvalidOperationException("The verifier accepted a corrupted result or guard.");
checks++;
}
bool poisonRejected = false;
try { vector.Verify(vector.Initial); } catch (InvalidOperationException) { poisonRejected = true; }
if (!poisonRejected) throw new InvalidOperationException("The verifier accepted untouched poison.");
checks++;
}
if (Count % BlockThreads == 0) throw new InvalidOperationException("The launch must exercise the partial-block bound.");
return checks + 1;
}
}
using System.Runtime.InteropServices;
using System.Security.Cryptography;
namespace XFESystem.DriverOracle;
internal sealed class VectorCase
{
public const int Count = 65_537, GuardWords = 32, BlockThreads = 256;
public const long MaximumDeviceBytes = 4 * 1024 * 1024;
public uint Seed { get; }
public uint Poison { get; }
public uint[] A { get; } = new uint[Count];
public uint[] B { get; } = new uint[Count];
public uint[] Initial { get; } = new uint[Count + 2 * GuardWords];
public uint[] Expected { get; } = new uint[Count + 2 * GuardWords];
public long DeviceBytes => ((long)A.Length + B.Length + Initial.Length) * sizeof(uint);
public VectorCase(uint seed)
{
Seed = seed; Poison = 0xDEADBEEFu ^ seed;
for (int index = 0; index < Count; index++)
{
A[index] = unchecked((0xFFFFFF00u + (uint)index * 0x9E3779B9u) ^ seed);
B[index] = unchecked(0x10203040u + ((uint)index ^ seed) * 0x85EBCA6Bu);
Initial[GuardWords + index] = Poison;
Expected[GuardWords + index] = unchecked(A[index] + B[index]);
}
for (int index = 0; index < GuardWords; index++)
{
Initial[index] = Expected[index] = 0xCAFE0000u ^ seed ^ (uint)index;
Initial[GuardWords + Count + index] = Expected[GuardWords + Count + index] = unchecked(0xBADC0000u ^ (seed + (uint)index));
}
if (DeviceBytes >= MaximumDeviceBytes) throw new InvalidOperationException("The fixed test exceeds the device allocation bound.");
}
public object Verify(uint[] actual)
{
if (actual.Length != Expected.Length) throw new InvalidOperationException("Result length differs from the complete guarded allocation.");
for (int index = 0; index < actual.Length; index++)
if (actual[index] != Expected[index]) throw new InvalidOperationException($"GPU result/guard mismatch at allocation word {index}: expected {Expected[index]:x8}, received {actual[index]:x8}.");
int changed = Enumerable.Range(0, Count).Count(index => actual[GuardWords + index] != Poison);
if (changed == 0) throw new InvalidOperationException("The output remains poisoned.");
return new { AllElementsMatched = true, MatchedElements = Count, PrefixGuardWords = GuardWords,
SuffixGuardWords = GuardWords, PrefixGuardPassed = true, SuffixGuardPassed = true,
ChangedFromPoison = changed, Modulo32OverflowElements = Enumerable.Range(0, Count).Count(index => (ulong)A[index] + B[index] > uint.MaxValue),
ExpectedSha256 = Hash(Expected), ActualSha256 = Hash(actual), OutputBodySha256 = Hash(actual.AsSpan(GuardWords, Count)),
InputASha256 = Hash(A), InputBSha256 = Hash(B) };
}
public static string Hash(ReadOnlySpan<uint> data) => Convert.ToHexStringLower(SHA256.HashData(MemoryMarshal.AsBytes(data)));
public static int SelfTest()
{
int checks = 0;
foreach (uint seed in new[] { 0u, 1u, uint.MaxValue, 0x12345678u })
{
var vector = new VectorCase(seed); _ = vector.Verify((uint[])vector.Expected.Clone()); checks++;
foreach (int index in new[] { 0, GuardWords - 1, GuardWords, GuardWords + Count - 1, GuardWords + Count, vector.Expected.Length - 1 })
{
var bad = (uint[])vector.Expected.Clone(); bad[index] ^= 1;
bool rejected = false;
try { vector.Verify(bad); } catch (InvalidOperationException) { rejected = true; }
if (!rejected) throw new InvalidOperationException("The verifier accepted a corrupted result or guard.");
checks++;
}
bool poisonRejected = false;
try { vector.Verify(vector.Initial); } catch (InvalidOperationException) { poisonRejected = true; }
if (!poisonRejected) throw new InvalidOperationException("The verifier accepted untouched poison.");
checks++;
}
if (Count % BlockThreads == 0) throw new InvalidOperationException("The launch must exercise the partial-block bound.");
return checks + 1;
}
}