zeropoint-node 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +97 -0
- package/CITATION.cff +1 -1
- package/README.md +1 -1
- package/package.json +5 -3
- package/src/crypto/ml-kem-768-acvp.json +492 -0
- package/src/crypto/ml-kem.test.ts +140 -0
- package/src/crypto/ml-kem.ts +554 -0
- package/src/quantum/error-correction.ts +69 -16
- package/src/quantum/hybrid.ts +2 -2
- package/src/quantum/simulator.ts +19 -0
- package/src/quantum/tomography.ts +4 -4
- package/src/verification/lean-bridge.test.ts +109 -228
- package/src/verification/lean-bridge.ts +401 -153
- package/src/crypto/kyber-real.test.ts +0 -198
- package/src/crypto/kyber-real.ts +0 -489
|
@@ -1,27 +1,74 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lean
|
|
2
|
+
* Lean bridge — what is actually checked, and what is only written down.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
*
|
|
4
|
+
* This module used to report "Verified: 2/2", "Confidence: 100.0%" and
|
|
5
|
+
* "Production Grade (Formally Verified)". None of it was measured. The hash
|
|
6
|
+
* covered the theorem's NAME rather than its proof; `verifyProofCertificate`
|
|
7
|
+
* tested that some strings were non-empty and that a hash was 16 characters,
|
|
8
|
+
* which is true of every certificate this file can construct; `lean_version`
|
|
9
|
+
* was asserted although no Lean has ever run here; and seven of the thirteen
|
|
10
|
+
* Lean scripts below end in `sorry`, which is Lean for "not proved".
|
|
9
11
|
*
|
|
10
|
-
*
|
|
12
|
+
* The scripts are kept verbatim — they were never the problem. What changed is
|
|
13
|
+
* that a certificate now carries two independent, separately reported facts:
|
|
14
|
+
*
|
|
15
|
+
* lean_status what the Lean source actually is: a script, a `sorry`
|
|
16
|
+
* placeholder, an axiom, or absent. Derived by reading the
|
|
17
|
+
* script, not declared.
|
|
18
|
+
* seal whether a RECOMPUTABLE predicate for that theorem ran and
|
|
19
|
+
* held, against the simulator in `src/quantum/`. Not a proof of
|
|
20
|
+
* the general theorem — a decision on a concrete instance.
|
|
21
|
+
*
|
|
22
|
+
* A theorem counts as verified here only when its seal holds. `sorry` scripts
|
|
23
|
+
* with a passing seal are reported as sealed-but-not-proved, because a checked
|
|
24
|
+
* instance is not a proof, and an unchecked proof script is not evidence.
|
|
25
|
+
* Nothing in this file claims Lean was invoked, because it was not.
|
|
26
|
+
*
|
|
27
|
+
* To make this honest at the Lean level someone must build the Lean
|
|
28
|
+
* development these scripts gesture at and run `lake build` in CI. Until then
|
|
29
|
+
* the seals are the real content and the scripts are documentation.
|
|
11
30
|
*/
|
|
12
31
|
|
|
13
32
|
import { createHash } from 'node:crypto'
|
|
33
|
+
import {
|
|
34
|
+
zeroState,
|
|
35
|
+
applyGate1,
|
|
36
|
+
isNormalized,
|
|
37
|
+
qft,
|
|
38
|
+
iqft,
|
|
39
|
+
grover,
|
|
40
|
+
groverIterations,
|
|
41
|
+
shor,
|
|
42
|
+
measureSyndromeRepetition,
|
|
43
|
+
STEANE_CODE,
|
|
44
|
+
symplecticProduct,
|
|
45
|
+
estimateSurfaceCodeThreshold,
|
|
46
|
+
} from '../quantum/index.ts'
|
|
47
|
+
import { ML_KEM_768 } from '../crypto/ml-kem.ts'
|
|
48
|
+
import { sqrt } from '../0/algebra.ts'
|
|
14
49
|
|
|
15
50
|
// ============================================================================
|
|
16
51
|
// PROOF CERTIFICATE TYPES
|
|
17
52
|
// ============================================================================
|
|
18
53
|
|
|
54
|
+
/** What the Lean source for a theorem actually is. Read, never declared. */
|
|
55
|
+
export type LeanStatus = 'script' | 'sorry' | 'axiom' | 'absent'
|
|
56
|
+
|
|
57
|
+
/** Whether a recomputable predicate ran and held for this theorem. */
|
|
58
|
+
export type SealStatus = 'held' | 'failed' | 'none'
|
|
59
|
+
|
|
19
60
|
export interface ProofCertificate {
|
|
20
61
|
readonly theorem_name: string
|
|
21
62
|
readonly statement: string
|
|
22
63
|
readonly proof_script: string
|
|
23
64
|
readonly verified_at: string
|
|
24
|
-
|
|
65
|
+
/** Derived from proof_script — 'sorry' means Lean would reject it. */
|
|
66
|
+
readonly lean_status: LeanStatus
|
|
67
|
+
/** 'none' when no executable predicate exists for this theorem. */
|
|
68
|
+
readonly seal: SealStatus
|
|
69
|
+
/** What the seal actually computes, so a reader can judge its weight. */
|
|
70
|
+
readonly seal_basis: string
|
|
71
|
+
/** Content address of statement + script. Changing either changes this. */
|
|
25
72
|
readonly hash: string
|
|
26
73
|
}
|
|
27
74
|
|
|
@@ -137,225 +184,426 @@ export const LEAN_PROOFS = {
|
|
|
137
184
|
axiom lwe_hardness : ¬ (polynomial_time_solves_lwe 768 3329)
|
|
138
185
|
`,
|
|
139
186
|
} as const
|
|
140
|
-
|
|
141
187
|
// ============================================================================
|
|
142
|
-
//
|
|
188
|
+
// SEALS - recomputable predicates, the only thing here that counts as checked
|
|
143
189
|
// ============================================================================
|
|
144
190
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
statement: 'IsUnitary hadamard',
|
|
150
|
-
property: 'unitary' as const,
|
|
151
|
-
},
|
|
152
|
-
PauliX: {
|
|
153
|
-
theorem_name: 'pauliX_unitary',
|
|
154
|
-
statement: 'IsUnitary pauliX',
|
|
155
|
-
property: 'unitary' as const,
|
|
156
|
-
},
|
|
157
|
-
}
|
|
191
|
+
// 1/sqrt(2) via the repo's algebra, not ambient Math.
|
|
192
|
+
const SQRT1_2 = 1 / sqrt(2)
|
|
193
|
+
type C = { re: number; im: number }
|
|
194
|
+
const c = (re: number, im = 0): C => ({ re, im })
|
|
158
195
|
|
|
159
|
-
|
|
196
|
+
const H: [C, C, C, C] = [c(SQRT1_2), c(SQRT1_2), c(SQRT1_2), c(-SQRT1_2)]
|
|
197
|
+
const X: [C, C, C, C] = [c(0), c(1), c(1), c(0)]
|
|
198
|
+
const Y: [C, C, C, C] = [c(0), c(0, -1), c(0, 1), c(0)]
|
|
160
199
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
hash: computeProofHash(info.theorem_name),
|
|
170
|
-
}
|
|
200
|
+
const CLOSE = 1e-9
|
|
201
|
+
const near = (a: number, b: number): boolean => a - b < CLOSE && b - a < CLOSE
|
|
202
|
+
|
|
203
|
+
interface Seal {
|
|
204
|
+
/** One line a reader can check the predicate against. */
|
|
205
|
+
readonly basis: string
|
|
206
|
+
/** Decides a concrete instance. Must be able to return false. */
|
|
207
|
+
readonly decide: () => boolean
|
|
171
208
|
}
|
|
172
209
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Every seal decides an INSTANCE, never the universally quantified theorem.
|
|
212
|
+
* hadamard_squared checks H^2 = I on both computational basis states of one
|
|
213
|
+
* qubit, which for a linear map is the whole story; grover_speedup checks a
|
|
214
|
+
* success probability at one problem size, which is NOT the asymptotic claim.
|
|
215
|
+
* The basis string says which is which so the distinction cannot be lost.
|
|
216
|
+
*/
|
|
217
|
+
export const SEALS: Record<string, Seal> = {
|
|
218
|
+
hadamard_squared: {
|
|
219
|
+
basis: 'H applied twice to each basis state of one qubit returns the input amplitudes (linearity makes 2 states exhaustive)',
|
|
220
|
+
decide: () => {
|
|
221
|
+
for (const start of [0, 1]) {
|
|
222
|
+
let reg = zeroState(1)
|
|
223
|
+
if (start === 1) reg = applyGate1(reg, 0, X)
|
|
224
|
+
const twice = applyGate1(applyGate1(reg, 0, H), 0, H)
|
|
225
|
+
for (let i = 0; i < 2; i++) {
|
|
226
|
+
if (!near(twice.amps[i]!.re, reg.amps[i]!.re)) return false
|
|
227
|
+
if (!near(twice.amps[i]!.im, reg.amps[i]!.im)) return false
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return true
|
|
180
231
|
},
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
hadamard_unitary: {
|
|
235
|
+
basis: 'H preserves the norm of a 3-qubit register (unitary maps are exactly the norm-preserving ones)',
|
|
236
|
+
decide: () => {
|
|
237
|
+
let reg = zeroState(3)
|
|
238
|
+
for (const q of [0, 1, 2]) reg = applyGate1(reg, q, H)
|
|
239
|
+
return isNormalized(reg)
|
|
186
240
|
},
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
241
|
+
},
|
|
242
|
+
|
|
243
|
+
pauliX_unitary: {
|
|
244
|
+
basis: 'X applied twice is the identity, and X preserves the norm',
|
|
245
|
+
decide: () => {
|
|
246
|
+
const reg = zeroState(2)
|
|
247
|
+
const twice = applyGate1(applyGate1(reg, 0, X), 0, X)
|
|
248
|
+
return isNormalized(twice) && near(twice.amps[0]!.re, 1)
|
|
192
249
|
},
|
|
193
|
-
}
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
pauli_anticomm: {
|
|
253
|
+
basis: 'XY and YX differ by an overall sign on both basis states of one qubit',
|
|
254
|
+
decide: () => {
|
|
255
|
+
for (const start of [0, 1]) {
|
|
256
|
+
let reg = zeroState(1)
|
|
257
|
+
if (start === 1) reg = applyGate1(reg, 0, X)
|
|
258
|
+
const xy = applyGate1(applyGate1(reg, 0, Y), 0, X)
|
|
259
|
+
const yx = applyGate1(applyGate1(reg, 0, X), 0, Y)
|
|
260
|
+
for (let i = 0; i < 2; i++) {
|
|
261
|
+
if (!near(xy.amps[i]!.re, -yx.amps[i]!.re)) return false
|
|
262
|
+
if (!near(xy.amps[i]!.im, -yx.amps[i]!.im)) return false
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return true
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
born_rule_sum: {
|
|
270
|
+
basis: 'squared amplitudes sum to 1 after a Hadamard layer on 4 qubits',
|
|
271
|
+
decide: () => {
|
|
272
|
+
let reg = zeroState(4)
|
|
273
|
+
for (const q of [0, 1, 2, 3]) reg = applyGate1(reg, q, H)
|
|
274
|
+
const total = reg.amps.reduce((s, a) => s + a.re * a.re + a.im * a.im, 0)
|
|
275
|
+
return near(total, 1)
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
qft_unitary: {
|
|
280
|
+
basis: 'inverse QFT undoes QFT on a 3-qubit register, amplitude by amplitude',
|
|
281
|
+
decide: () => {
|
|
282
|
+
let reg = zeroState(3)
|
|
283
|
+
reg = applyGate1(reg, 0, H)
|
|
284
|
+
reg = applyGate1(reg, 2, X)
|
|
285
|
+
const back = iqft(qft(reg))
|
|
286
|
+
for (let i = 0; i < back.amps.length; i++) {
|
|
287
|
+
if (!near(back.amps[i]!.re, reg.amps[i]!.re)) return false
|
|
288
|
+
if (!near(back.amps[i]!.im, reg.amps[i]!.im)) return false
|
|
289
|
+
}
|
|
290
|
+
return true
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
grover_amplification: {
|
|
295
|
+
basis: 'Grover leaves the marked state with probability above the 1/N a random guess gets (n=4, N=16)',
|
|
296
|
+
decide: () => {
|
|
297
|
+
const n = 4
|
|
298
|
+
const target = 11
|
|
299
|
+
const out = grover(n, target, groverIterations(1 << n))
|
|
300
|
+
const p = out.amps[target]!.re ** 2 + out.amps[target]!.im ** 2
|
|
301
|
+
return p > 1 / (1 << n)
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
|
|
305
|
+
grover_speedup: {
|
|
306
|
+
basis: 'INSTANCE ONLY, not the asymptotic bound: round((pi/4)*sqrt(N)) iterations reach probability above 0.9 at N=16',
|
|
307
|
+
decide: () => {
|
|
308
|
+
const n = 4
|
|
309
|
+
const target = 6
|
|
310
|
+
const out = grover(n, target, groverIterations(1 << n))
|
|
311
|
+
const p = out.amps[target]!.re ** 2 + out.amps[target]!.im ** 2
|
|
312
|
+
return p > 9 / 10
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
shor_period_finding: {
|
|
317
|
+
basis: 'INSTANCE ONLY: shor(15, 7) returns non-trivial factors whose product is 15',
|
|
318
|
+
decide: () => {
|
|
319
|
+
const factors = shor(15, 7)
|
|
320
|
+
if (!Array.isArray(factors) || factors.length !== 2) return false
|
|
321
|
+
const [p, q] = factors as [number, number]
|
|
322
|
+
if (p <= 1 || q <= 1 || p >= 15 || q >= 15) return false
|
|
323
|
+
return p * q === 15
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
repetition_detects_error: {
|
|
328
|
+
basis: 'a clean 3-qubit codeword gives the zero syndrome and a single X error gives a non-zero one, so the syndrome distinguishes them',
|
|
329
|
+
decide: () => {
|
|
330
|
+
// |000> is the logical zero of the repetition code: no error, so the
|
|
331
|
+
// syndrome must be all zero. One X on qubit 0 must show up.
|
|
332
|
+
const clean = measureSyndromeRepetition(zeroState(3))
|
|
333
|
+
if (clean.detected || clean.syndrome.some((b) => b !== 0)) return false
|
|
334
|
+
const flipped = measureSyndromeRepetition(applyGate1(zeroState(3), 0, X))
|
|
335
|
+
return flipped.detected && flipped.syndrome.some((b) => b !== 0)
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
steane_corrects_error: {
|
|
340
|
+
basis: 'Steane [[7,1,3]] is a stabiliser group: exactly n-k = 6 generators, symplectically independent (rank 6), pairwise commuting, and distance 3 corrects floor((d-1)/2) = 1 arbitrary error',
|
|
341
|
+
decide: () => {
|
|
342
|
+
const code = STEANE_CODE
|
|
343
|
+
const n = code.physicalQubits
|
|
344
|
+
const k = code.logicalQubits
|
|
345
|
+
if (n !== 7 || k !== 1 || code.distance !== 3) return false
|
|
346
|
+
if ((code.distance - 1) / 2 < 1) return false
|
|
347
|
+
|
|
348
|
+
const g = code.generators
|
|
349
|
+
// A stabiliser group for [[n,k,d]] needs exactly n - k generators.
|
|
350
|
+
if (g.length !== n - k) return false
|
|
351
|
+
// Every pair must commute, i.e. have symplectic product zero.
|
|
352
|
+
for (let i = 0; i < g.length; i++) {
|
|
353
|
+
for (let j = i + 1; j < g.length; j++) {
|
|
354
|
+
if (symplecticProduct(g[i]!, g[j]!) !== 0) return false
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// And they must be independent over GF(2), or they fix fewer qubits than
|
|
358
|
+
// claimed. Gaussian elimination on the 2n-bit rows.
|
|
359
|
+
const M = g.map((r) => [...r])
|
|
360
|
+
let rank = 0
|
|
361
|
+
for (let col = 0; col < 2 * n && rank < M.length; col++) {
|
|
362
|
+
let pivot = -1
|
|
363
|
+
for (let r = rank; r < M.length; r++) if (M[r]![col] === 1) { pivot = r; break }
|
|
364
|
+
if (pivot < 0) continue
|
|
365
|
+
const tmp = M[rank]!; M[rank] = M[pivot]!; M[pivot] = tmp
|
|
366
|
+
for (let r = 0; r < M.length; r++) {
|
|
367
|
+
if (r !== rank && M[r]![col] === 1) {
|
|
368
|
+
for (let b = 0; b < 2 * n; b++) M[r]![b] = M[r]![b]! ^ M[rank]![b]!
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
rank++
|
|
372
|
+
}
|
|
373
|
+
return rank === n - k
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
surface_code_threshold: {
|
|
378
|
+
basis: 'estimateSurfaceCodeThreshold separates the two sides of the 1% threshold: below it reports below, above it does not',
|
|
379
|
+
decide: () => {
|
|
380
|
+
const below = estimateSurfaceCodeThreshold(3, 1 / 1000)
|
|
381
|
+
const above = estimateSurfaceCodeThreshold(3, 1 / 10)
|
|
382
|
+
return below.isBelowThreshold === true && above.isBelowThreshold === false
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
|
|
386
|
+
kyber_security: {
|
|
387
|
+
basis: 'the shipped ML-KEM parameters are ML-KEM-768 (ek 1184, dk 2400, ct 1088). NIST puts that at category 3, NOT the 128 the Lean script states.',
|
|
388
|
+
decide: () =>
|
|
389
|
+
ML_KEM_768.encapsulationKeyBytes === 1184 &&
|
|
390
|
+
ML_KEM_768.decapsulationKeyBytes === 2400 &&
|
|
391
|
+
ML_KEM_768.ciphertextBytes === 1088,
|
|
392
|
+
},
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// ============================================================================
|
|
396
|
+
// PROOF GENERATION
|
|
397
|
+
// ============================================================================
|
|
398
|
+
|
|
399
|
+
/** Read what the Lean source is. A sorry anywhere means Lean would reject it. */
|
|
400
|
+
export function readLeanStatus(script: string): LeanStatus {
|
|
401
|
+
const s = script.trim()
|
|
402
|
+
if (s.length === 0) return 'absent'
|
|
403
|
+
if (/\bsorry\b/.test(s)) return 'sorry'
|
|
404
|
+
if (/^axiom\b/m.test(s)) return 'axiom'
|
|
405
|
+
return 'script'
|
|
406
|
+
}
|
|
194
407
|
|
|
195
|
-
|
|
408
|
+
/**
|
|
409
|
+
* Content address of the claim. Covers the statement and the proof script, so
|
|
410
|
+
* editing either changes the hash. The previous version hashed the theorem's
|
|
411
|
+
* NAME, which stayed constant no matter what the proof said.
|
|
412
|
+
*/
|
|
413
|
+
export function computeProofHash(statement: string, proof_script: string): string {
|
|
414
|
+
return createHash('sha256').update(statement).update(' ').update(proof_script).digest('hex').slice(0, 16)
|
|
415
|
+
}
|
|
196
416
|
|
|
417
|
+
/** Run the seal for a theorem, if one exists. */
|
|
418
|
+
export function runSeal(theorem_name: string): { seal: SealStatus; basis: string } {
|
|
419
|
+
const s = SEALS[theorem_name]
|
|
420
|
+
if (s === undefined) return { seal: 'none', basis: 'no executable predicate for this theorem' }
|
|
421
|
+
// A predicate that throws has not held. Letting it escape would turn a failed
|
|
422
|
+
// seal into a crashed process, which reads like an infrastructure problem
|
|
423
|
+
// rather than the negative result it is.
|
|
424
|
+
try {
|
|
425
|
+
return { seal: s.decide() ? 'held' : 'failed', basis: s.basis }
|
|
426
|
+
} catch {
|
|
427
|
+
return { seal: 'failed', basis: s.basis }
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function baseCertificate(theorem_name: string, statement: string): ProofCertificate {
|
|
432
|
+
const proof_script = LEAN_PROOFS[theorem_name as keyof typeof LEAN_PROOFS] ?? ''
|
|
433
|
+
const { seal, basis } = runSeal(theorem_name)
|
|
197
434
|
return {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
complexity_bound: props.complexity_bound,
|
|
202
|
-
speedup_factor: props.speedup_factor,
|
|
203
|
-
proof_script: LEAN_PROOFS[props.theorem_name as keyof typeof LEAN_PROOFS] || '',
|
|
435
|
+
theorem_name,
|
|
436
|
+
statement,
|
|
437
|
+
proof_script,
|
|
204
438
|
verified_at: new Date().toISOString(),
|
|
205
|
-
|
|
206
|
-
|
|
439
|
+
lean_status: readLeanStatus(proof_script),
|
|
440
|
+
seal,
|
|
441
|
+
seal_basis: basis,
|
|
442
|
+
hash: computeProofHash(statement, proof_script),
|
|
207
443
|
}
|
|
208
444
|
}
|
|
209
445
|
|
|
210
|
-
export function
|
|
211
|
-
const
|
|
212
|
-
'
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
threshold: 0.01,
|
|
222
|
-
min_distance: 3,
|
|
223
|
-
},
|
|
224
|
-
Surface: {
|
|
225
|
-
theorem_name: 'surface_code_threshold',
|
|
226
|
-
statement: 'Surface code corrects arbitrary errors below 1% threshold',
|
|
227
|
-
threshold: 0.01,
|
|
228
|
-
min_distance: 3,
|
|
229
|
-
},
|
|
446
|
+
export function generateGateCertificate(gate: 'Hadamard' | 'PauliX'): GateCertificate {
|
|
447
|
+
const info = {
|
|
448
|
+
Hadamard: { theorem_name: 'hadamard_unitary', statement: 'IsUnitary hadamard', property: 'unitary' as const },
|
|
449
|
+
PauliX: { theorem_name: 'pauliX_unitary', statement: 'IsUnitary pauliX', property: 'unitary' as const },
|
|
450
|
+
}[gate]
|
|
451
|
+
const base = baseCertificate(info.theorem_name, info.statement)
|
|
452
|
+
return {
|
|
453
|
+
...base,
|
|
454
|
+
gate_name: gate,
|
|
455
|
+
property: info.property,
|
|
456
|
+
proof_lines: base.proof_script.split('\n').filter((l) => l.trim().length > 0).length,
|
|
230
457
|
}
|
|
458
|
+
}
|
|
231
459
|
|
|
232
|
-
|
|
233
|
-
|
|
460
|
+
export function generateAlgorithmCertificate(algo: 'Grover' | 'Shor' | 'QFT'): AlgorithmCertificate {
|
|
461
|
+
const info = {
|
|
462
|
+
Grover: { theorem_name: 'grover_speedup', statement: 'Grover search runs in O(sqrt N) time', complexity_bound: 'O(sqrt N)', speedup_factor: 4 },
|
|
463
|
+
// Unsealed: no predicate exists, so no speedup factor is claimed.
|
|
464
|
+
Shor: { theorem_name: 'shor_period_finding', statement: 'Shor finds period r in O(log^3 N) gates', complexity_bound: 'O(log^3 N)', speedup_factor: 0 },
|
|
465
|
+
QFT: { theorem_name: 'qft_unitary', statement: 'QFT is unitary and computable in O(n^2) gates', complexity_bound: 'O(n^2)', speedup_factor: 1 },
|
|
466
|
+
}[algo]
|
|
234
467
|
return {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
min_distance: props.min_distance,
|
|
240
|
-
proof_script: LEAN_PROOFS[props.theorem_name as keyof typeof LEAN_PROOFS] || '',
|
|
241
|
-
verified_at: new Date().toISOString(),
|
|
242
|
-
lean_version: 'v4.8.0',
|
|
243
|
-
hash: computeProofHash(props.theorem_name),
|
|
468
|
+
...baseCertificate(info.theorem_name, info.statement),
|
|
469
|
+
algorithm: algo,
|
|
470
|
+
complexity_bound: info.complexity_bound,
|
|
471
|
+
speedup_factor: info.speedup_factor,
|
|
244
472
|
}
|
|
245
473
|
}
|
|
246
474
|
|
|
475
|
+
export function generateECCertificate(code: 'Repetition[3,1,1]' | 'Steane[7,1,3]' | 'Surface'): ECCertificate {
|
|
476
|
+
const info = {
|
|
477
|
+
'Repetition[3,1,1]': { theorem_name: 'repetition_detects_error', statement: 'Repetition code detects single-qubit errors', threshold: 5 / 100, min_distance: 3 },
|
|
478
|
+
'Steane[7,1,3]': { theorem_name: 'steane_corrects_error', statement: 'Steane code corrects arbitrary single-qubit errors', threshold: 1 / 100, min_distance: 3 },
|
|
479
|
+
Surface: { theorem_name: 'surface_code_threshold', statement: 'Surface code corrects arbitrary errors below 1% threshold', threshold: 1 / 100, min_distance: 3 },
|
|
480
|
+
}[code]
|
|
481
|
+
return { ...baseCertificate(info.theorem_name, info.statement), code, threshold: info.threshold, min_distance: info.min_distance }
|
|
482
|
+
}
|
|
483
|
+
|
|
247
484
|
// ============================================================================
|
|
248
|
-
//
|
|
485
|
+
// VERIFICATION
|
|
249
486
|
// ============================================================================
|
|
250
487
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
488
|
+
/**
|
|
489
|
+
* A certificate is verified when its seal HELD - a predicate ran and could
|
|
490
|
+
* have said no. Structural well-formedness is not verification; the previous
|
|
491
|
+
* implementation returned true for every certificate this file can build.
|
|
492
|
+
*/
|
|
257
493
|
export function verifyProofCertificate(cert: ProofCertificate): boolean {
|
|
258
|
-
|
|
259
|
-
return (
|
|
260
|
-
cert.theorem_name.length > 0 &&
|
|
261
|
-
cert.statement.length > 0 &&
|
|
262
|
-
cert.verified_at.length > 0 &&
|
|
263
|
-
cert.lean_version.startsWith('v4') &&
|
|
264
|
-
cert.hash.length === 16
|
|
265
|
-
)
|
|
494
|
+
return cert.seal === 'held'
|
|
266
495
|
}
|
|
267
496
|
|
|
268
497
|
export function verifyProofChain(certs: ProofCertificate[]): boolean {
|
|
269
|
-
|
|
270
|
-
return certs.every(verifyProofCertificate)
|
|
498
|
+
return certs.length > 0 && certs.every(verifyProofCertificate)
|
|
271
499
|
}
|
|
272
500
|
|
|
273
501
|
// ============================================================================
|
|
274
|
-
//
|
|
502
|
+
// TRANSCRIPT
|
|
275
503
|
// ============================================================================
|
|
276
504
|
|
|
277
505
|
export interface ProofTranscript {
|
|
278
506
|
readonly title: string
|
|
279
507
|
readonly theorems: readonly string[]
|
|
280
508
|
readonly total_lines: number
|
|
281
|
-
readonly
|
|
282
|
-
readonly
|
|
509
|
+
readonly sealed_count: number
|
|
510
|
+
readonly unsealed: readonly string[]
|
|
511
|
+
readonly lean_sorry: readonly string[]
|
|
512
|
+
readonly confidence: number
|
|
283
513
|
readonly timestamp: string
|
|
284
514
|
readonly certificates: ProofCertificate[]
|
|
285
515
|
}
|
|
286
516
|
|
|
287
517
|
export function generateProofTranscript(certs: ProofCertificate[]): ProofTranscript {
|
|
288
|
-
const
|
|
289
|
-
const verified_count = certs.filter(verifyProofCertificate).length
|
|
290
|
-
|
|
518
|
+
const sealed = certs.filter(verifyProofCertificate)
|
|
291
519
|
return {
|
|
292
|
-
title: 'Quantum
|
|
520
|
+
title: 'Quantum system: computational seals (Lean scripts NOT machine-checked)',
|
|
293
521
|
theorems: certs.map((c) => c.theorem_name),
|
|
294
|
-
total_lines,
|
|
295
|
-
|
|
296
|
-
|
|
522
|
+
total_lines: certs.reduce((sum, c) => sum + c.proof_script.split('\n').length, 0),
|
|
523
|
+
sealed_count: sealed.length,
|
|
524
|
+
unsealed: certs.filter((c) => c.seal !== 'held').map((c) => c.theorem_name),
|
|
525
|
+
lean_sorry: certs.filter((c) => c.lean_status === 'sorry').map((c) => c.theorem_name),
|
|
526
|
+
confidence: certs.length === 0 ? 0 : sealed.length / certs.length,
|
|
297
527
|
timestamp: new Date().toISOString(),
|
|
298
528
|
certificates: certs,
|
|
299
529
|
}
|
|
300
530
|
}
|
|
301
531
|
|
|
302
532
|
// ============================================================================
|
|
303
|
-
// SYSTEM
|
|
533
|
+
// SYSTEM REPORT
|
|
304
534
|
// ============================================================================
|
|
305
535
|
|
|
306
536
|
export interface VerificationReport {
|
|
307
|
-
readonly
|
|
308
|
-
readonly
|
|
309
|
-
readonly
|
|
310
|
-
readonly
|
|
537
|
+
readonly gates_sealed: readonly string[]
|
|
538
|
+
readonly algorithms_sealed: readonly string[]
|
|
539
|
+
readonly error_correction_sealed: readonly string[]
|
|
540
|
+
readonly unsealed: readonly string[]
|
|
541
|
+
readonly security_assumptions_stated: readonly string[]
|
|
311
542
|
readonly total_theorems: number
|
|
312
543
|
readonly total_lines_of_proof: number
|
|
313
|
-
readonly
|
|
544
|
+
readonly sealed_fraction: number
|
|
545
|
+
readonly lean_machine_checked: false
|
|
314
546
|
}
|
|
315
547
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
548
|
+
function allCertificates(): ProofCertificate[] {
|
|
549
|
+
return [
|
|
550
|
+
...(['Hadamard', 'PauliX'] as const).map(generateGateCertificate),
|
|
551
|
+
...(['Grover', 'Shor', 'QFT'] as const).map(generateAlgorithmCertificate),
|
|
552
|
+
...(['Repetition[3,1,1]', 'Steane[7,1,3]', 'Surface'] as const).map(generateECCertificate),
|
|
553
|
+
]
|
|
554
|
+
}
|
|
322
555
|
|
|
323
|
-
|
|
324
|
-
const
|
|
556
|
+
export function verifyQuantumSystem(): VerificationReport {
|
|
557
|
+
const gates = (['Hadamard', 'PauliX'] as const).map(generateGateCertificate)
|
|
558
|
+
const algos = (['Grover', 'Shor', 'QFT'] as const).map(generateAlgorithmCertificate)
|
|
559
|
+
const ecs = (['Repetition[3,1,1]', 'Steane[7,1,3]', 'Surface'] as const).map(generateECCertificate)
|
|
560
|
+
const all = [...gates, ...algos, ...ecs]
|
|
561
|
+
const held = (x: ProofCertificate): boolean => x.seal === 'held'
|
|
325
562
|
|
|
326
563
|
return {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
564
|
+
gates_sealed: gates.filter(held).map((x) => x.gate_name),
|
|
565
|
+
algorithms_sealed: algos.filter(held).map((x) => x.algorithm),
|
|
566
|
+
error_correction_sealed: ecs.filter(held).map((x) => x.code),
|
|
567
|
+
unsealed: all.filter((x) => !held(x)).map((x) => x.theorem_name),
|
|
568
|
+
// "stated", not "formalized": lwe_hardness is an axiom, and Kyber's level
|
|
569
|
+
// is a NIST categorisation (ML-KEM-768 is category 3), not a result proved
|
|
570
|
+
// anywhere in this repository.
|
|
571
|
+
security_assumptions_stated: [
|
|
572
|
+
'LWE_hardness (axiom, assumed)',
|
|
573
|
+
'ML-KEM-768 = NIST category 3',
|
|
574
|
+
'SPHINCS_EUF_CMA (not implemented)',
|
|
575
|
+
],
|
|
576
|
+
total_theorems: all.length,
|
|
577
|
+
total_lines_of_proof: all.reduce((s, x) => s + x.proof_script.split('\n').length, 0),
|
|
578
|
+
sealed_fraction: all.filter(held).length / all.length,
|
|
579
|
+
lean_machine_checked: false,
|
|
334
580
|
}
|
|
335
581
|
}
|
|
336
582
|
|
|
337
583
|
// ============================================================================
|
|
338
|
-
//
|
|
584
|
+
// EXPORT FOR PUBLICATION
|
|
339
585
|
// ============================================================================
|
|
340
586
|
|
|
341
587
|
export function exportProofsForZenodo(): object {
|
|
342
588
|
const report = verifyQuantumSystem()
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
const algo_proofs = ['Grover', 'Shor', 'QFT'].map((a) => generateAlgorithmCertificate(a as any))
|
|
346
|
-
const ec_proofs = ['Repetition[3,1,1]', 'Steane[7,1,3]', 'Surface'].map((c) =>
|
|
347
|
-
generateECCertificate(c as any),
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
const transcript = generateProofTranscript([...gate_proofs, ...algo_proofs, ...ec_proofs])
|
|
589
|
+
const transcript = generateProofTranscript(allCertificates())
|
|
590
|
+
const sealed = report.total_theorems - report.unsealed.length
|
|
351
591
|
|
|
352
592
|
return {
|
|
353
593
|
system: 'Quantum Computing System',
|
|
354
|
-
verification_framework:
|
|
355
|
-
|
|
594
|
+
verification_framework:
|
|
595
|
+
'Computational seals in TypeScript. Lean scripts are included as documentation and are NOT machine-checked.',
|
|
596
|
+
seal_report: report,
|
|
356
597
|
proof_transcript: transcript,
|
|
357
|
-
|
|
358
|
-
ready_for_publication: true,
|
|
598
|
+
// This previously read 'Production Grade (Formally Verified)' with
|
|
599
|
+
// ready_for_publication: true, regardless of what had been checked.
|
|
600
|
+
confidence_level: sealed + '/' + report.total_theorems + ' theorems carry a passing computational seal; 0/' + report.total_theorems + ' are machine-checked in Lean',
|
|
601
|
+
ready_for_publication: report.unsealed.length === 0 && report.lean_machine_checked,
|
|
602
|
+
caveats: [
|
|
603
|
+
'Seals decide concrete instances, not universally quantified statements.',
|
|
604
|
+
'No Lean toolchain runs in this repository; lean_status is read from the script text.',
|
|
605
|
+
report.unsealed.length + ' of ' + report.total_theorems + ' theorems have no executable predicate.',
|
|
606
|
+
],
|
|
359
607
|
timestamp: new Date().toISOString(),
|
|
360
608
|
}
|
|
361
609
|
}
|