File size: 7,040 Bytes
224e773 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | /*
* routing_tensor.c — QRA Routing Tensor
*
* Discrete routing alphabet:
* Π = 0x01 (pi, identity/continuation)
* Γ = 0x03 (gamma, intermediate state)
* Δ = 0x04 (delta, transition)
* Ω = 0x0A (omega, absorbing/termination)
* Λ = 0xFF (lambda, left identity)
* Ψ = 0x0B (psi, control)
*
* The routing tensor Q ∈ {0,...,5}^{6×6} maps (current_glyph, prev_glyph) → next_glyph.
*
* Key property: H(next | current, previous) = 0 nats
* The next state is deterministic given current state and one predecessor.
* Zero entropy: no sampling, no randomness.
*
* Distinguished elements:
* - Λ (left identity): Q[Λ][j] = j ∀j (continuation)
* - Ω (absorber): Q[Ω][j] = Ω ∀j (termination sink)
*/
#include "hyperkitty/qra.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* ================================================================
* Routing glyphs and encoding
* ================================================================ */
#define GLYPH_PI 0 /* Π = 0x01 → index 0 */
#define GLYPH_GAM 1 /* Γ = 0x03 → index 1 */
#define GLYPH_DEL 2 /* Δ = 0x04 → index 2 */
#define GLYPH_OME 3 /* Ω = 0x0A → index 3 (absorber) */
#define GLYPH_LAM 4 /* Λ = 0xFF → index 4 (identity) */
#define GLYPH_PSI 5 /* Ψ = 0x0B → index 5 */
#define NUM_GLYPHS 6
static const char *glyph_name(int g) {
const char *names[] = { "PI", "GAMMA", "DELTA", "OMEGA", "LAMBDA", "PSI" };
return (g >= 0 && g < NUM_GLYPHS) ? names[g] : "UNKNOWN";
}
static int glyph_from_byte(uint8_t b) {
switch (b) {
case 0x01: return GLYPH_PI;
case 0x03: return GLYPH_GAM;
case 0x04: return GLYPH_DEL;
case 0x0A: return GLYPH_OME;
case 0xFF: return GLYPH_LAM;
case 0x0B: return GLYPH_PSI;
default: return -1;
}
}
static uint8_t byte_from_glyph(int g) {
const uint8_t bytes[] = { 0x01, 0x03, 0x04, 0x0A, 0xFF, 0x0B };
return (g >= 0 && g < NUM_GLYPHS) ? bytes[g] : 0;
}
/* ================================================================
* Routing tensor Q[6][6]
* ================================================================ */
typedef struct {
int Q[NUM_GLYPHS][NUM_GLYPHS]; /* Next glyph given (current, prev) */
} RoutingTensor;
static RoutingTensor *routing_tensor_alloc(void) {
RoutingTensor *rt = malloc(sizeof(RoutingTensor));
if (!rt) return NULL;
/* Initialize: identity behavior by default */
for (int i = 0; i < NUM_GLYPHS; i++) {
for (int j = 0; j < NUM_GLYPHS; j++) {
rt->Q[i][j] = i; /* Stay in current glyph */
}
}
/* Lambda (left identity): Q[LAM][j] = j (continue to j) */
for (int j = 0; j < NUM_GLYPHS; j++) {
rt->Q[GLYPH_LAM][j] = j;
}
/* Omega (absorber): Q[OME][j] = OME (sink to absorber) */
for (int j = 0; j < NUM_GLYPHS; j++) {
rt->Q[GLYPH_OME][j] = GLYPH_OME;
}
/* Example transitions */
rt->Q[GLYPH_PI][GLYPH_GAM] = GLYPH_DEL; /* PI ← GAM → DEL */
rt->Q[GLYPH_GAM][GLYPH_PI] = GLYPH_DEL; /* GAM ← PI → DEL */
rt->Q[GLYPH_DEL][GLYPH_DEL] = GLYPH_OME; /* DEL ← DEL → OME (absorb) */
return rt;
}
void routing_tensor_free(RoutingTensor *rt) {
free(rt);
}
/* ================================================================
* Witness evolution (for token state machines)
* ================================================================ */
int hk_qra_step(int current, int previous, RoutingTensor *rt) {
if (!rt || current < 0 || current >= NUM_GLYPHS ||
previous < 0 || previous >= NUM_GLYPHS) {
return GLYPH_OME; /* Default to absorber on error */
}
return rt->Q[current][previous];
}
/* ================================================================
* Witness progression (used in token state)
* ================================================================ */
typedef struct {
int glyphs[3]; /* Current witness state: [w0, w1, w2] */
} Witness;
static Witness witness_init(int g0, int g1, int g2) {
Witness w;
w.glyphs[0] = g0;
w.glyphs[1] = g1;
w.glyphs[2] = g2;
return w;
}
Witness hk_qra_evolve_witness(Witness w, RoutingTensor *rt) {
/* Evolve: w' = [Q(w0, w1), Q(w1, w2), Q(w2, w0)] */
Witness next;
next.glyphs[0] = hk_qra_step(w.glyphs[0], w.glyphs[1], rt);
next.glyphs[1] = hk_qra_step(w.glyphs[1], w.glyphs[2], rt);
next.glyphs[2] = hk_qra_step(w.glyphs[2], w.glyphs[0], rt);
return next;
}
/* ================================================================
* Absorption detection
* ================================================================ */
int hk_qra_is_absorbed(Witness w) {
/* Absorbed if all glyphs are omega */
return (w.glyphs[0] == GLYPH_OME &&
w.glyphs[1] == GLYPH_OME &&
w.glyphs[2] == GLYPH_OME);
}
int hk_qra_is_fixed(Witness w) {
/* Fixed if all glyphs are lambda (identity) */
return (w.glyphs[0] == GLYPH_LAM &&
w.glyphs[1] == GLYPH_LAM &&
w.glyphs[2] == GLYPH_LAM);
}
/* ================================================================
* Token lifetime via algebraic exhaustion
* ================================================================ */
typedef struct {
uint64_t sequence;
Witness witness;
int steps_to_absorption; /* How many evolution steps until absorption */
} TokenState;
int hk_qra_token_lifetime(Witness initial, RoutingTensor *rt, int max_steps) {
if (!rt) return -1;
Witness w = initial;
/* Fixed points (lambda loop) are invalid—tokens with all-lambda witness
* never exhaust and would bypass replay resistance. */
if (hk_qra_is_fixed(w)) {
return -1;
}
for (int step = 0; step < max_steps; step++) {
w = hk_qra_evolve_witness(w, rt);
if (hk_qra_is_absorbed(w)) {
return step;
}
}
return -1; /* Did not absorb within max_steps */
}
/* ================================================================
* Debug output
* ================================================================ */
void hk_qra_print_tensor(RoutingTensor *rt) {
if (!rt) return;
printf("Routing Tensor Q[current][previous]:\n\n");
printf(" ");
for (int j = 0; j < NUM_GLYPHS; j++) {
printf("%8s ", glyph_name(j));
}
printf("\n");
for (int i = 0; i < NUM_GLYPHS; i++) {
printf("%5s ", glyph_name(i));
for (int j = 0; j < NUM_GLYPHS; j++) {
printf("%8s ", glyph_name(rt->Q[i][j]));
}
printf("\n");
}
}
void hk_qra_print_witness(Witness w) {
printf("Witness: [%s, %s, %s]\n",
glyph_name(w.glyphs[0]),
glyph_name(w.glyphs[1]),
glyph_name(w.glyphs[2]));
}
|