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 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; } }