@trynullsec/s1-zk 1.0.5 → 1.0.7

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 ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ ## 1.0.5
4
+
5
+ ### Added
6
+
7
+ - Circom frontend with tokenizer, parser, constraint graph, examples, reports, and rule coverage.
8
+ - Halo2-style Rust frontend with heuristic gate, assignment, equality, selector, lookup, and public binding extraction.
9
+ - Graph-aware Halo2 constraint analysis.
10
+ - Proof obligation deep mode.
11
+ - Deterministic exploit hypotheses.
12
+ - Orchard-inspired synthetic Halo2 benchmark.
13
+ - npm package `@trynullsec/s1-zk`.
14
+
15
+ ### Changed
16
+
17
+ - README and package metadata now present the project as deterministic, graph-aware static analysis.
18
+ - Version reporting is synchronized from `package.json`.
19
+
20
+ ### Fixed
21
+
22
+ - CLI/report version mismatch.
23
+ - Prompt-builder code fence language for Halo2 issues.
@@ -0,0 +1,31 @@
1
+ # Contributing
2
+
3
+ Thanks for helping improve Nullsec S1-ZK.
4
+
5
+ ## Development
6
+
7
+ ```bash
8
+ npm install
9
+ npm run build
10
+ npm test
11
+ npm run benchmark
12
+ ```
13
+
14
+ ## Rule Contributions
15
+
16
+ Every new rule should include:
17
+
18
+ - Rule implementation.
19
+ - Vulnerable fixture.
20
+ - Safe fixture when practical.
21
+ - Test coverage.
22
+ - `RULES.md` documentation.
23
+
24
+ Rule naming:
25
+
26
+ - `NS-ZK-*` for generic or Circom ZK rules.
27
+ - `NS-H2-*` for Halo2 rules.
28
+
29
+ ## Notes
30
+
31
+ Keep findings precise and avoid formal-verification claims unless the implementation actually proves a property. Prefer deterministic static-analysis evidence, clear confidence levels, and honest limitations.
package/README.md CHANGED
@@ -6,19 +6,21 @@
6
6
 
7
7
  <p align="center">
8
8
  <a href="https://www.npmjs.com/package/@trynullsec/s1-zk"><img src="https://img.shields.io/npm/v/@trynullsec/s1-zk?color=111827&label=npm" alt="npm version" /></a>
9
+ <a href="https://github.com/trynullsec/nullsec-s1-zk/actions/workflows/ci.yml"><img src="https://github.com/trynullsec/nullsec-s1-zk/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
9
10
  <img src="https://img.shields.io/badge/TypeScript-5.x-3178c6" alt="TypeScript" />
10
11
  <img src="https://img.shields.io/badge/Circom-supported-16a34a" alt="Circom supported" />
11
- <img src="https://img.shields.io/badge/Halo2-supported-7c3aed" alt="Halo2 supported" />
12
- <img src="https://img.shields.io/badge/status-active-16a34a" alt="status active" />
12
+ <img src="https://img.shields.io/badge/Halo2-heuristic-7c3aed" alt="Halo2 heuristic" />
13
13
  <img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license" />
14
14
  </p>
15
15
 
16
- **AI-native auditing for zero-knowledge circuits.**
16
+ **Deterministic, graph-aware static analysis for zero-knowledge circuits.**
17
17
 
18
18
  Nullsec S1-ZK is an open-source security engine for zero-knowledge circuits.
19
19
 
20
20
  It analyzes Circom and Halo2 circuits, builds constraint graphs, infers proof obligations, and generates exploit hypotheses for underconstraint risks.
21
21
 
22
+ S1-ZK is fully local and deterministic. It sends no code to external services. LLM-assisted reasoning is planned, but not required by the current engine.
23
+
22
24
  **Find underconstraints before they mint infinite money.**
23
25
 
24
26
  ```bash
@@ -37,6 +39,13 @@ The tool is designed for ZK auditors, protocol engineers, security researchers,
37
39
 
38
40
  ## Supported Frontends
39
41
 
42
+ | Frontend | Status | Notes |
43
+ | --- | --- | --- |
44
+ | Circom | Full | Tokenizer, parser, constraint graph, rule coverage |
45
+ | Halo2-style Rust | Heuristic | Pattern/dataflow based; no full Rust AST yet |
46
+ | Noir | Planned | Adapter stub only |
47
+ | gnark | Planned | Adapter stub only |
48
+
40
49
  ### Circom
41
50
 
42
51
  The Circom frontend parses `.circom` files and builds a signal/constraint graph for high-signal soundness checks:
@@ -115,11 +124,18 @@ nullsec-zk scan ./circuits
115
124
  nullsec-zk scan ./circuits --deep
116
125
  nullsec-zk scan ./circuits --format json
117
126
  nullsec-zk scan ./circuits --report markdown
127
+ nullsec-zk scan ./circuits --deep --no-banner
118
128
  nullsec-zk rules
119
129
  nullsec-zk explain NS-H2-005
120
130
  nullsec-zk init
121
131
  ```
122
132
 
133
+ Use `--no-banner` for machine-readable logs or minimal terminal output:
134
+
135
+ ```bash
136
+ nullsec-zk scan ./circuits --deep --no-banner
137
+ ```
138
+
123
139
  The same commands work through `npx`:
124
140
 
125
141
  ```bash
@@ -138,14 +154,21 @@ Target: ./examples
138
154
  Frontend: Mixed
139
155
  Files scanned: 24
140
156
  Rules executed: 18
141
- Issues found: 33
157
+ Issues found: 34
142
158
 
143
159
  Severity summary:
144
160
  CRITICAL 2
145
- HIGH 12
146
- MEDIUM 15
147
- LOW 4
148
- INFO 0
161
+ HIGH 20
162
+ MEDIUM 8
163
+ LOW 3
164
+ INFO 1
165
+
166
+ Proof obligations:
167
+ Total 68
168
+ Satisfied 59
169
+ Partial 0
170
+ Missing 9
171
+ Unknown 0
149
172
  ```
150
173
 
151
174
  ## Rule Coverage
@@ -185,6 +208,33 @@ Run it with deep analysis:
185
208
  npx @trynullsec/s1-zk scan ./benchmarks/historical/orchard-inspired --deep
186
209
  ```
187
210
 
211
+ ## Benchmark
212
+
213
+ Run the bundled regression corpus:
214
+
215
+ ```bash
216
+ npm run benchmark
217
+ ```
218
+
219
+ Current output:
220
+
221
+ ```text
222
+ vuln=14 safe=10 TP=13 FN=1 TN=10 FP=0
223
+ precision=100.00% recall=92.86% false_safe_rate=7.14% false_positive_rate=0.00%
224
+ MISSED: examples/halo2/vulnerable/missing-selector-booleanity.rs
225
+ ```
226
+
227
+ | Metric | Value |
228
+ | --- | ---: |
229
+ | False-safe rate | 7.14% |
230
+ | False-positive rate | 0.00% |
231
+ | Precision | 100.00% |
232
+ | Recall | 92.86% |
233
+
234
+ Bundled corpus size is small and intentionally synthetic. These numbers are regression signals for this repository, not a general claim about all ZK circuits.
235
+
236
+ Known miss: `examples/halo2/vulnerable/missing-selector-booleanity.rs`. Selector-booleanity detection for this fixture is not yet covered by `NS-H2-003`.
237
+
188
238
  ## Reports
189
239
 
190
240
  Nullsec S1-ZK supports:
package/SECURITY.md ADDED
@@ -0,0 +1,13 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ Please email [security@trynullsec.com](mailto:security@trynullsec.com).
6
+
7
+ Do not open public GitHub issues for vulnerabilities.
8
+
9
+ We aim to acknowledge reports within 48 hours and provide a remediation timeline within 5 business days.
10
+
11
+ ## Scope
12
+
13
+ Nullsec S1-ZK performs best-effort static analysis. It does not prove circuit soundness and does not replace expert ZK audits. See [LIMITATIONS.md](./LIMITATIONS.md).
@@ -0,0 +1,72 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { readdirSync } from "node:fs";
3
+ import { join } from "node:path";
4
+
5
+ const root = new URL("..", import.meta.url).pathname;
6
+
7
+ const sets = [
8
+ { vulnerable: "examples/vulnerable", safe: "examples/safe" },
9
+ { vulnerable: "examples/halo2/vulnerable", safe: "examples/halo2/safe" }
10
+ ];
11
+
12
+ function filesIn(dir) {
13
+ return readdirSync(join(root, dir))
14
+ .filter((file) => file.endsWith(".circom") || file.endsWith(".rs"))
15
+ .map((file) => join(dir, file));
16
+ }
17
+
18
+ function scan(file) {
19
+ try {
20
+ return JSON.parse(execFileSync("node", ["dist/cli.js", "scan", file, "--format", "json"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }));
21
+ } catch (error) {
22
+ const stdout = error.stdout?.toString() ?? "";
23
+ if (stdout.trim()) return JSON.parse(stdout);
24
+ throw error;
25
+ }
26
+ }
27
+
28
+ function hasHighOrCritical(result) {
29
+ return result.issues.some((issue) => issue.severity === "CRITICAL" || issue.severity === "HIGH");
30
+ }
31
+
32
+ let vuln = 0;
33
+ let safe = 0;
34
+ let TP = 0;
35
+ let FN = 0;
36
+ let TN = 0;
37
+ let FP = 0;
38
+ const missed = [];
39
+ const falsePositives = [];
40
+
41
+ for (const set of sets) {
42
+ for (const file of filesIn(set.vulnerable)) {
43
+ vuln += 1;
44
+ if (hasHighOrCritical(scan(file))) TP += 1;
45
+ else {
46
+ FN += 1;
47
+ missed.push(file);
48
+ }
49
+ }
50
+ for (const file of filesIn(set.safe)) {
51
+ safe += 1;
52
+ if (hasHighOrCritical(scan(file))) {
53
+ FP += 1;
54
+ falsePositives.push(file);
55
+ } else {
56
+ TN += 1;
57
+ }
58
+ }
59
+ }
60
+
61
+ const pct = (numerator, denominator) => (denominator === 0 ? "0.00" : ((numerator / denominator) * 100).toFixed(2));
62
+ const precision = pct(TP, TP + FP);
63
+ const recall = pct(TP, TP + FN);
64
+ const falseSafeRate = pct(FN, vuln);
65
+ const falsePositiveRate = pct(FP, safe);
66
+
67
+ console.log(`vuln=${vuln} safe=${safe} TP=${TP} FN=${FN} TN=${TN} FP=${FP}`);
68
+ console.log(`precision=${precision}% recall=${recall}% false_safe_rate=${falseSafeRate}% false_positive_rate=${falsePositiveRate}%`);
69
+ for (const file of missed) console.log(`MISSED: ${file}`);
70
+ for (const file of falsePositives) console.log(`FALSE POSITIVE: ${file}`);
71
+
72
+ if (FP > 0) process.exit(1);
@@ -1,4 +1,5 @@
1
1
  export function buildReasoningPrompt(issue, surroundingCode, circuitIntent = "Unknown from static analysis") {
2
+ const codeFenceLanguage = issue.ruleId.startsWith("NS-H2") ? "rust" : "circom";
2
3
  return `You are reviewing a zero-knowledge circuit issue reported by Nullsec S1-ZK.
3
4
 
4
5
  Circuit intent:
@@ -19,7 +20,7 @@ Impact:
19
20
  ${issue.impact}
20
21
 
21
22
  Surrounding code:
22
- \`\`\`circom
23
+ \`\`\`${codeFenceLanguage}
23
24
  ${surroundingCode}
24
25
  \`\`\`
25
26
 
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../src/ai/prompt-builder.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAAC,KAAY,EAAE,eAAuB,EAAE,aAAa,GAAG,8BAA8B;IACxH,OAAO;;;EAGP,aAAa;;;UAGL,KAAK,CAAC,MAAM;WACX,KAAK,CAAC,KAAK;cACR,KAAK,CAAC,QAAQ;gBACZ,KAAK,CAAC,UAAU;UACtB,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;YACtB,KAAK,CAAC,UAAU,IAAI,SAAS;;;EAGvC,KAAK,CAAC,WAAW;;;EAGjB,KAAK,CAAC,MAAM;;;;EAIZ,eAAe;;;;;;;;+DAQ8C,CAAC;AAChE,CAAC"}
1
+ {"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../src/ai/prompt-builder.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAAC,KAAY,EAAE,eAAuB,EAAE,aAAa,GAAG,8BAA8B;IACxH,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/E,OAAO;;;EAGP,aAAa;;;UAGL,KAAK,CAAC,MAAM;WACX,KAAK,CAAC,KAAK;cACR,KAAK,CAAC,QAAQ;gBACZ,KAAK,CAAC,UAAU;UACtB,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;YACtB,KAAK,CAAC,UAAU,IAAI,SAAS;;;EAGvC,KAAK,CAAC,WAAW;;;EAGjB,KAAK,CAAC,MAAM;;;QAGN,iBAAiB;EACvB,eAAe;;;;;;;;+DAQ8C,CAAC;AAChE,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface BannerOptions {
2
+ compact?: boolean;
3
+ silent?: boolean;
4
+ }
5
+ export declare function printBanner(options?: BannerOptions): void;
@@ -0,0 +1,38 @@
1
+ import chalk from "chalk";
2
+ function shouldPrint(silent) {
3
+ if (silent)
4
+ return false;
5
+ return Boolean(process.stdout.isTTY) || process.env.NULLSEC_ZK_FORCE_BANNER === "1";
6
+ }
7
+ export function printBanner(options = {}) {
8
+ if (!shouldPrint(options.silent))
9
+ return;
10
+ const accent = chalk.cyanBright;
11
+ const muted = chalk.gray;
12
+ const strong = chalk.whiteBright;
13
+ const star = process.stdout.isTTY ? "✶" : "*";
14
+ if (options.compact) {
15
+ process.stdout.write(`${muted("╭────────────────────────────────────────────╮")}
16
+ ${muted("│")} ${accent(star)} ${strong("Nullsec S1-ZK")} ${muted("│")}
17
+ ${muted("╰────────────────────────────────────────────╯")}
18
+
19
+ `);
20
+ return;
21
+ }
22
+ process.stdout.write(`${muted("╭────────────────────────────────────────────╮")}
23
+ ${muted("│")} ${accent(star)} ${strong("Nullsec S1-ZK")} ${muted("│")}
24
+ ${muted("╰────────────────────────────────────────────╯")}
25
+
26
+ ${accent("███╗ ██╗██╗ ██╗██╗ ██╗ ███████╗███████╗ ██████╗")}
27
+ ${accent("████╗ ██║██║ ██║██║ ██║ ██╔════╝██╔════╝██╔════╝")}
28
+ ${accent("██╔██╗ ██║██║ ██║██║ ██║ ███████╗█████╗ ██║ ")}
29
+ ${accent("██║╚██╗██║██║ ██║██║ ██║ ╚════██║██╔══╝ ██║ ")}
30
+ ${accent("██║ ╚████║╚██████╔╝███████╗███████╗███████║███████╗╚██████╗")}
31
+ ${accent("╚═╝ ╚═══╝ ╚═════╝ ╚══════╝╚══════╝╚══════╝╚══════╝ ╚═════╝")}
32
+
33
+ ${strong("S1-ZK")} ${muted("·")} audit what your circuit actually proves
34
+ ${muted("Local deterministic analysis · Circom + Halo2 · scan ./circuits --deep")}
35
+
36
+ `);
37
+ }
38
+ //# sourceMappingURL=cli-banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-banner.js","sourceRoot":"","sources":["../src/cli-banner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,SAAS,WAAW,CAAC,MAAgB;IACnC,IAAI,MAAM;QAAE,OAAO,KAAK,CAAC;IACzB,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,UAAyB,EAAE;IACrD,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO;IAEzC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC;IACzB,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;IACjC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAE9C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,KAAK,CAAC,gDAAgD,CAAC;EAC9D,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,eAAe,CAAC,+BAA+B,KAAK,CAAC,GAAG,CAAC;EAC9F,KAAK,CAAC,gDAAgD,CAAC;;CAExD,CACI,CAAC;QACF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,KAAK,CAAC,gDAAgD,CAAC;EAC5D,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,eAAe,CAAC,+BAA+B,KAAK,CAAC,GAAG,CAAC;EAC9F,KAAK,CAAC,gDAAgD,CAAC;;EAEvD,MAAM,CAAC,6DAA6D,CAAC;EACrE,MAAM,CAAC,6DAA6D,CAAC;EACrE,MAAM,CAAC,6DAA6D,CAAC;EACrE,MAAM,CAAC,6DAA6D,CAAC;EACrE,MAAM,CAAC,6DAA6D,CAAC;EACrE,MAAM,CAAC,6DAA6D,CAAC;;EAErE,MAAM,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC;EAC9B,KAAK,CAAC,4EAA4E,CAAC;;CAEpF,CACE,CAAC;AACJ,CAAC"}
package/dist/cli.js CHANGED
@@ -5,12 +5,25 @@ import { existsSync } from "node:fs";
5
5
  import { scanTarget } from "./scanner.js";
6
6
  import { writeDefaultConfig } from "./config.js";
7
7
  import { allRules } from "./rules/index.js";
8
+ import { printBanner } from "./cli-banner.js";
8
9
  import { normalizeSeverity } from "./core/severity.js";
10
+ import { VERSION } from "./version.js";
9
11
  const program = new Command();
12
+ function bannerDisabled(options) {
13
+ return options.banner === false || process.argv.includes("--no-banner");
14
+ }
15
+ function isMachineFormat(format) {
16
+ return format === "json" || format === "sarif";
17
+ }
10
18
  program
11
19
  .name("nullsec-zk")
12
- .description("Nullsec S1-ZK: AI-native auditing for zero-knowledge circuits.")
13
- .version("1.0.0");
20
+ .description("Nullsec S1-ZK: deterministic, graph-aware static analysis for zero-knowledge circuits.")
21
+ .version(VERSION);
22
+ program.option("--no-banner", "disable the terminal intro banner");
23
+ program.addHelpText("beforeAll", () => {
24
+ printBanner({ compact: true, silent: bannerDisabled(program.opts()) });
25
+ return "";
26
+ });
14
27
  program
15
28
  .command("scan")
16
29
  .argument("<target>", "Circom file or directory to scan")
@@ -20,8 +33,12 @@ program
20
33
  .option("--fail-on <severity>", "CRITICAL, HIGH, MEDIUM, LOW, or INFO")
21
34
  .option("--config <path>", "config file path")
22
35
  .option("--deep", "enable proof obligation, taint flow, and exploit hypothesis analysis")
36
+ .option("--no-banner", "disable the terminal intro banner")
23
37
  .action(async (target, options) => {
24
38
  try {
39
+ const suppressBanner = bannerDisabled(options) || isMachineFormat(options.format) || Boolean(options.out);
40
+ if (!suppressBanner)
41
+ printBanner({ compact: options.report === "markdown", silent: false });
25
42
  const run = await scanTarget(target, {
26
43
  format: options.format,
27
44
  report: options.report,
@@ -41,11 +58,13 @@ program
41
58
  }
42
59
  });
43
60
  program.command("rules").description("List supported Nullsec S1-ZK rules").action(() => {
61
+ printBanner({ compact: true, silent: bannerDisabled(program.opts()) });
44
62
  for (const rule of allRules) {
45
63
  console.log(`${rule.id} ${rule.defaultSeverity.padEnd(8)} ${rule.title}`);
46
64
  }
47
65
  });
48
66
  program.command("explain").argument("<issue-id>", "Rule ID or issue ID").description("Explain a supported rule").action((issueId) => {
67
+ printBanner({ compact: true, silent: bannerDisabled(program.opts()) });
49
68
  const ruleId = issueId.match(/NS-(?:ZK|H2)-\d{3}/)?.[0] ?? issueId;
50
69
  const rule = allRules.find((candidate) => candidate.id === ruleId);
51
70
  if (!rule) {
@@ -61,6 +80,7 @@ Tags: ${rule.tags.join(", ")}
61
80
  ${rule.description}`);
62
81
  });
63
82
  program.command("init").description("Create a .nullsec-zk.json config file").action(() => {
83
+ printBanner({ compact: true, silent: bannerDisabled(program.opts()) });
64
84
  if (existsSync(".nullsec-zk.json")) {
65
85
  console.error(".nullsec-zk.json already exists");
66
86
  process.exitCode = 2;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,gEAAgE,CAAC;KAC7E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,QAAQ,CAAC,UAAU,EAAE,kCAAkC,CAAC;KACxD,MAAM,CAAC,mBAAmB,EAAE,oCAAoC,CAAC;KACjE,MAAM,CAAC,mBAAmB,EAAE,wCAAwC,CAAC;KACrE,MAAM,CAAC,cAAc,EAAE,+BAA+B,CAAC;KACvD,MAAM,CAAC,sBAAsB,EAAE,sCAAsC,CAAC;KACtE,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;KAC7C,MAAM,CAAC,QAAQ,EAAE,sEAAsE,CAAC;KACxF,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,OAAyH,EAAE,EAAE;IAC1J,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE;YACnC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;YAClF,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtE,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,KAAK,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;IACrF,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC,OAAe,EAAE,EAAE;IAC1I,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;IACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACnE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK;;oBAEnB,IAAI,CAAC,eAAe;QAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;;EAE1B,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACtB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,uCAAuC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;IACvF,IAAI,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { ConstraintGraph } from "../ir/constraint-graph.js";
4
4
  import { runDeepAnalysis } from "../analysis/deep-analysis.js";
5
5
  import { allRules } from "../rules/index.js";
6
6
  import { summarizeIssues } from "../report/summary.js";
7
+ import { VERSION } from "../version.js";
7
8
  import { RuleEngine } from "./rule-engine.js";
8
9
  function frontendName(circomCount, halo2Count) {
9
10
  if (circomCount > 0 && halo2Count > 0)
@@ -20,7 +21,7 @@ export function auditParsedFiles(target, parsedFiles, config, halo2Files = [], d
20
21
  const context = { target, ir, graph, config, halo2 };
21
22
  const { issues, rulesExecuted } = engine.run(context);
22
23
  return {
23
- tool: { name: "Nullsec S1-ZK", version: "1.0.0" },
24
+ tool: { name: "Nullsec S1-ZK", version: VERSION },
24
25
  target,
25
26
  frontend: frontendName(parsedFiles.length, halo2Files.length),
26
27
  filesScanned: parsedFiles.length + halo2Files.length,
@@ -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,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"}
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,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,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"}
@@ -0,0 +1 @@
1
+ export declare const VERSION = "1.0.7";
@@ -0,0 +1,2 @@
1
+ export const VERSION = "1.0.7";
2
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@trynullsec/s1-zk",
3
- "version": "1.0.5",
4
- "description": "Nullsec S1-ZK: AI-native auditing for zero-knowledge circuits.",
3
+ "version": "1.0.7",
4
+ "description": "Deterministic, graph-aware static analysis for zero-knowledge circuits.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "nullsec-zk": "dist/cli.js"
@@ -10,10 +10,12 @@
10
10
  ".": "./dist/index.js"
11
11
  },
12
12
  "scripts": {
13
+ "prebuild": "node scripts/sync-version.mjs",
13
14
  "build": "tsc -p tsconfig.json",
14
15
  "dev": "tsx src/cli.ts",
15
16
  "test": "vitest run tests",
16
- "lint": "tsc -p tsconfig.json --noEmit"
17
+ "lint": "tsc -p tsconfig.json --noEmit",
18
+ "benchmark": "npm run build && node benchmarks/run.mjs"
17
19
  },
18
20
  "keywords": [
19
21
  "zk",
@@ -51,6 +53,9 @@
51
53
  "dist",
52
54
  "README.md",
53
55
  "LICENSE",
56
+ "SECURITY.md",
57
+ "CONTRIBUTING.md",
58
+ "CHANGELOG.md",
54
59
  "RULES.md",
55
60
  "LIMITATIONS.md",
56
61
  "ROADMAP.md",