@trynullsec/s1-zk 1.0.0 → 1.0.2

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.
Files changed (35) hide show
  1. package/LIMITATIONS.md +2 -0
  2. package/README.md +14 -1
  3. package/ROADMAP.md +1 -0
  4. package/RULES.md +6 -0
  5. package/dist/analysis/circuit-intent.d.ts +9 -0
  6. package/dist/analysis/circuit-intent.js +58 -0
  7. package/dist/analysis/circuit-intent.js.map +1 -0
  8. package/dist/analysis/deep-analysis.d.ts +2 -0
  9. package/dist/analysis/deep-analysis.js +18 -0
  10. package/dist/analysis/deep-analysis.js.map +1 -0
  11. package/dist/analysis/exploit-hypothesis.d.ts +2 -0
  12. package/dist/analysis/exploit-hypothesis.js +65 -0
  13. package/dist/analysis/exploit-hypothesis.js.map +1 -0
  14. package/dist/analysis/proof-obligation-extractor.d.ts +2 -0
  15. package/dist/analysis/proof-obligation-extractor.js +119 -0
  16. package/dist/analysis/proof-obligation-extractor.js.map +1 -0
  17. package/dist/analysis/relation-checker.d.ts +9 -0
  18. package/dist/analysis/relation-checker.js +64 -0
  19. package/dist/analysis/relation-checker.js.map +1 -0
  20. package/dist/analysis/taint-flow.d.ts +2 -0
  21. package/dist/analysis/taint-flow.js +60 -0
  22. package/dist/analysis/taint-flow.js.map +1 -0
  23. package/dist/cli.js +3 -1
  24. package/dist/cli.js.map +1 -1
  25. package/dist/core/audit-engine.d.ts +1 -1
  26. package/dist/core/audit-engine.js +6 -3
  27. package/dist/core/audit-engine.js.map +1 -1
  28. package/dist/report/markdown.js +33 -0
  29. package/dist/report/markdown.js.map +1 -1
  30. package/dist/report/terminal.js +25 -0
  31. package/dist/report/terminal.js.map +1 -1
  32. package/dist/scanner.js +1 -1
  33. package/dist/scanner.js.map +1 -1
  34. package/dist/types.d.ts +58 -0
  35. package/package.json +1 -1
package/LIMITATIONS.md CHANGED
@@ -7,6 +7,8 @@ Nullsec S1-ZK v1 is deterministic static analysis for ZK circuit auditing. It is
7
7
  - The Halo2 frontend is best-effort Rust source scanning. It is not a full Rust AST, MIR, or Halo2 synthesis analyzer.
8
8
  - The Halo2 constraint graph is approximate. It links obvious gates, regions, advice assignments, selector enables, equality/copy edges, lookups, and instance bindings, but it does not execute synthesis code.
9
9
  - It is not full formal verification and does not prove circuit soundness.
10
+ - The `--deep` proof obligation layer infers likely obligations from naming, graph relationships, and source structure. These inferred obligations may be wrong, incomplete, or project-specific.
11
+ - Exploit hypotheses are deterministic audit aids, not generated counterexamples and not proof of exploitability.
10
12
  - It may miss semantic bugs that require protocol context, cross-circuit reasoning, or full compilation.
11
13
  - It does not generate witnesses or counterexamples yet.
12
14
  - It does not compile Circom circuits, inspect generated R1CS, or run Halo2 circuit synthesis yet.
package/README.md CHANGED
@@ -44,6 +44,18 @@ The Halo2 frontend builds a best-effort constraint graph from Rust source. It li
44
44
 
45
45
  This graph lets Nullsec S1-ZK distinguish advice values that are connected through gates, equality edges, lookups, or public instance exposure from values that are merely assigned in a region. It improves high-signal findings for Orchard-style EC gadgets and other Halo2 circuits, but it is still static source analysis, not formal verification or complete Halo2 synthesis.
46
46
 
47
+ ## Deep Relationship Analysis
48
+
49
+ Use `--deep` to enable proof obligation extraction, relation checking, taint/dataflow analysis, and deterministic exploit hypotheses.
50
+
51
+ ```bash
52
+ nullsec-zk scan ./circuits --deep
53
+ ```
54
+
55
+ Deep analysis infers likely obligations such as commitment binding, nullifier binding, Merkle path binding, selector booleanity, EC multiplication consistency, public input binding, and range constraints. It then checks whether parsed constraints, Halo2 graph edges, equality/copy edges, lookups, and public instance bindings appear to support those obligations.
56
+
57
+ This is relationship-aware static analysis. It helps auditors find gaps faster, but inferred obligations may be wrong or incomplete and are not formal proof obligations in the mathematical verification sense.
58
+
47
59
  ## Installation
48
60
 
49
61
  ```bash
@@ -57,6 +69,7 @@ npm link
57
69
  ```bash
58
70
  nullsec-zk scan ./examples
59
71
  nullsec-zk scan ./examples/halo2
72
+ nullsec-zk scan ./benchmarks/historical/orchard-inspired --deep
60
73
  nullsec-zk scan ./examples --format json
61
74
  nullsec-zk scan ./examples --format sarif
62
75
  nullsec-zk scan ./examples --report markdown
@@ -138,7 +151,7 @@ Example:
138
151
 
139
152
  ## Limitations
140
153
 
141
- Static analysis is approximate. The Circom and Halo2 frontends are best-effort source analyzers, do not compile circuits, do not generate witnesses, and do not perform formal verification. See `LIMITATIONS.md`.
154
+ Static analysis is approximate. The Circom and Halo2 frontends are best-effort source analyzers, and `--deep` infers likely proof obligations from naming and graph relationships. Nullsec S1-ZK does not compile circuits, generate witnesses, or perform formal verification. See `LIMITATIONS.md`.
142
155
 
143
156
  ## Roadmap
144
157
 
package/ROADMAP.md CHANGED
@@ -10,6 +10,7 @@ Nullsec S1-ZK is designed as a modular security product foundation.
10
10
  - Plonky2 frontend.
11
11
  - R1CS extraction and analysis.
12
12
  - Constraint graph visualization.
13
+ - Proof obligation visualization and reviewer workflow.
13
14
  - Witness counterexample generation.
14
15
  - Spec-to-circuit comparison.
15
16
  - LLM-assisted exploit reasoning.
package/RULES.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  Each rule reports a deterministic static-analysis finding. Severity can be overridden in `.nullsec-zk.json`.
4
4
 
5
+ ## Deep Analysis Layer
6
+
7
+ `nullsec-zk scan --deep` adds relationship-aware analysis on top of rule findings. It infers likely proof obligations, checks them against parsed Circom constraints and the Halo2 constraint graph, tracks taint/dataflow paths, and generates deterministic exploit hypotheses for high-impact findings.
8
+
9
+ This layer is not a formal proof system. Obligations are inferred from circuit structure, names, public bindings, and graph relationships, so they may be incomplete or incorrect. The goal is to help auditors find likely semantic gaps faster.
10
+
5
11
  ## NS-ZK-001 Dangerous Hint Assignment
6
12
 
7
13
  Severity: CRITICAL when unconstrained, MEDIUM when later constrained.
@@ -0,0 +1,9 @@
1
+ import type { AuditContext, SourceLocation } from "../types.js";
2
+ export interface CircuitIntentHint {
3
+ kind: "commitment" | "nullifier" | "merkle" | "selector" | "range" | "ec" | "public";
4
+ subject: string;
5
+ related: string[];
6
+ confidence: "HIGH" | "MEDIUM" | "LOW";
7
+ location: SourceLocation;
8
+ }
9
+ export declare function inferCircuitIntent(context: AuditContext): CircuitIntentHint[];
@@ -0,0 +1,58 @@
1
+ import { isBooleanLikeName } from "../frontends/circom/circom-utils.js";
2
+ import { isEcLikeName } from "../frontends/halo2/halo2-patterns.js";
3
+ function locationOf(file, line = 1, snippet = "") {
4
+ return { file, line, column: 1, snippet };
5
+ }
6
+ export function inferCircuitIntent(context) {
7
+ const hints = [];
8
+ for (const signal of context.ir.signals) {
9
+ const lower = signal.baseName.toLowerCase();
10
+ const refs = context.graph.signalReferences(signal.name);
11
+ if (/commitment|commit/.test(lower)) {
12
+ hints.push({ kind: "commitment", subject: signal.name, related: refs.flatMap((ref) => ref.snippet?.match(/[A-Za-z_][A-Za-z0-9_]*/g) ?? []), confidence: "MEDIUM", location: signal });
13
+ }
14
+ if (/nullifier/.test(lower)) {
15
+ hints.push({ kind: "nullifier", subject: signal.name, related: refs.flatMap((ref) => ref.snippet?.match(/[A-Za-z_][A-Za-z0-9_]*/g) ?? []), confidence: "MEDIUM", location: signal });
16
+ }
17
+ if (/root|path|leaf/.test(lower)) {
18
+ hints.push({ kind: "merkle", subject: signal.name, related: refs.flatMap((ref) => ref.snippet?.match(/[A-Za-z_][A-Za-z0-9_]*/g) ?? []), confidence: "MEDIUM", location: signal });
19
+ }
20
+ if (isBooleanLikeName(signal.baseName)) {
21
+ hints.push({ kind: "selector", subject: signal.name, related: refs.map((ref) => ref.snippet ?? "").filter(Boolean), confidence: "HIGH", location: signal });
22
+ }
23
+ if (/amount|balance|fee|nonce|index|timestamp|quantity|count|size|limb/i.test(signal.baseName)) {
24
+ hints.push({ kind: "range", subject: signal.name, related: refs.map((ref) => ref.snippet ?? "").filter(Boolean), confidence: "HIGH", location: signal });
25
+ }
26
+ if (signal.kind === "input") {
27
+ hints.push({ kind: "public", subject: signal.name, related: refs.map((ref) => ref.snippet ?? "").filter(Boolean), confidence: "MEDIUM", location: signal });
28
+ }
29
+ }
30
+ for (const assignment of context.halo2?.assignments ?? []) {
31
+ const text = `${assignment.label ?? ""} ${assignment.columnName ?? ""} ${assignment.assignedVariable ?? ""} ${assignment.expression}`;
32
+ if (isEcLikeName(text)) {
33
+ hints.push({
34
+ kind: "ec",
35
+ subject: assignment.label ?? assignment.columnName ?? "ec assignment",
36
+ related: assignment.referencedSymbols,
37
+ confidence: "MEDIUM",
38
+ location: assignment
39
+ });
40
+ }
41
+ }
42
+ for (const query of context.halo2?.queries.filter((candidate) => candidate.queryType === "instance") ?? []) {
43
+ hints.push({
44
+ kind: "public",
45
+ subject: query.columnName,
46
+ related: [query.snippet ?? ""],
47
+ confidence: "MEDIUM",
48
+ location: query
49
+ });
50
+ }
51
+ for (const file of context.halo2?.files ?? []) {
52
+ if (/ec|ecc|curve|point|scalar|orchard/i.test(file.rawSource)) {
53
+ hints.push({ kind: "ec", subject: file.filePath.split("/").pop() ?? file.filePath, related: ["base", "scalar", "point", "output"], confidence: "LOW", location: locationOf(file.filePath, 1, "EC-related Halo2 source") });
54
+ }
55
+ }
56
+ return hints;
57
+ }
58
+ //# sourceMappingURL=circuit-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-intent.js","sourceRoot":"","sources":["../../src/analysis/circuit-intent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { AuditContext, DeepAnalysisResult, Issue } from "../types.js";
2
+ export declare function runDeepAnalysis(context: AuditContext, issues: Issue[]): DeepAnalysisResult;
@@ -0,0 +1,18 @@
1
+ import { generateExploitHypotheses } from "./exploit-hypothesis.js";
2
+ import { extractProofObligations } from "./proof-obligation-extractor.js";
3
+ import { checkProofObligations, summarizeRelationChecks } from "./relation-checker.js";
4
+ import { analyzeTaintFlow } from "./taint-flow.js";
5
+ export function runDeepAnalysis(context, issues) {
6
+ const taintFlows = analyzeTaintFlow(context);
7
+ const proofObligations = extractProofObligations(context);
8
+ const relationChecks = checkProofObligations(context, proofObligations, taintFlows);
9
+ return {
10
+ enabled: true,
11
+ proofObligations,
12
+ relationChecks,
13
+ proofObligationSummary: summarizeRelationChecks(relationChecks),
14
+ taintFlows,
15
+ exploitHypotheses: generateExploitHypotheses(issues, relationChecks)
16
+ };
17
+ }
18
+ //# sourceMappingURL=deep-analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-analysis.js","sourceRoot":"","sources":["../../src/analysis/deep-analysis.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,UAAU,eAAe,CAAC,OAAqB,EAAE,MAAe;IACpE,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC;IACpF,OAAO;QACL,OAAO,EAAE,IAAI;QACb,gBAAgB;QAChB,cAAc;QACd,sBAAsB,EAAE,uBAAuB,CAAC,cAAc,CAAC;QAC/D,UAAU;QACV,iBAAiB,EAAE,yBAAyB,CAAC,MAAM,EAAE,cAAc,CAAC;KACrE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ExploitHypothesis, Issue, RelationCheckResult } from "../types.js";
2
+ export declare function generateExploitHypotheses(issues: Issue[], relationChecks: RelationCheckResult[]): ExploitHypothesis[];
@@ -0,0 +1,65 @@
1
+ function matchObligation(issue, checks) {
2
+ const issueText = `${issue.signalName ?? ""} ${issue.explanation} ${issue.snippet ?? ""}`.toLowerCase();
3
+ return checks.find((check) => check.status === "missing" || check.status === "partially_satisfied") ??
4
+ checks.find((check) => issueText.includes(check.obligationId.toLowerCase().split("-").at(-1) ?? ""));
5
+ }
6
+ function issueText(issue) {
7
+ return `${issue.ruleId} ${issue.title} ${issue.signalName ?? ""} ${issue.explanation} ${issue.impact} ${issue.suggestedFix} ${issue.snippet ?? ""} ${issue.tags.join(" ")} ${JSON.stringify(issue.metadata ?? {})}`;
8
+ }
9
+ function isEcIssue(issue) {
10
+ return issue.ruleId.startsWith("NS-H2") && /ec|ecc|curve|point|scalar|base|accumulator|coordinate|output point|output|fixed_base|variable_base/i.test(issueText(issue));
11
+ }
12
+ function isOutputBindingIssue(issue) {
13
+ return /commitment|nullifier|root|unconstrained output|output value/i.test(issueText(issue));
14
+ }
15
+ function isRangeIssue(issue) {
16
+ return issue.ruleId === "NS-ZK-006" || /range|bounded integer|overflow|alias/i.test(issueText(issue));
17
+ }
18
+ function isSelectorIssue(issue) {
19
+ return issue.ruleId === "NS-ZK-005" || issue.ruleId === "NS-ZK-012" || issue.ruleId === "NS-H2-003" || /selector|booleanity|boolean domain|pathindex|flag/i.test(issueText(issue));
20
+ }
21
+ function brokenAssumptionForIssue(issue) {
22
+ if (isEcIssue(issue))
23
+ return "EC coordinates and intermediates are fully bound to the claimed group operation.";
24
+ if (isOutputBindingIssue(issue))
25
+ return "Output value is fully bound to the private witness relation the protocol assumes.";
26
+ if (isRangeIssue(issue))
27
+ return "Arithmetic value has the required bounded integer constraints.";
28
+ if (isSelectorIssue(issue))
29
+ return "Selector-like values are constrained to the expected boolean domain.";
30
+ return "The circuit constrains the semantic relation that the protocol assumes.";
31
+ }
32
+ export function generateExploitHypotheses(issues, relationChecks) {
33
+ return issues
34
+ .filter((issue) => issue.severity === "CRITICAL" || issue.severity === "HIGH")
35
+ .map((issue) => {
36
+ const related = matchObligation(issue, relationChecks);
37
+ const isEc = isEcIssue(issue);
38
+ const isPublic = /public|instance/i.test(`${issue.title} ${issue.explanation}`);
39
+ const isCommitment = isOutputBindingIssue(issue);
40
+ return {
41
+ issueId: issue.id,
42
+ relatedObligationId: related?.obligationId,
43
+ hypothesis: isEc
44
+ ? `A malicious prover may choose ${issue.signalName ?? "an EC-related advice value"} independently of the claimed scalar multiplication relation. If the verifier accepts this value as part of the EC output, the circuit may verify an invalid group operation.`
45
+ : isPublic
46
+ ? "A malicious prover may satisfy local witness assignments while failing to bind the claimed public instance value to the private witness relation."
47
+ : isCommitment
48
+ ? "A malicious prover may choose a commitment, nullifier, or root value that is not fully bound to the private witness data the protocol assumes it represents."
49
+ : `A malicious prover may exploit ${issue.title.toLowerCase()} by choosing witness values that satisfy parsed constraints while violating the intended statement.`,
50
+ attackerControl: issue.signalName
51
+ ? `The prover controls witness/advice data influencing \`${issue.signalName}\`.`
52
+ : "The prover controls witness/advice assignments involved in this finding.",
53
+ brokenAssumption: brokenAssumptionForIssue(issue),
54
+ possibleImpact: issue.impact,
55
+ validationSteps: [
56
+ "Inspect the cited assignment and all constraints that should bind it.",
57
+ "Check whether the value appears in a gate expression, equality/copy edge, lookup, or public binding.",
58
+ "Attempt to construct two witnesses that differ in the suspect value while preserving parsed constraints."
59
+ ],
60
+ patchDirection: issue.suggestedFix,
61
+ confidence: isEc ? "HIGH" : issue.confidence
62
+ };
63
+ });
64
+ }
65
+ //# sourceMappingURL=exploit-hypothesis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exploit-hypothesis.js","sourceRoot":"","sources":["../../src/analysis/exploit-hypothesis.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { AuditContext, ProofObligation } from "../types.js";
2
+ export declare function extractProofObligations(context: AuditContext): ProofObligation[];
@@ -0,0 +1,119 @@
1
+ import { inferCircuitIntent } from "./circuit-intent.js";
2
+ function makeId(type, subject, index) {
3
+ return `PO-${type.toUpperCase().replace(/_/g, "-")}-${subject.replace(/[^A-Za-z0-9]+/g, "-")}-${index}`;
4
+ }
5
+ function relatedInputsForCircom(context, subject) {
6
+ const refs = context.graph.signalReferences(subject);
7
+ const names = new Set();
8
+ for (const ref of refs) {
9
+ for (const token of ref.snippet?.match(/\b[A-Za-z_][A-Za-z0-9_]*\b/g) ?? []) {
10
+ if (!["signal", "input", "output", "component", "template"].includes(token) && token !== subject)
11
+ names.add(token);
12
+ }
13
+ }
14
+ for (const input of context.ir.signals.filter((signal) => signal.kind === "input")) {
15
+ if (/secret|amount|asset|nullifier|note|leaf|path|base|scalar|balance/i.test(input.baseName))
16
+ names.add(input.name);
17
+ }
18
+ return [...names].slice(0, 8);
19
+ }
20
+ function locationFallback(subject) {
21
+ return { file: "unknown", line: 1, column: 1, snippet: subject };
22
+ }
23
+ export function extractProofObligations(context) {
24
+ const obligations = [];
25
+ const hints = inferCircuitIntent(context);
26
+ hints.forEach((hint, index) => {
27
+ if (hint.kind === "commitment") {
28
+ obligations.push({
29
+ id: makeId("commitment_binding", hint.subject, index),
30
+ type: "commitment_binding",
31
+ subject: hint.subject,
32
+ requiredInputs: relatedInputsForCircom(context, hint.subject).filter((name) => /secret|amount|asset|nullifier|note/i.test(name)),
33
+ expectedRelation: "Commitment output should bind the secret, amount, asset, nullifier, or note data it claims to commit to.",
34
+ relatedSignals: hint.related,
35
+ confidence: hint.confidence,
36
+ sourceLocation: hint.location
37
+ });
38
+ }
39
+ if (hint.kind === "nullifier") {
40
+ obligations.push({
41
+ id: makeId("nullifier_binding", hint.subject, index),
42
+ type: "nullifier_binding",
43
+ subject: hint.subject,
44
+ requiredInputs: relatedInputsForCircom(context, hint.subject).filter((name) => /secret|note|nullifier/i.test(name)),
45
+ expectedRelation: "Nullifier should bind secret or note data so it cannot be chosen independently.",
46
+ relatedSignals: hint.related,
47
+ confidence: hint.confidence,
48
+ sourceLocation: hint.location
49
+ });
50
+ }
51
+ if (hint.kind === "merkle") {
52
+ obligations.push({
53
+ id: makeId("merkle_root_binding", hint.subject, index),
54
+ type: "merkle_root_binding",
55
+ subject: hint.subject,
56
+ requiredInputs: relatedInputsForCircom(context, hint.subject).filter((name) => /path|leaf|root|index/i.test(name)),
57
+ expectedRelation: "Merkle root should bind path elements, path selector/index values, and the leaf.",
58
+ relatedSignals: hint.related,
59
+ confidence: hint.confidence,
60
+ sourceLocation: hint.location
61
+ });
62
+ }
63
+ if (hint.kind === "selector") {
64
+ obligations.push({
65
+ id: makeId("selector_booleanity", hint.subject, index),
66
+ type: "selector_booleanity",
67
+ subject: hint.subject,
68
+ requiredInputs: [hint.subject],
69
+ expectedRelation: "Selector or path index should be constrained to boolean values.",
70
+ relatedSignals: hint.related,
71
+ confidence: "HIGH",
72
+ sourceLocation: hint.location
73
+ });
74
+ }
75
+ if (hint.kind === "range") {
76
+ obligations.push({
77
+ id: makeId("range_constraint", hint.subject, index),
78
+ type: "range_constraint",
79
+ subject: hint.subject,
80
+ requiredInputs: [hint.subject],
81
+ expectedRelation: "Arithmetic value should be range constrained to its intended integer domain.",
82
+ relatedSignals: hint.related,
83
+ confidence: hint.confidence,
84
+ sourceLocation: hint.location
85
+ });
86
+ }
87
+ if (hint.kind === "public") {
88
+ obligations.push({
89
+ id: makeId("public_input_binding", hint.subject, index),
90
+ type: "public_input_binding",
91
+ subject: hint.subject,
92
+ requiredInputs: [hint.subject],
93
+ expectedRelation: "Public input or instance value should be connected to private witness data or a constrained relation.",
94
+ relatedSignals: hint.related,
95
+ confidence: hint.confidence,
96
+ sourceLocation: hint.location
97
+ });
98
+ }
99
+ });
100
+ const halo2 = context.halo2;
101
+ if (halo2 && halo2.assignments.some((assignment) => /ec|curve|point|scalar|base|accumulator|output/i.test(`${assignment.label ?? ""} ${assignment.columnName ?? ""}`))) {
102
+ const first = halo2.assignments.find((assignment) => /ec|curve|point|scalar|base|accumulator|output/i.test(`${assignment.label ?? ""} ${assignment.columnName ?? ""}`));
103
+ const related = halo2.assignments
104
+ .filter((assignment) => assignment.file === first?.file && /base|scalar|point|accumulator|output|x|y/i.test(`${assignment.label ?? ""} ${assignment.columnName ?? ""}`))
105
+ .map((assignment) => assignment.label ?? assignment.columnName ?? "unknown");
106
+ obligations.push({
107
+ id: makeId("ec_multiplication", first?.file.split("/").pop() ?? "halo2-ec", obligations.length),
108
+ type: "ec_multiplication",
109
+ subject: first?.file.split("/").pop() ?? "Halo2 EC operation",
110
+ requiredInputs: related,
111
+ expectedRelation: "Output point should bind base point and scalar through complete elliptic-curve multiplication constraints.",
112
+ relatedSignals: related,
113
+ confidence: "MEDIUM",
114
+ sourceLocation: first ?? locationFallback("Halo2 EC operation")
115
+ });
116
+ }
117
+ return obligations;
118
+ }
119
+ //# sourceMappingURL=proof-obligation-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proof-obligation-extractor.js","sourceRoot":"","sources":["../../src/analysis/proof-obligation-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { AuditContext, ProofObligation, RelationCheckResult, TaintFlowPath } from "../types.js";
2
+ export declare function checkProofObligations(context: AuditContext, obligations: ProofObligation[], taintFlows?: TaintFlowPath[]): RelationCheckResult[];
3
+ export declare function summarizeRelationChecks(checks: RelationCheckResult[]): {
4
+ total: number;
5
+ satisfied: number;
6
+ partially_satisfied: number;
7
+ missing: number;
8
+ unknown: number;
9
+ };
@@ -0,0 +1,64 @@
1
+ import { Halo2ConstraintGraph } from "../frontends/halo2/halo2-constraint-graph.js";
2
+ function statusCounts(connections) {
3
+ if (connections.length === 0)
4
+ return "unknown";
5
+ if (connections.every(Boolean))
6
+ return "satisfied";
7
+ if (connections.some(Boolean))
8
+ return "partially_satisfied";
9
+ return "missing";
10
+ }
11
+ function result(obligation, status, evidence, missing, explanation) {
12
+ return { obligationId: obligation.id, status, evidence, missing, explanation };
13
+ }
14
+ export function checkProofObligations(context, obligations, taintFlows = []) {
15
+ const halo2Graph = context.halo2 ? new Halo2ConstraintGraph(context.halo2) : undefined;
16
+ return obligations.map((obligation) => {
17
+ if (obligation.type === "selector_booleanity") {
18
+ const ok = context.graph.hasBooleanityConstraint(obligation.subject);
19
+ return result(obligation, ok ? "satisfied" : "missing", ok ? [`Booleanity constraint found for ${obligation.subject}`] : [], ok ? [] : [obligation.subject], ok ? "Selector-like value has a recognized booleanity constraint." : "Selector-like value does not have a recognized booleanity constraint.");
20
+ }
21
+ if (obligation.type === "range_constraint") {
22
+ const ok = context.graph.hasRangeCheck(obligation.subject);
23
+ return result(obligation, ok ? "satisfied" : "missing", ok ? [`Range-check pattern found for ${obligation.subject}`] : [], ok ? [] : [obligation.subject], ok ? "Arithmetic value has a recognized range-check pattern." : "Arithmetic value does not have a recognized range-check pattern.");
24
+ }
25
+ if (obligation.type === "public_input_binding") {
26
+ const circomBound = context.graph.appearsInAnyConstraint(obligation.subject);
27
+ const halo2Bound = halo2Graph?.instanceQueryIsBound(obligation.subject, obligation.sourceLocation.file) ?? false;
28
+ const ok = circomBound || halo2Bound;
29
+ return result(obligation, ok ? "satisfied" : "missing", ok ? [`Public value ${obligation.subject} appears connected to constraints or instance binding`] : [], ok ? [] : [obligation.subject], ok ? "Public value is connected to a parsed relation." : "Public value is not connected to a parsed relation.");
30
+ }
31
+ if (obligation.type === "commitment_binding" || obligation.type === "nullifier_binding" || obligation.type === "merkle_root_binding") {
32
+ const subjectConnected = context.graph.appearsInAnyConstraint(obligation.subject);
33
+ const inputChecks = obligation.requiredInputs.map((input) => context.graph.appearsInAnyConstraint(input));
34
+ const status = subjectConnected ? statusCounts(inputChecks.length > 0 ? inputChecks : [subjectConnected]) : "missing";
35
+ return result(obligation, status, subjectConnected ? [`${obligation.subject} appears in parsed constraints`] : [], obligation.requiredInputs.filter((input, index) => !inputChecks[index]), status === "satisfied"
36
+ ? "The inferred binding obligation is supported by parsed constraints."
37
+ : status === "partially_satisfied"
38
+ ? "Some inferred inputs are connected, but the full binding relation was not established."
39
+ : "The inferred binding relation is missing or not visible to static analysis.");
40
+ }
41
+ if (obligation.type === "ec_multiplication") {
42
+ const relevantFlows = taintFlows.filter((flow) => flow.risk === "ec_unconnected_coordinate" && flow.sourceLocation?.file === obligation.sourceLocation.file);
43
+ const required = obligation.requiredInputs.length > 0 ? obligation.requiredInputs : relevantFlows.map((flow) => flow.sink);
44
+ const connected = required.map((name) => {
45
+ const flow = relevantFlows.find((candidate) => candidate.sink === name || candidate.sink.includes(name) || name.includes(candidate.sink));
46
+ return flow ? flow.constrained : true;
47
+ });
48
+ const status = statusCounts(connected);
49
+ return result(obligation, status, relevantFlows.filter((flow) => flow.constrained).map((flow) => `${flow.sink}: ${flow.support.join(", ")}`), relevantFlows.filter((flow) => !flow.constrained).map((flow) => flow.sink), status === "satisfied"
50
+ ? "EC multiplication-related assignments appear connected to parsed constraints."
51
+ : status === "partially_satisfied"
52
+ ? "The EC multiplication relation is partially supported, but some coordinates or inputs are unconnected."
53
+ : "The EC multiplication relation is missing critical connections between assigned values and constraints.");
54
+ }
55
+ return result(obligation, "unknown", [], obligation.requiredInputs, "No relation checker is available for this obligation type.");
56
+ });
57
+ }
58
+ export function summarizeRelationChecks(checks) {
59
+ return checks.reduce((summary, check) => {
60
+ summary[check.status] += 1;
61
+ return summary;
62
+ }, { total: checks.length, satisfied: 0, partially_satisfied: 0, missing: 0, unknown: 0 });
63
+ }
64
+ //# sourceMappingURL=relation-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-checker.js","sourceRoot":"","sources":["../../src/analysis/relation-checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { AuditContext, TaintFlowPath } from "../types.js";
2
+ export declare function analyzeTaintFlow(context: AuditContext): TaintFlowPath[];
@@ -0,0 +1,60 @@
1
+ import { Halo2ConstraintGraph } from "../frontends/halo2/halo2-constraint-graph.js";
2
+ function idFor(prefix, index) {
3
+ return `${prefix}-${String(index + 1).padStart(4, "0")}`;
4
+ }
5
+ export function analyzeTaintFlow(context) {
6
+ const flows = [];
7
+ for (const assignment of context.ir.assignments) {
8
+ const sinkLike = /commit|nullifier|root|out|output/i.test(assignment.lhs);
9
+ if (!sinkLike)
10
+ continue;
11
+ const constrained = context.graph.appearsInAnyConstraint(assignment.lhs);
12
+ flows.push({
13
+ id: idFor("TF-CIRCOM", flows.length),
14
+ source: assignment.rhs,
15
+ sink: assignment.lhs,
16
+ path: [assignment.rhs, assignment.lhs],
17
+ constrained,
18
+ support: constrained ? context.graph.constraintsForSignal(assignment.lhs).map((constraint) => constraint.expression) : [],
19
+ risk: "untrusted_to_output",
20
+ confidence: constrained ? "MEDIUM" : "HIGH",
21
+ sourceLocation: assignment
22
+ });
23
+ }
24
+ if (context.halo2) {
25
+ const graph = new Halo2ConstraintGraph(context.halo2);
26
+ for (const assignment of context.halo2.assignments) {
27
+ const label = assignment.label ?? assignment.columnName ?? assignment.target ?? "unknown";
28
+ const sinkLike = /commit|nullifier|root|output|out|point|base|scalar|accumulator|x|y/i.test(label);
29
+ if (!sinkLike)
30
+ continue;
31
+ const support = graph.assignmentConnections(assignment);
32
+ flows.push({
33
+ id: idFor("TF-HALO2", flows.length),
34
+ source: assignment.assignedVariable ?? assignment.expression,
35
+ sink: label,
36
+ path: [assignment.assignedVariable ?? assignment.expression, label],
37
+ constrained: support.length > 0,
38
+ support,
39
+ risk: /point|base|scalar|accumulator|x|y/i.test(label) ? "ec_unconnected_coordinate" : "untrusted_to_output",
40
+ confidence: support.length > 0 ? "MEDIUM" : "HIGH",
41
+ sourceLocation: assignment
42
+ });
43
+ }
44
+ for (const binding of context.halo2.instanceConstraints) {
45
+ flows.push({
46
+ id: idFor("TF-HALO2-PUBLIC", flows.length),
47
+ source: binding.cell,
48
+ sink: binding.instanceColumn,
49
+ path: [binding.cell, binding.instanceColumn],
50
+ constrained: true,
51
+ support: [binding.snippet ?? "constrain_instance"],
52
+ risk: "public_binding_without_relation",
53
+ confidence: "MEDIUM",
54
+ sourceLocation: binding
55
+ });
56
+ }
57
+ }
58
+ return flows;
59
+ }
60
+ //# sourceMappingURL=taint-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taint-flow.js","sourceRoot":"","sources":["../../src/analysis/taint-flow.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -19,6 +19,7 @@ program
19
19
  .option("--out <path>", "write report output to a path")
20
20
  .option("--fail-on <severity>", "CRITICAL, HIGH, MEDIUM, LOW, or INFO")
21
21
  .option("--config <path>", "config file path")
22
+ .option("--deep", "enable proof obligation, taint flow, and exploit hypothesis analysis")
22
23
  .action(async (target, options) => {
23
24
  try {
24
25
  const run = await scanTarget(target, {
@@ -26,7 +27,8 @@ program
26
27
  report: options.report,
27
28
  out: options.out,
28
29
  failOn: options.failOn ? normalizeSeverity(options.failOn, "CRITICAL") : undefined,
29
- configPath: options.config
30
+ configPath: options.config,
31
+ deep: options.deep
30
32
  });
31
33
  if (!options.out && !options.report)
32
34
  process.stdout.write(run.output);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  import type { AuditResult, NullsecConfig, ParsedCircuitFile } from "../types.js";
2
2
  import type { Halo2CircuitFile } from "../frontends/halo2/halo2-types.js";
3
- export declare function auditParsedFiles(target: string, parsedFiles: ParsedCircuitFile[], config: NullsecConfig, halo2Files?: Halo2CircuitFile[]): AuditResult;
3
+ export declare function auditParsedFiles(target: string, parsedFiles: ParsedCircuitFile[], config: NullsecConfig, halo2Files?: Halo2CircuitFile[], deep?: boolean): AuditResult;
@@ -1,6 +1,7 @@
1
1
  import { buildCircuitIR } from "../frontends/circom/circom-ir-builder.js";
2
2
  import { buildHalo2IR } from "../frontends/halo2/halo2-ir-builder.js";
3
3
  import { ConstraintGraph } from "../ir/constraint-graph.js";
4
+ import { runDeepAnalysis } from "../analysis/deep-analysis.js";
4
5
  import { allRules } from "../rules/index.js";
5
6
  import { summarizeIssues } from "../report/summary.js";
6
7
  import { RuleEngine } from "./rule-engine.js";
@@ -11,12 +12,13 @@ function frontendName(circomCount, halo2Count) {
11
12
  return "Halo2";
12
13
  return "Circom";
13
14
  }
14
- export function auditParsedFiles(target, parsedFiles, config, halo2Files = []) {
15
+ export function auditParsedFiles(target, parsedFiles, config, halo2Files = [], deep = false) {
15
16
  const ir = buildCircuitIR(parsedFiles);
16
17
  const halo2 = buildHalo2IR(halo2Files);
17
18
  const graph = new ConstraintGraph(ir);
18
19
  const engine = new RuleEngine(allRules);
19
- const { issues, rulesExecuted } = engine.run({ target, ir, graph, config, halo2 });
20
+ const context = { target, ir, graph, config, halo2 };
21
+ const { issues, rulesExecuted } = engine.run(context);
20
22
  return {
21
23
  tool: { name: "Nullsec S1-ZK", version: "1.0.0" },
22
24
  target,
@@ -25,7 +27,8 @@ export function auditParsedFiles(target, parsedFiles, config, halo2Files = []) {
25
27
  rulesExecuted,
26
28
  summary: summarizeIssues(issues),
27
29
  issues,
28
- parserWarnings: [...ir.parserWarnings, ...halo2.parserWarnings]
30
+ parserWarnings: [...ir.parserWarnings, ...halo2.parserWarnings],
31
+ deepAnalysis: deep ? runDeepAnalysis(context, issues) : undefined
29
32
  };
30
33
  }
31
34
  //# sourceMappingURL=audit-engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit-engine.js","sourceRoot":"","sources":["../../src/core/audit-engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,SAAS,YAAY,CAAC,WAAmB,EAAE,UAAkB;IAC3D,IAAI,WAAW,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IACtD,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IACnC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,WAAgC,EAAE,MAAqB,EAAE,aAAiC,EAAE;IAC3I,MAAM,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACnF,OAAO;QACL,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE;QACjD,MAAM;QACN,QAAQ,EAAE,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC;QAC7D,YAAY,EAAE,WAAW,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM;QACpD,aAAa;QACb,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;QAChC,MAAM;QACN,cAAc,EAAE,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,GAAG,KAAK,CAAC,cAAc,CAAC;KAChE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"audit-engine.js","sourceRoot":"","sources":["../../src/core/audit-engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,SAAS,YAAY,CAAC,WAAmB,EAAE,UAAkB;IAC3D,IAAI,WAAW,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IACtD,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IACnC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,WAAgC,EAAE,MAAqB,EAAE,aAAiC,EAAE,EAAE,IAAI,GAAG,KAAK;IACzJ,MAAM,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACrD,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtD,OAAO;QACL,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE;QACjD,MAAM;QACN,QAAQ,EAAE,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC;QAC7D,YAAY,EAAE,WAAW,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM;QACpD,aAAa;QACb,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;QAChC,MAAM;QACN,cAAc,EAAE,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,GAAG,KAAK,CAAC,cAAc,CAAC;QAC/D,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;KAClE,CAAC;AACJ,CAAC"}
@@ -19,6 +19,38 @@ ${issue.impact}
19
19
  ${issue.suggestedFix}
20
20
  `;
21
21
  }
22
+ function renderDeepAnalysis(result) {
23
+ const deep = result.deepAnalysis;
24
+ if (!deep)
25
+ return "";
26
+ const summary = deep.proofObligationSummary;
27
+ return `## Proof Obligations
28
+
29
+ - Total inferred: ${summary.total}
30
+ - Satisfied: ${summary.satisfied}
31
+ - Partial: ${summary.partially_satisfied}
32
+ - Missing: ${summary.missing}
33
+ - Unknown: ${summary.unknown}
34
+
35
+ ## Exploit Hypotheses
36
+
37
+ ${deep.exploitHypotheses
38
+ .slice(0, 10)
39
+ .map((hypothesis) => `### ${hypothesis.issueId}
40
+
41
+ ${hypothesis.hypothesis}
42
+
43
+ **Attacker control:** ${hypothesis.attackerControl}
44
+
45
+ **Broken assumption:** ${hypothesis.brokenAssumption}
46
+
47
+ **Possible impact:** ${hypothesis.possibleImpact}
48
+
49
+ **Patch direction:** ${hypothesis.patchDirection}
50
+ `)
51
+ .join("\n")}
52
+ `;
53
+ }
22
54
  export function renderMarkdownReport(result) {
23
55
  return `# Nullsec S1-ZK Report
24
56
 
@@ -38,6 +70,7 @@ AI-native auditing for zero-knowledge circuits. Find underconstraints before the
38
70
  - LOW: ${result.summary.LOW}
39
71
  - INFO: ${result.summary.INFO}
40
72
 
73
+ ${renderDeepAnalysis(result)}
41
74
  ${result.issues.map(renderIssue).join("\n")}
42
75
  ${result.parserWarnings.length > 0 ? `\n## Parser Warnings\n\n${result.parserWarnings.map((warning) => `- \`${warning.file}:${warning.line}\` ${warning.message}`).join("\n")}\n` : ""}
43
76
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/report/markdown.ts"],"names":[],"mappings":"AAEA,SAAS,WAAW,CAAC,KAAY;IAC/B,OAAO,OAAO,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK;;cAEhD,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;gBACtB,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,SAAS;kBAC1D,KAAK,CAAC,UAAU;;;EAGhC,KAAK,CAAC,OAAO,IAAI,EAAE;;;;EAInB,KAAK,CAAC,WAAW;;;EAGjB,KAAK,CAAC,MAAM;;;EAGZ,KAAK,CAAC,YAAY;CACnB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,OAAO;;;;gBAIO,MAAM,CAAC,MAAM;gBACb,MAAM,CAAC,QAAQ;qBACV,MAAM,CAAC,YAAY;sBAClB,MAAM,CAAC,aAAa;oBACtB,MAAM,CAAC,MAAM,CAAC,MAAM;;;;cAI1B,MAAM,CAAC,OAAO,CAAC,QAAQ;UAC3B,MAAM,CAAC,OAAO,CAAC,IAAI;YACjB,MAAM,CAAC,OAAO,CAAC,MAAM;SACxB,MAAM,CAAC,OAAO,CAAC,GAAG;UACjB,MAAM,CAAC,OAAO,CAAC,IAAI;;EAE3B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;EACzC,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,2BAA2B,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;CACrL,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/report/markdown.ts"],"names":[],"mappings":"AAEA,SAAS,WAAW,CAAC,KAAY;IAC/B,OAAO,OAAO,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK;;cAEhD,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;gBACtB,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,SAAS;kBAC1D,KAAK,CAAC,UAAU;;;EAGhC,KAAK,CAAC,OAAO,IAAI,EAAE;;;;EAInB,KAAK,CAAC,WAAW;;;EAGjB,KAAK,CAAC,MAAM;;;EAGZ,KAAK,CAAC,YAAY;CACnB,CAAC;AACF,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAmB;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC;IAC5C,OAAO;;oBAEW,OAAO,CAAC,KAAK;eAClB,OAAO,CAAC,SAAS;aACnB,OAAO,CAAC,mBAAmB;aAC3B,OAAO,CAAC,OAAO;aACf,OAAO,CAAC,OAAO;;;;EAI1B,IAAI,CAAC,iBAAiB;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,GAAG,CACF,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,OAAO;;EAE3C,UAAU,CAAC,UAAU;;wBAEC,UAAU,CAAC,eAAe;;yBAEzB,UAAU,CAAC,gBAAgB;;uBAE7B,UAAU,CAAC,cAAc;;uBAEzB,UAAU,CAAC,cAAc;CAC/C,CACE;SACA,IAAI,CAAC,IAAI,CAAC;CACZ,CAAC;AACF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,OAAO;;;;gBAIO,MAAM,CAAC,MAAM;gBACb,MAAM,CAAC,QAAQ;qBACV,MAAM,CAAC,YAAY;sBAClB,MAAM,CAAC,aAAa;oBACtB,MAAM,CAAC,MAAM,CAAC,MAAM;;;;cAI1B,MAAM,CAAC,OAAO,CAAC,QAAQ;UAC3B,MAAM,CAAC,OAAO,CAAC,IAAI;YACjB,MAAM,CAAC,OAAO,CAAC,MAAM;SACxB,MAAM,CAAC,OAAO,CAAC,GAAG;UACjB,MAAM,CAAC,OAAO,CAAC,IAAI;;EAE3B,kBAAkB,CAAC,MAAM,CAAC;EAC1B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;EACzC,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,2BAA2B,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;CACrL,CAAC;AACF,CAAC"}
@@ -27,6 +27,30 @@ Confidence:
27
27
  ${issue.confidence}
28
28
  `;
29
29
  }
30
+ function renderDeepAnalysis(result) {
31
+ const deep = result.deepAnalysis;
32
+ if (!deep)
33
+ return "";
34
+ const summary = deep.proofObligationSummary;
35
+ const criticalHypotheses = deep.exploitHypotheses.slice(0, 5);
36
+ return `
37
+ Proof obligations:
38
+ Total ${summary.total}
39
+ Satisfied ${summary.satisfied}
40
+ Partial ${summary.partially_satisfied}
41
+ Missing ${summary.missing}
42
+ Unknown ${summary.unknown}
43
+
44
+ ${criticalHypotheses
45
+ .map((hypothesis) => `Exploit hypothesis for ${hypothesis.issueId}:
46
+ ${hypothesis.hypothesis}
47
+ Broken assumption:
48
+ ${hypothesis.brokenAssumption}
49
+ Patch direction:
50
+ ${hypothesis.patchDirection}
51
+ `)
52
+ .join("\n")}`;
53
+ }
30
54
  export function renderTerminalReport(result) {
31
55
  return `${chalk.bold("Nullsec S1-ZK")}
32
56
  AI-native auditing for zero-knowledge circuits
@@ -44,6 +68,7 @@ MEDIUM ${result.summary.MEDIUM}
44
68
  LOW ${result.summary.LOW}
45
69
  INFO ${result.summary.INFO}
46
70
 
71
+ ${renderDeepAnalysis(result)}
47
72
  ${result.issues.map(renderIssue).join("\n")}
48
73
  ${result.parserWarnings.length > 0 ? `Parser warnings: ${result.parserWarnings.length}\n` : ""}`;
49
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/report/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,eAAe,GAAgD;IACnE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI;IAC9B,IAAI,EAAE,KAAK,CAAC,GAAG;IACf,MAAM,EAAE,KAAK,CAAC,MAAM;IACpB,GAAG,EAAE,KAAK,CAAC,IAAI;IACf,IAAI,EAAE,KAAK,CAAC,IAAI;CACjB,CAAC;AAEF,SAAS,WAAW,CAAC,KAAY;IAC/B,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK;QAC/D,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;YACpB,KAAK,CAAC,YAAY,IAAI,SAAS;;IAEvC,KAAK,CAAC,OAAO,IAAI,EAAE;;;EAGrB,KAAK,CAAC,WAAW;;;EAGjB,KAAK,CAAC,MAAM;;;EAGZ,KAAK,CAAC,YAAY;;;EAGlB,KAAK,CAAC,UAAU;CACjB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;;;UAG7B,MAAM,CAAC,MAAM;YACX,MAAM,CAAC,QAAQ;iBACV,MAAM,CAAC,YAAY;kBAClB,MAAM,CAAC,aAAa;gBACtB,MAAM,CAAC,MAAM,CAAC,MAAM;;;YAGxB,MAAM,CAAC,OAAO,CAAC,QAAQ;YACvB,MAAM,CAAC,OAAO,CAAC,IAAI;YACnB,MAAM,CAAC,OAAO,CAAC,MAAM;YACrB,MAAM,CAAC,OAAO,CAAC,GAAG;YAClB,MAAM,CAAC,OAAO,CAAC,IAAI;;EAE7B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;EACzC,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,MAAM,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACjG,CAAC"}
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/report/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,eAAe,GAAgD;IACnE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI;IAC9B,IAAI,EAAE,KAAK,CAAC,GAAG;IACf,MAAM,EAAE,KAAK,CAAC,MAAM;IACpB,GAAG,EAAE,KAAK,CAAC,IAAI;IACf,IAAI,EAAE,KAAK,CAAC,IAAI;CACjB,CAAC;AAEF,SAAS,WAAW,CAAC,KAAY;IAC/B,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK;QAC/D,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;YACpB,KAAK,CAAC,YAAY,IAAI,SAAS;;IAEvC,KAAK,CAAC,OAAO,IAAI,EAAE;;;EAGrB,KAAK,CAAC,WAAW;;;EAGjB,KAAK,CAAC,MAAM;;;EAGZ,KAAK,CAAC,YAAY;;;EAGlB,KAAK,CAAC,UAAU;CACjB,CAAC;AACF,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAmB;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC;IAC5C,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,OAAO;;aAEI,OAAO,CAAC,KAAK;aACb,OAAO,CAAC,SAAS;aACjB,OAAO,CAAC,mBAAmB;aAC3B,OAAO,CAAC,OAAO;aACf,OAAO,CAAC,OAAO;;EAE1B,kBAAkB;SACjB,GAAG,CACF,CAAC,UAAU,EAAE,EAAE,CAAC,0BAA0B,UAAU,CAAC,OAAO;EAC9D,UAAU,CAAC,UAAU;;EAErB,UAAU,CAAC,gBAAgB;;EAE3B,UAAU,CAAC,cAAc;CAC1B,CACE;SACA,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;;;UAG7B,MAAM,CAAC,MAAM;YACX,MAAM,CAAC,QAAQ;iBACV,MAAM,CAAC,YAAY;kBAClB,MAAM,CAAC,aAAa;gBACtB,MAAM,CAAC,MAAM,CAAC,MAAM;;;YAGxB,MAAM,CAAC,OAAO,CAAC,QAAQ;YACvB,MAAM,CAAC,OAAO,CAAC,IAAI;YACnB,MAAM,CAAC,OAAO,CAAC,MAAM;YACrB,MAAM,CAAC,OAAO,CAAC,GAAG;YAClB,MAAM,CAAC,OAAO,CAAC,IAAI;;EAE7B,kBAAkB,CAAC,MAAM,CAAC;EAC1B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;EACzC,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,MAAM,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACjG,CAAC"}
package/dist/scanner.js CHANGED
@@ -18,7 +18,7 @@ export async function scanTarget(target, options = {}) {
18
18
  const rustFiles = await loadRustFiles(target, config.ignore);
19
19
  const parsed = circomFiles.map((file) => parseCircomFile(file.filePath, file.rawSource));
20
20
  const halo2Parsed = rustFiles.filter((file) => isLikelyHalo2Source(file.rawSource)).map((file) => parseHalo2File(file.filePath, file.rawSource));
21
- const result = auditParsedFiles(target, parsed, { ...config, failOn, format }, halo2Parsed);
21
+ const result = auditParsedFiles(target, parsed, { ...config, failOn, format }, halo2Parsed, options.deep ?? false);
22
22
  const output = renderReport(result, format);
23
23
  if (options.out || options.report) {
24
24
  const outPath = options.out ?? defaultReportPath(format);
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -6,6 +6,8 @@ export type AssignmentOperator = "<--" | "<==";
6
6
  export type ConstraintOperator = "===" | "<==";
7
7
  export type OutputFormat = "terminal" | "json" | "markdown" | "sarif";
8
8
  export type FrontendName = "Circom" | "Halo2" | "Mixed";
9
+ export type ProofObligationType = "commitment_binding" | "nullifier_binding" | "merkle_root_binding" | "selector_booleanity" | "ec_multiplication" | "public_input_binding" | "range_constraint";
10
+ export type RelationStatus = "satisfied" | "partially_satisfied" | "missing" | "unknown";
9
11
  export interface SourceLocation {
10
12
  file: string;
11
13
  line: number;
@@ -161,6 +163,7 @@ export interface AuditResult {
161
163
  summary: AuditSummary;
162
164
  issues: Issue[];
163
165
  parserWarnings: ParserWarning[];
166
+ deepAnalysis?: DeepAnalysisResult;
164
167
  }
165
168
  export interface ScanOptions {
166
169
  format?: OutputFormat;
@@ -168,4 +171,59 @@ export interface ScanOptions {
168
171
  out?: string;
169
172
  failOn?: Severity;
170
173
  configPath?: string;
174
+ deep?: boolean;
175
+ }
176
+ export interface ProofObligation {
177
+ id: string;
178
+ type: ProofObligationType;
179
+ subject: string;
180
+ requiredInputs: string[];
181
+ expectedRelation: string;
182
+ relatedSignals: string[];
183
+ confidence: Confidence;
184
+ sourceLocation: SourceLocation;
185
+ }
186
+ export interface RelationCheckResult {
187
+ obligationId: string;
188
+ status: RelationStatus;
189
+ evidence: string[];
190
+ missing: string[];
191
+ explanation: string;
192
+ }
193
+ export interface TaintFlowPath {
194
+ id: string;
195
+ source: string;
196
+ sink: string;
197
+ path: string[];
198
+ constrained: boolean;
199
+ support: string[];
200
+ risk: "untrusted_to_output" | "public_binding_without_relation" | "ec_unconnected_coordinate";
201
+ confidence: Confidence;
202
+ sourceLocation?: SourceLocation;
203
+ }
204
+ export interface ExploitHypothesis {
205
+ issueId: string;
206
+ relatedObligationId?: string;
207
+ hypothesis: string;
208
+ attackerControl: string;
209
+ brokenAssumption: string;
210
+ possibleImpact: string;
211
+ validationSteps: string[];
212
+ patchDirection: string;
213
+ confidence: Confidence;
214
+ }
215
+ export interface ProofObligationSummary {
216
+ total: number;
217
+ satisfied: number;
218
+ partially_satisfied: number;
219
+ missing: number;
220
+ unknown: number;
221
+ }
222
+ export interface DeepAnalysisResult {
223
+ enabled: true;
224
+ proofObligations: ProofObligation[];
225
+ relationChecks: RelationCheckResult[];
226
+ proofObligationSummary: ProofObligationSummary;
227
+ taintFlows: TaintFlowPath[];
228
+ exploitHypotheses: ExploitHypothesis[];
171
229
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trynullsec/s1-zk",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Nullsec S1-ZK: AI-native auditing for zero-knowledge circuits.",
5
5
  "type": "module",
6
6
  "bin": {