Remove WireGuard integration from production deployment to simplify infrastructure: - Remove docker-compose-direct-access.yml (VPN-bound services) - Remove VPN-only middlewares from Grafana, Prometheus, Portainer - Remove WireGuard middleware definitions from Traefik - Remove WireGuard IPs (10.8.0.0/24) from Traefik forwarded headers All monitoring services now publicly accessible via subdomains: - grafana.michaelschiemer.de (with Grafana native auth) - prometheus.michaelschiemer.de (with Basic Auth) - portainer.michaelschiemer.de (with Portainer native auth) All services use Let's Encrypt SSL certificates via Traefik.
113 lines
3.5 KiB
PHP
113 lines
3.5 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
echo "=== Syndrome Formula Test ===\n\n";
|
||
|
||
// For Reed-Solomon, syndromes are calculated as:
|
||
// S[i] = c(α^i) where c(x) is the codeword polynomial
|
||
// c(x) = c[0] + c[1]*x + c[2]*x^2 + ... + c[n-1]*x^(n-1)
|
||
// S[i] = sum over j: c[j] * (α^i)^j
|
||
|
||
// Initialize GF(256)
|
||
$gfLog = array_fill(0, 256, 0);
|
||
$gfExp = array_fill(0, 512, 0);
|
||
|
||
$x = 1;
|
||
for ($i = 0; $i < 255; $i++) {
|
||
$gfExp[$i] = $x;
|
||
$gfLog[$x] = $i;
|
||
$x <<= 1;
|
||
if ($x & 0x100) {
|
||
$x ^= 0x11d;
|
||
}
|
||
}
|
||
|
||
for ($i = 255; $i < 512; $i++) {
|
||
$gfExp[$i] = $gfExp[$i - 255];
|
||
}
|
||
|
||
function gfMult(array $gfExp, array $gfLog, int $a, int $b): int
|
||
{
|
||
if ($a === 0 || $b === 0) return 0;
|
||
return $gfExp[$gfLog[$a] + $gfLog[$b]];
|
||
}
|
||
|
||
// Test with a known valid codeword
|
||
// For RS(7, 4), if data = [1, 2, 3, 4] and generator = [1, 7, 14, 8]
|
||
// We need to calculate the correct EC codewords
|
||
|
||
echo "Testing syndrome calculation:\n";
|
||
echo "For a valid RS codeword, all syndromes should be 0.\n\n";
|
||
|
||
// Try with a simple case: data = [1], ecCodewords = 2
|
||
// Generator: g(x) = (x-1)(x-2) = x^2 + 3x + 2
|
||
// But in GF(256), we need to use α^i values
|
||
|
||
// Actually, let's use the correct generator polynomial from specification
|
||
// For 10 EC codewords: [0, 251, 67, 46, 61, 118, 70, 64, 94, 32, 45]
|
||
// This means: g(x) = x^10 + 251*x^9 + 67*x^8 + ... + 45
|
||
|
||
// The key insight: For the codeword to be valid, when we evaluate it at
|
||
// the roots of the generator (α^0, α^1, ..., α^9), we should get 0.
|
||
|
||
// But wait - maybe the issue is that we're evaluating at the wrong powers?
|
||
// In RS, we evaluate at α^0, α^1, ..., α^(t-1) where t is the number of EC codewords.
|
||
|
||
echo "Note: Syndrome calculation evaluates c(x) at α^0, α^1, ..., α^(t-1)\n";
|
||
echo "where c(x) = c[0] + c[1]*x + c[2]*x^2 + ... + c[n-1]*x^(n-1)\n";
|
||
echo "and c[0] is the FIRST codeword (highest power)\n";
|
||
echo "OR c[n-1] is the FIRST codeword (lowest power)?\n\n";
|
||
|
||
echo "This is the key question - what is the polynomial representation?\n";
|
||
echo "In QR codes, codewords are placed MSB-first, so:\n";
|
||
echo " c[0] is the coefficient of x^(n-1) (highest power)\n";
|
||
echo " c[n-1] is the coefficient of x^0 (lowest power)\n\n";
|
||
|
||
echo "So the polynomial is: c(x) = c[0]*x^(n-1) + c[1]*x^(n-2) + ... + c[n-1]*1\n";
|
||
echo "When evaluating at α^i, we need: c(α^i) = sum(c[j] * (α^i)^(n-1-j))\n\n";
|
||
|
||
// Test with reversed order
|
||
echo "=== Testing Reversed Evaluation ===\n";
|
||
$codeword = [64, 180, 132, 84, 196, 196, 242, 5, 116, 245, 36, 196, 64, 236, 17, 236, 48, 24, 202, 227, 36, 252, 121, 15, 219, 141];
|
||
$n = count($codeword);
|
||
$t = 10;
|
||
|
||
echo "Codeword length: {$n}\n";
|
||
echo "EC codewords: {$t}\n\n";
|
||
|
||
$syndromes = [];
|
||
for ($i = 0; $i < $t; $i++) {
|
||
$alphaPower = $gfExp[$i]; // α^i
|
||
$syndrome = 0;
|
||
|
||
// Evaluate: c(x) = c[0]*x^(n-1) + c[1]*x^(n-2) + ... + c[n-1]
|
||
// At x = α^i: c(α^i) = sum(c[j] * (α^i)^(n-1-j))
|
||
$power = $gfExp[$i * ($n - 1) % 255]; // (α^i)^(n-1)
|
||
|
||
for ($j = 0; $j < $n; $j++) {
|
||
$syndrome ^= gfMult($gfExp, $gfLog, $codeword[$j], $power);
|
||
// Next power: (α^i)^(n-2-j) = current_power / α^i
|
||
$power = gfMult($gfExp, $gfLog, $power, $gfExp[255 - $i]); // Divide by α^i
|
||
}
|
||
|
||
$syndromes[$i] = $syndrome;
|
||
echo " S[{$i}] = {$syndrome}\n";
|
||
}
|
||
|
||
$allZero = true;
|
||
foreach ($syndromes as $s) {
|
||
if ($s !== 0) {
|
||
$allZero = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ($allZero) {
|
||
echo "\n✅ All syndromes are zero with reversed evaluation!\n";
|
||
} else {
|
||
echo "\n❌ Still not all zero\n";
|
||
}
|
||
|
||
|