@elizaos/skills 2.0.0-alpha.3

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 (371) hide show
  1. package/README.md +126 -0
  2. package/package.json +53 -0
  3. package/skills/1password/SKILL.md +70 -0
  4. package/skills/1password/references/cli-examples.md +29 -0
  5. package/skills/1password/references/get-started.md +17 -0
  6. package/skills/apple-notes/SKILL.md +77 -0
  7. package/skills/apple-reminders/SKILL.md +96 -0
  8. package/skills/bear-notes/SKILL.md +107 -0
  9. package/skills/bird/SKILL.md +224 -0
  10. package/skills/blogwatcher/SKILL.md +69 -0
  11. package/skills/blucli/SKILL.md +47 -0
  12. package/skills/bluebubbles/SKILL.md +131 -0
  13. package/skills/camsnap/SKILL.md +45 -0
  14. package/skills/canvas/SKILL.md +203 -0
  15. package/skills/clawhub/SKILL.md +77 -0
  16. package/skills/coding-agent/SKILL.md +284 -0
  17. package/skills/discord/SKILL.md +578 -0
  18. package/skills/eightctl/SKILL.md +50 -0
  19. package/skills/food-order/SKILL.md +48 -0
  20. package/skills/gemini/SKILL.md +43 -0
  21. package/skills/gifgrep/SKILL.md +79 -0
  22. package/skills/github/SKILL.md +77 -0
  23. package/skills/gog/SKILL.md +116 -0
  24. package/skills/goplaces/SKILL.md +52 -0
  25. package/skills/healthcheck/SKILL.md +245 -0
  26. package/skills/himalaya/SKILL.md +257 -0
  27. package/skills/himalaya/references/configuration.md +184 -0
  28. package/skills/himalaya/references/message-composition.md +199 -0
  29. package/skills/imsg/SKILL.md +74 -0
  30. package/skills/local-places/SERVER_README.md +101 -0
  31. package/skills/local-places/SKILL.md +102 -0
  32. package/skills/local-places/pyproject.toml +21 -0
  33. package/skills/local-places/src/local_places/__init__.py +2 -0
  34. package/skills/local-places/src/local_places/google_places.py +314 -0
  35. package/skills/local-places/src/local_places/main.py +65 -0
  36. package/skills/local-places/src/local_places/schemas.py +107 -0
  37. package/skills/mcporter/SKILL.md +61 -0
  38. package/skills/model-usage/SKILL.md +69 -0
  39. package/skills/model-usage/references/codexbar-cli.md +33 -0
  40. package/skills/model-usage/scripts/model_usage.py +310 -0
  41. package/skills/nano-banana-pro/SKILL.md +58 -0
  42. package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
  43. package/skills/nano-pdf/SKILL.md +38 -0
  44. package/skills/notion/SKILL.md +172 -0
  45. package/skills/obsidian/SKILL.md +81 -0
  46. package/skills/openai-image-gen/SKILL.md +89 -0
  47. package/skills/openai-image-gen/scripts/gen.py +240 -0
  48. package/skills/openai-whisper/SKILL.md +38 -0
  49. package/skills/openai-whisper-api/SKILL.md +52 -0
  50. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  51. package/skills/openhue/SKILL.md +51 -0
  52. package/skills/oracle/SKILL.md +125 -0
  53. package/skills/ordercli/SKILL.md +78 -0
  54. package/skills/peekaboo/SKILL.md +190 -0
  55. package/skills/sag/SKILL.md +87 -0
  56. package/skills/security-ask-questions-if-underspecified/.claude-plugin/plugin.json +10 -0
  57. package/skills/security-ask-questions-if-underspecified/README.md +24 -0
  58. package/skills/security-ask-questions-if-underspecified/skills/ask-questions-if-underspecified/SKILL.md +85 -0
  59. package/skills/security-audit-context-building/.claude-plugin/plugin.json +10 -0
  60. package/skills/security-audit-context-building/README.md +58 -0
  61. package/skills/security-audit-context-building/commands/audit-context.md +21 -0
  62. package/skills/security-audit-context-building/skills/audit-context-building/SKILL.md +297 -0
  63. package/skills/security-audit-context-building/skills/audit-context-building/resources/COMPLETENESS_CHECKLIST.md +47 -0
  64. package/skills/security-audit-context-building/skills/audit-context-building/resources/FUNCTION_MICRO_ANALYSIS_EXAMPLE.md +355 -0
  65. package/skills/security-audit-context-building/skills/audit-context-building/resources/OUTPUT_REQUIREMENTS.md +71 -0
  66. package/skills/security-building-secure-contracts/.claude-plugin/plugin.json +10 -0
  67. package/skills/security-building-secure-contracts/README.md +241 -0
  68. package/skills/security-building-secure-contracts/skills/algorand-vulnerability-scanner/SKILL.md +284 -0
  69. package/skills/security-building-secure-contracts/skills/algorand-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +405 -0
  70. package/skills/security-building-secure-contracts/skills/audit-prep-assistant/SKILL.md +409 -0
  71. package/skills/security-building-secure-contracts/skills/cairo-vulnerability-scanner/SKILL.md +329 -0
  72. package/skills/security-building-secure-contracts/skills/cairo-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +722 -0
  73. package/skills/security-building-secure-contracts/skills/code-maturity-assessor/SKILL.md +218 -0
  74. package/skills/security-building-secure-contracts/skills/code-maturity-assessor/resources/ASSESSMENT_CRITERIA.md +355 -0
  75. package/skills/security-building-secure-contracts/skills/code-maturity-assessor/resources/EXAMPLE_REPORT.md +248 -0
  76. package/skills/security-building-secure-contracts/skills/code-maturity-assessor/resources/REPORT_FORMAT.md +33 -0
  77. package/skills/security-building-secure-contracts/skills/cosmos-vulnerability-scanner/SKILL.md +334 -0
  78. package/skills/security-building-secure-contracts/skills/cosmos-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +740 -0
  79. package/skills/security-building-secure-contracts/skills/guidelines-advisor/SKILL.md +252 -0
  80. package/skills/security-building-secure-contracts/skills/guidelines-advisor/resources/ASSESSMENT_AREAS.md +329 -0
  81. package/skills/security-building-secure-contracts/skills/guidelines-advisor/resources/DELIVERABLES.md +118 -0
  82. package/skills/security-building-secure-contracts/skills/guidelines-advisor/resources/EXAMPLE_REPORT.md +298 -0
  83. package/skills/security-building-secure-contracts/skills/secure-workflow-guide/SKILL.md +161 -0
  84. package/skills/security-building-secure-contracts/skills/secure-workflow-guide/resources/EXAMPLE_REPORT.md +279 -0
  85. package/skills/security-building-secure-contracts/skills/secure-workflow-guide/resources/WORKFLOW_STEPS.md +132 -0
  86. package/skills/security-building-secure-contracts/skills/solana-vulnerability-scanner/SKILL.md +389 -0
  87. package/skills/security-building-secure-contracts/skills/solana-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +669 -0
  88. package/skills/security-building-secure-contracts/skills/substrate-vulnerability-scanner/SKILL.md +298 -0
  89. package/skills/security-building-secure-contracts/skills/substrate-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +791 -0
  90. package/skills/security-building-secure-contracts/skills/token-integration-analyzer/SKILL.md +362 -0
  91. package/skills/security-building-secure-contracts/skills/token-integration-analyzer/resources/ASSESSMENT_CATEGORIES.md +571 -0
  92. package/skills/security-building-secure-contracts/skills/token-integration-analyzer/resources/REPORT_TEMPLATES.md +141 -0
  93. package/skills/security-building-secure-contracts/skills/ton-vulnerability-scanner/SKILL.md +388 -0
  94. package/skills/security-building-secure-contracts/skills/ton-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +595 -0
  95. package/skills/security-burpsuite-project-parser/.claude-plugin/plugin.json +10 -0
  96. package/skills/security-burpsuite-project-parser/README.md +103 -0
  97. package/skills/security-burpsuite-project-parser/commands/burp-search.md +18 -0
  98. package/skills/security-burpsuite-project-parser/skills/SKILL.md +358 -0
  99. package/skills/security-burpsuite-project-parser/skills/scripts/burp-search.sh +99 -0
  100. package/skills/security-claude-in-chrome-troubleshooting/.claude-plugin/plugin.json +8 -0
  101. package/skills/security-claude-in-chrome-troubleshooting/README.md +31 -0
  102. package/skills/security-claude-in-chrome-troubleshooting/skills/claude-in-chrome-troubleshooting/SKILL.md +251 -0
  103. package/skills/security-constant-time-analysis/.claude-plugin/plugin.json +9 -0
  104. package/skills/security-constant-time-analysis/README.md +381 -0
  105. package/skills/security-constant-time-analysis/commands/ct-check.md +20 -0
  106. package/skills/security-constant-time-analysis/ct_analyzer/__init__.py +49 -0
  107. package/skills/security-constant-time-analysis/ct_analyzer/analyzer.py +1284 -0
  108. package/skills/security-constant-time-analysis/ct_analyzer/script_analyzers.py +3081 -0
  109. package/skills/security-constant-time-analysis/ct_analyzer/tests/__init__.py +1 -0
  110. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_analyzer.py +1397 -0
  111. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/bn_excerpt.js +205 -0
  112. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/decompose_constant_time.c +181 -0
  113. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/decompose_vulnerable.c +74 -0
  114. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/decompose_vulnerable.go +78 -0
  115. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/decompose_vulnerable.rs +92 -0
  116. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.cs +174 -0
  117. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.java +161 -0
  118. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.kt +181 -0
  119. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.php +140 -0
  120. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.py +252 -0
  121. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.rb +188 -0
  122. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.swift +199 -0
  123. package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.ts +154 -0
  124. package/skills/security-constant-time-analysis/pyproject.toml +52 -0
  125. package/skills/security-constant-time-analysis/skills/constant-time-analysis/README.md +90 -0
  126. package/skills/security-constant-time-analysis/skills/constant-time-analysis/SKILL.md +219 -0
  127. package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/compiled.md +129 -0
  128. package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/javascript.md +136 -0
  129. package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/kotlin.md +252 -0
  130. package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/php.md +172 -0
  131. package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/python.md +179 -0
  132. package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/ruby.md +198 -0
  133. package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/swift.md +288 -0
  134. package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/vm-compiled.md +354 -0
  135. package/skills/security-constant-time-analysis/uv.lock +8 -0
  136. package/skills/security-culture-index/.claude-plugin/plugin.json +8 -0
  137. package/skills/security-culture-index/README.md +79 -0
  138. package/skills/security-culture-index/skills/interpreting-culture-index/SKILL.md +293 -0
  139. package/skills/security-culture-index/skills/interpreting-culture-index/references/anti-patterns.md +255 -0
  140. package/skills/security-culture-index/skills/interpreting-culture-index/references/conversation-starters.md +408 -0
  141. package/skills/security-culture-index/skills/interpreting-culture-index/references/interview-trait-signals.md +253 -0
  142. package/skills/security-culture-index/skills/interpreting-culture-index/references/motivators.md +158 -0
  143. package/skills/security-culture-index/skills/interpreting-culture-index/references/patterns-archetypes.md +147 -0
  144. package/skills/security-culture-index/skills/interpreting-culture-index/references/primary-traits.md +307 -0
  145. package/skills/security-culture-index/skills/interpreting-culture-index/references/secondary-traits.md +228 -0
  146. package/skills/security-culture-index/skills/interpreting-culture-index/references/team-composition.md +148 -0
  147. package/skills/security-culture-index/skills/interpreting-culture-index/scripts/check_deps.py +108 -0
  148. package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/__init__.py +20 -0
  149. package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/constants.py +122 -0
  150. package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/extract.py +187 -0
  151. package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/models.py +16 -0
  152. package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/opencv_extractor.py +520 -0
  153. package/skills/security-culture-index/skills/interpreting-culture-index/scripts/extract_pdf.py +237 -0
  154. package/skills/security-culture-index/skills/interpreting-culture-index/scripts/pyproject.toml +18 -0
  155. package/skills/security-culture-index/skills/interpreting-culture-index/templates/burnout-report.md +113 -0
  156. package/skills/security-culture-index/skills/interpreting-culture-index/templates/comparison-report.md +103 -0
  157. package/skills/security-culture-index/skills/interpreting-culture-index/templates/hiring-profile.md +127 -0
  158. package/skills/security-culture-index/skills/interpreting-culture-index/templates/individual-report.md +85 -0
  159. package/skills/security-culture-index/skills/interpreting-culture-index/templates/predicted-profile.md +165 -0
  160. package/skills/security-culture-index/skills/interpreting-culture-index/templates/team-report.md +109 -0
  161. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/analyze-team.md +188 -0
  162. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/coach-manager.md +267 -0
  163. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/compare-profiles.md +188 -0
  164. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/define-hiring-profile.md +220 -0
  165. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/detect-burnout.md +206 -0
  166. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/extract-from-pdf.md +121 -0
  167. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/interpret-individual.md +183 -0
  168. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/interview-debrief.md +234 -0
  169. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/mediate-conflict.md +306 -0
  170. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/plan-onboarding.md +322 -0
  171. package/skills/security-culture-index/skills/interpreting-culture-index/workflows/predict-from-interview.md +250 -0
  172. package/skills/security-differential-review/.claude-plugin/plugin.json +10 -0
  173. package/skills/security-differential-review/README.md +109 -0
  174. package/skills/security-differential-review/commands/diff-review.md +21 -0
  175. package/skills/security-differential-review/skills/differential-review/SKILL.md +220 -0
  176. package/skills/security-differential-review/skills/differential-review/adversarial.md +203 -0
  177. package/skills/security-differential-review/skills/differential-review/methodology.md +234 -0
  178. package/skills/security-differential-review/skills/differential-review/patterns.md +300 -0
  179. package/skills/security-differential-review/skills/differential-review/reporting.md +369 -0
  180. package/skills/security-dwarf-expert/.claude-plugin/plugin.json +10 -0
  181. package/skills/security-dwarf-expert/README.md +38 -0
  182. package/skills/security-dwarf-expert/skills/dwarf-expert/SKILL.md +93 -0
  183. package/skills/security-dwarf-expert/skills/dwarf-expert/reference/coding.md +31 -0
  184. package/skills/security-dwarf-expert/skills/dwarf-expert/reference/dwarfdump.md +50 -0
  185. package/skills/security-dwarf-expert/skills/dwarf-expert/reference/readelf.md +8 -0
  186. package/skills/security-entry-point-analyzer/.claude-plugin/plugin.json +10 -0
  187. package/skills/security-entry-point-analyzer/README.md +74 -0
  188. package/skills/security-entry-point-analyzer/commands/entry-points.md +18 -0
  189. package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/SKILL.md +251 -0
  190. package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/cosmwasm.md +182 -0
  191. package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/move-aptos.md +107 -0
  192. package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/move-sui.md +87 -0
  193. package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/solana.md +155 -0
  194. package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/solidity.md +135 -0
  195. package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/ton.md +185 -0
  196. package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/vyper.md +141 -0
  197. package/skills/security-firebase-apk-scanner/.claude-plugin/plugin.json +10 -0
  198. package/skills/security-firebase-apk-scanner/README.md +85 -0
  199. package/skills/security-firebase-apk-scanner/commands/scan-apk.md +18 -0
  200. package/skills/security-firebase-apk-scanner/scanner.sh +1408 -0
  201. package/skills/security-firebase-apk-scanner/skills/firebase-apk-scanner/SKILL.md +197 -0
  202. package/skills/security-firebase-apk-scanner/skills/firebase-apk-scanner/references/vulnerabilities.md +803 -0
  203. package/skills/security-fix-review/.claude-plugin/plugin.json +13 -0
  204. package/skills/security-fix-review/README.md +118 -0
  205. package/skills/security-fix-review/commands/fix-review.md +24 -0
  206. package/skills/security-fix-review/skills/fix-review/SKILL.md +264 -0
  207. package/skills/security-fix-review/skills/fix-review/references/bug-detection.md +408 -0
  208. package/skills/security-fix-review/skills/fix-review/references/finding-matching.md +298 -0
  209. package/skills/security-fix-review/skills/fix-review/references/report-parsing.md +398 -0
  210. package/skills/security-insecure-defaults/.claude-plugin/plugin.json +10 -0
  211. package/skills/security-insecure-defaults/README.md +45 -0
  212. package/skills/security-insecure-defaults/skills/insecure-defaults/SKILL.md +117 -0
  213. package/skills/security-insecure-defaults/skills/insecure-defaults/references/examples.md +409 -0
  214. package/skills/security-modern-python/.claude-plugin/plugin.json +10 -0
  215. package/skills/security-modern-python/README.md +58 -0
  216. package/skills/security-modern-python/hooks/hooks.json +16 -0
  217. package/skills/security-modern-python/hooks/intercept-legacy-python.bats +388 -0
  218. package/skills/security-modern-python/hooks/intercept-legacy-python.sh +109 -0
  219. package/skills/security-modern-python/hooks/test_helper.bash +75 -0
  220. package/skills/security-modern-python/skills/modern-python/SKILL.md +333 -0
  221. package/skills/security-modern-python/skills/modern-python/references/dependabot.md +43 -0
  222. package/skills/security-modern-python/skills/modern-python/references/migration-checklist.md +141 -0
  223. package/skills/security-modern-python/skills/modern-python/references/pep723-scripts.md +259 -0
  224. package/skills/security-modern-python/skills/modern-python/references/prek.md +211 -0
  225. package/skills/security-modern-python/skills/modern-python/references/pyproject.md +254 -0
  226. package/skills/security-modern-python/skills/modern-python/references/ruff-config.md +240 -0
  227. package/skills/security-modern-python/skills/modern-python/references/security-setup.md +255 -0
  228. package/skills/security-modern-python/skills/modern-python/references/testing.md +284 -0
  229. package/skills/security-modern-python/skills/modern-python/references/uv-commands.md +200 -0
  230. package/skills/security-modern-python/skills/modern-python/templates/dependabot.yml +36 -0
  231. package/skills/security-modern-python/skills/modern-python/templates/pre-commit-config.yaml +66 -0
  232. package/skills/security-property-based-testing/.claude-plugin/plugin.json +9 -0
  233. package/skills/security-property-based-testing/README.md +47 -0
  234. package/skills/security-property-based-testing/skills/property-based-testing/README.md +88 -0
  235. package/skills/security-property-based-testing/skills/property-based-testing/SKILL.md +109 -0
  236. package/skills/security-property-based-testing/skills/property-based-testing/references/design.md +191 -0
  237. package/skills/security-property-based-testing/skills/property-based-testing/references/generating.md +200 -0
  238. package/skills/security-property-based-testing/skills/property-based-testing/references/libraries.md +130 -0
  239. package/skills/security-property-based-testing/skills/property-based-testing/references/refactoring.md +181 -0
  240. package/skills/security-property-based-testing/skills/property-based-testing/references/reviewing.md +209 -0
  241. package/skills/security-property-based-testing/skills/property-based-testing/references/strategies.md +124 -0
  242. package/skills/semgrep-rule-creator/.claude-plugin/plugin.json +8 -0
  243. package/skills/semgrep-rule-creator/README.md +43 -0
  244. package/skills/semgrep-rule-creator/commands/semgrep-rule.md +26 -0
  245. package/skills/semgrep-rule-creator/skills/semgrep-rule-creator/SKILL.md +168 -0
  246. package/skills/semgrep-rule-creator/skills/semgrep-rule-creator/references/quick-reference.md +203 -0
  247. package/skills/semgrep-rule-creator/skills/semgrep-rule-creator/references/workflow.md +240 -0
  248. package/skills/semgrep-rule-variant-creator/.claude-plugin/plugin.json +9 -0
  249. package/skills/semgrep-rule-variant-creator/README.md +86 -0
  250. package/skills/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/SKILL.md +205 -0
  251. package/skills/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/references/applicability-analysis.md +250 -0
  252. package/skills/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/references/language-syntax-guide.md +324 -0
  253. package/skills/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/references/workflow.md +518 -0
  254. package/skills/session-logs/SKILL.md +115 -0
  255. package/skills/sharp-edges/.claude-plugin/plugin.json +10 -0
  256. package/skills/sharp-edges/README.md +48 -0
  257. package/skills/sharp-edges/skills/sharp-edges/SKILL.md +292 -0
  258. package/skills/sharp-edges/skills/sharp-edges/references/auth-patterns.md +252 -0
  259. package/skills/sharp-edges/skills/sharp-edges/references/case-studies.md +274 -0
  260. package/skills/sharp-edges/skills/sharp-edges/references/config-patterns.md +333 -0
  261. package/skills/sharp-edges/skills/sharp-edges/references/crypto-apis.md +190 -0
  262. package/skills/sharp-edges/skills/sharp-edges/references/lang-c.md +205 -0
  263. package/skills/sharp-edges/skills/sharp-edges/references/lang-csharp.md +285 -0
  264. package/skills/sharp-edges/skills/sharp-edges/references/lang-go.md +270 -0
  265. package/skills/sharp-edges/skills/sharp-edges/references/lang-java.md +263 -0
  266. package/skills/sharp-edges/skills/sharp-edges/references/lang-javascript.md +269 -0
  267. package/skills/sharp-edges/skills/sharp-edges/references/lang-kotlin.md +265 -0
  268. package/skills/sharp-edges/skills/sharp-edges/references/lang-php.md +245 -0
  269. package/skills/sharp-edges/skills/sharp-edges/references/lang-python.md +274 -0
  270. package/skills/sharp-edges/skills/sharp-edges/references/lang-ruby.md +273 -0
  271. package/skills/sharp-edges/skills/sharp-edges/references/lang-rust.md +272 -0
  272. package/skills/sharp-edges/skills/sharp-edges/references/lang-swift.md +287 -0
  273. package/skills/sharp-edges/skills/sharp-edges/references/language-specific.md +588 -0
  274. package/skills/sherpa-onnx-tts/SKILL.md +103 -0
  275. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
  276. package/skills/skill-creator/SKILL.md +370 -0
  277. package/skills/skill-creator/license.txt +202 -0
  278. package/skills/skill-creator/scripts/init_skill.py +378 -0
  279. package/skills/skill-creator/scripts/package_skill.py +111 -0
  280. package/skills/skill-creator/scripts/quick_validate.py +101 -0
  281. package/skills/slack/SKILL.md +144 -0
  282. package/skills/songsee/SKILL.md +49 -0
  283. package/skills/sonoscli/SKILL.md +46 -0
  284. package/skills/spec-to-code-compliance/.claude-plugin/plugin.json +10 -0
  285. package/skills/spec-to-code-compliance/README.md +67 -0
  286. package/skills/spec-to-code-compliance/commands/spec-compliance.md +22 -0
  287. package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/SKILL.md +349 -0
  288. package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/COMPLETENESS_CHECKLIST.md +69 -0
  289. package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/IR_EXAMPLES.md +417 -0
  290. package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/OUTPUT_REQUIREMENTS.md +105 -0
  291. package/skills/spotify-player/SKILL.md +64 -0
  292. package/skills/static-analysis/.claude-plugin/plugin.json +8 -0
  293. package/skills/static-analysis/README.md +59 -0
  294. package/skills/static-analysis/skills/codeql/SKILL.md +315 -0
  295. package/skills/static-analysis/skills/sarif-parsing/SKILL.md +479 -0
  296. package/skills/static-analysis/skills/sarif-parsing/resources/jq-queries.md +162 -0
  297. package/skills/static-analysis/skills/sarif-parsing/resources/sarif_helpers.py +331 -0
  298. package/skills/static-analysis/skills/semgrep/SKILL.md +337 -0
  299. package/skills/summarize/SKILL.md +87 -0
  300. package/skills/testing-handbook-skills/.claude-plugin/plugin.json +8 -0
  301. package/skills/testing-handbook-skills/README.md +241 -0
  302. package/skills/testing-handbook-skills/scripts/pyproject.toml +8 -0
  303. package/skills/testing-handbook-skills/scripts/validate-skills.py +657 -0
  304. package/skills/testing-handbook-skills/skills/address-sanitizer/SKILL.md +341 -0
  305. package/skills/testing-handbook-skills/skills/aflpp/SKILL.md +640 -0
  306. package/skills/testing-handbook-skills/skills/atheris/SKILL.md +515 -0
  307. package/skills/testing-handbook-skills/skills/cargo-fuzz/SKILL.md +454 -0
  308. package/skills/testing-handbook-skills/skills/codeql/SKILL.md +549 -0
  309. package/skills/testing-handbook-skills/skills/constant-time-testing/SKILL.md +507 -0
  310. package/skills/testing-handbook-skills/skills/coverage-analysis/SKILL.md +607 -0
  311. package/skills/testing-handbook-skills/skills/fuzzing-dictionary/SKILL.md +297 -0
  312. package/skills/testing-handbook-skills/skills/fuzzing-obstacles/SKILL.md +426 -0
  313. package/skills/testing-handbook-skills/skills/harness-writing/SKILL.md +614 -0
  314. package/skills/testing-handbook-skills/skills/libafl/SKILL.md +625 -0
  315. package/skills/testing-handbook-skills/skills/libfuzzer/SKILL.md +795 -0
  316. package/skills/testing-handbook-skills/skills/ossfuzz/SKILL.md +426 -0
  317. package/skills/testing-handbook-skills/skills/ruzzy/SKILL.md +443 -0
  318. package/skills/testing-handbook-skills/skills/semgrep/SKILL.md +601 -0
  319. package/skills/testing-handbook-skills/skills/testing-handbook-generator/SKILL.md +372 -0
  320. package/skills/testing-handbook-skills/skills/testing-handbook-generator/agent-prompt.md +280 -0
  321. package/skills/testing-handbook-skills/skills/testing-handbook-generator/discovery.md +452 -0
  322. package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/domain-skill.md +504 -0
  323. package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/fuzzer-skill.md +454 -0
  324. package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/technique-skill.md +527 -0
  325. package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/tool-skill.md +366 -0
  326. package/skills/testing-handbook-skills/skills/testing-handbook-generator/testing.md +482 -0
  327. package/skills/testing-handbook-skills/skills/wycheproof/SKILL.md +533 -0
  328. package/skills/things-mac/SKILL.md +86 -0
  329. package/skills/tmux/SKILL.md +135 -0
  330. package/skills/tmux/scripts/find-sessions.sh +112 -0
  331. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  332. package/skills/trello/SKILL.md +95 -0
  333. package/skills/variant-analysis/.claude-plugin/plugin.json +8 -0
  334. package/skills/variant-analysis/README.md +41 -0
  335. package/skills/variant-analysis/commands/variants.md +23 -0
  336. package/skills/variant-analysis/skills/variant-analysis/METHODOLOGY.md +327 -0
  337. package/skills/variant-analysis/skills/variant-analysis/SKILL.md +142 -0
  338. package/skills/variant-analysis/skills/variant-analysis/resources/codeql/cpp.ql +119 -0
  339. package/skills/variant-analysis/skills/variant-analysis/resources/codeql/go.ql +69 -0
  340. package/skills/variant-analysis/skills/variant-analysis/resources/codeql/java.ql +71 -0
  341. package/skills/variant-analysis/skills/variant-analysis/resources/codeql/javascript.ql +63 -0
  342. package/skills/variant-analysis/skills/variant-analysis/resources/codeql/python.ql +80 -0
  343. package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/cpp.yaml +98 -0
  344. package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/go.yaml +63 -0
  345. package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/java.yaml +61 -0
  346. package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/javascript.yaml +60 -0
  347. package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/python.yaml +72 -0
  348. package/skills/variant-analysis/skills/variant-analysis/resources/variant-report-template.md +75 -0
  349. package/skills/video-frames/SKILL.md +46 -0
  350. package/skills/video-frames/scripts/frame.sh +81 -0
  351. package/skills/voice-call/SKILL.md +45 -0
  352. package/skills/wacli/SKILL.md +72 -0
  353. package/skills/weather/SKILL.md +54 -0
  354. package/skills/yara-authoring/.claude-plugin/plugin.json +9 -0
  355. package/skills/yara-authoring/README.md +131 -0
  356. package/skills/yara-authoring/skills/yara-rule-authoring/SKILL.md +645 -0
  357. package/skills/yara-authoring/skills/yara-rule-authoring/examples/MAL_Mac_ProtonRAT_Jan25.yar +99 -0
  358. package/skills/yara-authoring/skills/yara-rule-authoring/examples/MAL_NPM_SupplyChain_Jan25.yar +170 -0
  359. package/skills/yara-authoring/skills/yara-rule-authoring/examples/MAL_Win_Remcos_Jan25.yar +103 -0
  360. package/skills/yara-authoring/skills/yara-rule-authoring/examples/SUSP_CRX_SuspiciousPermissions.yar +134 -0
  361. package/skills/yara-authoring/skills/yara-rule-authoring/examples/SUSP_JS_Obfuscation_Jan25.yar +185 -0
  362. package/skills/yara-authoring/skills/yara-rule-authoring/references/crx-module.md +214 -0
  363. package/skills/yara-authoring/skills/yara-rule-authoring/references/dex-module.md +383 -0
  364. package/skills/yara-authoring/skills/yara-rule-authoring/references/performance.md +333 -0
  365. package/skills/yara-authoring/skills/yara-rule-authoring/references/strings.md +433 -0
  366. package/skills/yara-authoring/skills/yara-rule-authoring/references/style-guide.md +257 -0
  367. package/skills/yara-authoring/skills/yara-rule-authoring/references/testing.md +399 -0
  368. package/skills/yara-authoring/skills/yara-rule-authoring/scripts/atom_analyzer.py +526 -0
  369. package/skills/yara-authoring/skills/yara-rule-authoring/scripts/pyproject.toml +25 -0
  370. package/skills/yara-authoring/skills/yara-rule-authoring/scripts/yara_lint.py +631 -0
  371. package/skills/yara-authoring/skills/yara-rule-authoring/workflows/rule-development.md +493 -0
@@ -0,0 +1,1284 @@
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # requires-python = ">=3.10"
4
+ # ///
5
+ """
6
+ ct_analyzer - Constant-Time Assembly Analyzer
7
+
8
+ A portable tool for detecting timing side-channel vulnerabilities in compiled
9
+ cryptographic code by analyzing assembly output for variable-time instructions.
10
+
11
+ This tool analyzes assembly from multiple compilers (gcc, clang, go, rustc)
12
+ across multiple architectures (x86_64, arm64, arm, riscv64, etc.) to detect
13
+ instructions that could leak timing information about secret data.
14
+
15
+ Usage:
16
+ python ct_analyzer/analyzer.py [options] <source_file>
17
+
18
+ Examples:
19
+ # Analyze a C file with default settings (clang, native arch)
20
+ python ct_analyzer/analyzer.py crypto.c
21
+
22
+ # Analyze with specific compiler and optimization level
23
+ python ct_analyzer/analyzer.py --compiler gcc --opt-level O2 crypto.c
24
+
25
+ # Analyze a Go file for arm64
26
+ python ct_analyzer/analyzer.py --arch arm64 crypto.go
27
+
28
+ # Analyze with warnings enabled (shows conditional branches)
29
+ python ct_analyzer/analyzer.py --warnings crypto.c
30
+ """
31
+
32
+ import argparse
33
+ import json
34
+ import os
35
+ import re
36
+ import subprocess
37
+ import sys
38
+ import tempfile
39
+ from dataclasses import dataclass, field
40
+ from enum import Enum
41
+ from pathlib import Path
42
+
43
+
44
+ class Severity(Enum):
45
+ ERROR = "error"
46
+ WARNING = "warning"
47
+
48
+
49
+ class OutputFormat(Enum):
50
+ TEXT = "text"
51
+ JSON = "json"
52
+ GITHUB = "github"
53
+
54
+
55
+ @dataclass
56
+ class Violation:
57
+ """A detected constant-time violation."""
58
+
59
+ function: str
60
+ file: str
61
+ line: int | None
62
+ address: str
63
+ instruction: str
64
+ mnemonic: str
65
+ reason: str
66
+ severity: Severity
67
+
68
+
69
+ @dataclass
70
+ class AnalysisReport:
71
+ """Report from analyzing a compiled binary."""
72
+
73
+ architecture: str
74
+ compiler: str
75
+ optimization: str
76
+ source_file: str
77
+ total_functions: int
78
+ total_instructions: int
79
+ violations: list[Violation] = field(default_factory=list)
80
+
81
+ @property
82
+ def error_count(self) -> int:
83
+ return sum(1 for v in self.violations if v.severity == Severity.ERROR)
84
+
85
+ @property
86
+ def warning_count(self) -> int:
87
+ return sum(1 for v in self.violations if v.severity == Severity.WARNING)
88
+
89
+ @property
90
+ def passed(self) -> bool:
91
+ return self.error_count == 0
92
+
93
+
94
+ # Architecture-specific dangerous instructions
95
+ # Based on research from Trail of Bits and the cryptocoding guidelines
96
+
97
+ DANGEROUS_INSTRUCTIONS = {
98
+ # x86_64 / amd64
99
+ "x86_64": {
100
+ "errors": {
101
+ # Integer division - variable time based on operand values (KyberSlash attack vector)
102
+ "div": "DIV has data-dependent timing; execution time varies based on operand values",
103
+ "idiv": "IDIV has data-dependent timing; execution time varies based on operand values",
104
+ "divb": "DIVB has data-dependent timing; execution time varies based on operand values",
105
+ "divw": "DIVW has data-dependent timing; execution time varies based on operand values",
106
+ "divl": "DIVL has data-dependent timing; execution time varies based on operand values",
107
+ "divq": "DIVQ has data-dependent timing; execution time varies based on operand values",
108
+ "idivb": "IDIVB has data-dependent timing; execution time varies based on operand values",
109
+ "idivw": "IDIVW has data-dependent timing; execution time varies based on operand values",
110
+ "idivl": "IDIVL has data-dependent timing; execution time varies based on operand values",
111
+ "idivq": "IDIVQ has data-dependent timing; execution time varies based on operand values",
112
+ # Floating-point division - variable latency
113
+ "divss": "DIVSS (scalar single FP division) has variable latency",
114
+ "divsd": "DIVSD (scalar double FP division) has variable latency",
115
+ "divps": "DIVPS (packed single FP division) has variable latency",
116
+ "divpd": "DIVPD (packed double FP division) has variable latency",
117
+ "vdivss": "VDIVSS (AVX scalar single FP division) has variable latency",
118
+ "vdivsd": "VDIVSD (AVX scalar double FP division) has variable latency",
119
+ "vdivps": "VDIVPS (AVX packed single FP division) has variable latency",
120
+ "vdivpd": "VDIVPD (AVX packed double FP division) has variable latency",
121
+ # Square root - variable latency
122
+ "sqrtss": "SQRTSS has variable latency based on operand values",
123
+ "sqrtsd": "SQRTSD has variable latency based on operand values",
124
+ "sqrtps": "SQRTPS has variable latency based on operand values",
125
+ "sqrtpd": "SQRTPD has variable latency based on operand values",
126
+ "vsqrtss": "VSQRTSS has variable latency based on operand values",
127
+ "vsqrtsd": "VSQRTSD has variable latency based on operand values",
128
+ "vsqrtps": "VSQRTPS has variable latency based on operand values",
129
+ "vsqrtpd": "VSQRTPD has variable latency based on operand values",
130
+ },
131
+ "warnings": {
132
+ # Conditional branches - may leak timing if condition depends on secret data
133
+ "je": "conditional branch may leak timing information if condition depends on secret data",
134
+ "jne": "conditional branch may leak timing information if condition depends on secret data",
135
+ "jz": "conditional branch may leak timing information if condition depends on secret data",
136
+ "jnz": "conditional branch may leak timing information if condition depends on secret data",
137
+ "ja": "conditional branch may leak timing information if condition depends on secret data",
138
+ "jae": "conditional branch may leak timing information if condition depends on secret data",
139
+ "jb": "conditional branch may leak timing information if condition depends on secret data",
140
+ "jbe": "conditional branch may leak timing information if condition depends on secret data",
141
+ "jg": "conditional branch may leak timing information if condition depends on secret data",
142
+ "jge": "conditional branch may leak timing information if condition depends on secret data",
143
+ "jl": "conditional branch may leak timing information if condition depends on secret data",
144
+ "jle": "conditional branch may leak timing information if condition depends on secret data",
145
+ "jo": "conditional branch may leak timing information if condition depends on secret data",
146
+ "jno": "conditional branch may leak timing information if condition depends on secret data",
147
+ "js": "conditional branch may leak timing information if condition depends on secret data",
148
+ "jns": "conditional branch may leak timing information if condition depends on secret data",
149
+ "jp": "conditional branch may leak timing information if condition depends on secret data",
150
+ "jnp": "conditional branch may leak timing information if condition depends on secret data",
151
+ "jc": "conditional branch may leak timing information if condition depends on secret data",
152
+ "jnc": "conditional branch may leak timing information if condition depends on secret data",
153
+ },
154
+ },
155
+ # ARM64 / AArch64
156
+ "arm64": {
157
+ "errors": {
158
+ # Division - early termination optimization makes these variable-time
159
+ # Note: Even with DIT (Data Independent Timing) enabled, division is NOT constant-time
160
+ "udiv": "UDIV has early termination optimization; execution time depends on operand values",
161
+ "sdiv": "SDIV has early termination optimization; execution time depends on operand values",
162
+ # Floating-point division
163
+ "fdiv": "FDIV (FP division) has variable latency based on operand values",
164
+ # Square root
165
+ "fsqrt": "FSQRT has variable latency based on operand values",
166
+ },
167
+ "warnings": {
168
+ # Conditional branches
169
+ "b.eq": "conditional branch may leak timing information if condition depends on secret data",
170
+ "b.ne": "conditional branch may leak timing information if condition depends on secret data",
171
+ "b.cs": "conditional branch may leak timing information if condition depends on secret data",
172
+ "b.cc": "conditional branch may leak timing information if condition depends on secret data",
173
+ "b.mi": "conditional branch may leak timing information if condition depends on secret data",
174
+ "b.pl": "conditional branch may leak timing information if condition depends on secret data",
175
+ "b.vs": "conditional branch may leak timing information if condition depends on secret data",
176
+ "b.vc": "conditional branch may leak timing information if condition depends on secret data",
177
+ "b.hi": "conditional branch may leak timing information if condition depends on secret data",
178
+ "b.ls": "conditional branch may leak timing information if condition depends on secret data",
179
+ "b.ge": "conditional branch may leak timing information if condition depends on secret data",
180
+ "b.lt": "conditional branch may leak timing information if condition depends on secret data",
181
+ "b.gt": "conditional branch may leak timing information if condition depends on secret data",
182
+ "b.le": "conditional branch may leak timing information if condition depends on secret data",
183
+ "beq": "conditional branch may leak timing information if condition depends on secret data",
184
+ "bne": "conditional branch may leak timing information if condition depends on secret data",
185
+ "bcs": "conditional branch may leak timing information if condition depends on secret data",
186
+ "bcc": "conditional branch may leak timing information if condition depends on secret data",
187
+ "bmi": "conditional branch may leak timing information if condition depends on secret data",
188
+ "bpl": "conditional branch may leak timing information if condition depends on secret data",
189
+ "bvs": "conditional branch may leak timing information if condition depends on secret data",
190
+ "bvc": "conditional branch may leak timing information if condition depends on secret data",
191
+ "bhi": "conditional branch may leak timing information if condition depends on secret data",
192
+ "bls": "conditional branch may leak timing information if condition depends on secret data",
193
+ "bge": "conditional branch may leak timing information if condition depends on secret data",
194
+ "blt": "conditional branch may leak timing information if condition depends on secret data",
195
+ "bgt": "conditional branch may leak timing information if condition depends on secret data",
196
+ "ble": "conditional branch may leak timing information if condition depends on secret data",
197
+ # Compare and branch
198
+ "cbz": "compare-and-branch may leak timing information if value depends on secret data",
199
+ "cbnz": "compare-and-branch may leak timing information if value depends on secret data",
200
+ "tbz": "test-bit-and-branch may leak timing information if value depends on secret data",
201
+ "tbnz": "test-bit-and-branch may leak timing information if value depends on secret data",
202
+ },
203
+ },
204
+ # ARM 32-bit
205
+ "arm": {
206
+ "errors": {
207
+ "udiv": "UDIV has early termination optimization; execution time depends on operand values",
208
+ "sdiv": "SDIV has early termination optimization; execution time depends on operand values",
209
+ "vdiv.f32": "VDIV.F32 has variable latency",
210
+ "vdiv.f64": "VDIV.F64 has variable latency",
211
+ "vsqrt.f32": "VSQRT.F32 has variable latency",
212
+ "vsqrt.f64": "VSQRT.F64 has variable latency",
213
+ },
214
+ "warnings": {
215
+ "beq": "conditional branch may leak timing information if condition depends on secret data",
216
+ "bne": "conditional branch may leak timing information if condition depends on secret data",
217
+ "bcs": "conditional branch may leak timing information if condition depends on secret data",
218
+ "bcc": "conditional branch may leak timing information if condition depends on secret data",
219
+ "bmi": "conditional branch may leak timing information if condition depends on secret data",
220
+ "bpl": "conditional branch may leak timing information if condition depends on secret data",
221
+ "bvs": "conditional branch may leak timing information if condition depends on secret data",
222
+ "bvc": "conditional branch may leak timing information if condition depends on secret data",
223
+ "bhi": "conditional branch may leak timing information if condition depends on secret data",
224
+ "bls": "conditional branch may leak timing information if condition depends on secret data",
225
+ "bge": "conditional branch may leak timing information if condition depends on secret data",
226
+ "blt": "conditional branch may leak timing information if condition depends on secret data",
227
+ "bgt": "conditional branch may leak timing information if condition depends on secret data",
228
+ "ble": "conditional branch may leak timing information if condition depends on secret data",
229
+ },
230
+ },
231
+ # RISC-V 64-bit
232
+ "riscv64": {
233
+ "errors": {
234
+ "div": "DIV has variable-time execution based on operand values",
235
+ "divu": "DIVU has variable-time execution based on operand values",
236
+ "divw": "DIVW has variable-time execution based on operand values",
237
+ "divuw": "DIVUW has variable-time execution based on operand values",
238
+ "rem": "REM has variable-time execution based on operand values",
239
+ "remu": "REMU has variable-time execution based on operand values",
240
+ "remw": "REMW has variable-time execution based on operand values",
241
+ "remuw": "REMUW has variable-time execution based on operand values",
242
+ "fdiv.s": "FDIV.S has variable latency",
243
+ "fdiv.d": "FDIV.D has variable latency",
244
+ "fsqrt.s": "FSQRT.S has variable latency",
245
+ "fsqrt.d": "FSQRT.D has variable latency",
246
+ },
247
+ "warnings": {
248
+ "beq": "conditional branch may leak timing information if condition depends on secret data",
249
+ "bne": "conditional branch may leak timing information if condition depends on secret data",
250
+ "blt": "conditional branch may leak timing information if condition depends on secret data",
251
+ "bge": "conditional branch may leak timing information if condition depends on secret data",
252
+ "bltu": "conditional branch may leak timing information if condition depends on secret data",
253
+ "bgeu": "conditional branch may leak timing information if condition depends on secret data",
254
+ },
255
+ },
256
+ # PowerPC 64-bit Little Endian
257
+ "ppc64le": {
258
+ "errors": {
259
+ "divw": "DIVW has variable-time execution",
260
+ "divwu": "DIVWU has variable-time execution",
261
+ "divd": "DIVD has variable-time execution",
262
+ "divdu": "DIVDU has variable-time execution",
263
+ "divwe": "DIVWE has variable-time execution",
264
+ "divweu": "DIVWEU has variable-time execution",
265
+ "divde": "DIVDE has variable-time execution",
266
+ "divdeu": "DIVDEU has variable-time execution",
267
+ "fdiv": "FDIV has variable latency",
268
+ "fdivs": "FDIVS has variable latency",
269
+ "fsqrt": "FSQRT has variable latency",
270
+ "fsqrts": "FSQRTS has variable latency",
271
+ },
272
+ "warnings": {
273
+ "beq": "conditional branch may leak timing information if condition depends on secret data",
274
+ "bne": "conditional branch may leak timing information if condition depends on secret data",
275
+ "blt": "conditional branch may leak timing information if condition depends on secret data",
276
+ "bge": "conditional branch may leak timing information if condition depends on secret data",
277
+ "bgt": "conditional branch may leak timing information if condition depends on secret data",
278
+ "ble": "conditional branch may leak timing information if condition depends on secret data",
279
+ },
280
+ },
281
+ # IBM z/Architecture (s390x)
282
+ "s390x": {
283
+ "errors": {
284
+ "d": "D (divide) has variable-time execution",
285
+ "dr": "DR (divide register) has variable-time execution",
286
+ "dl": "DL (divide logical) has variable-time execution",
287
+ "dlr": "DLR (divide logical register) has variable-time execution",
288
+ "dlg": "DLG (divide logical 64-bit) has variable-time execution",
289
+ "dlgr": "DLGR (divide logical register 64-bit) has variable-time execution",
290
+ "dsg": "DSG (divide single 64-bit) has variable-time execution",
291
+ "dsgr": "DSGR (divide single register 64-bit) has variable-time execution",
292
+ "dsgf": "DSGF (divide single 64x32) has variable-time execution",
293
+ "dsgfr": "DSGFR (divide single register 64x32) has variable-time execution",
294
+ "ddb": "DDB (divide FP) has variable latency",
295
+ "ddbr": "DDBR (divide FP register) has variable latency",
296
+ "sqdb": "SQDB (square root FP) has variable latency",
297
+ "sqdbr": "SQDBR (square root FP register) has variable latency",
298
+ },
299
+ "warnings": {
300
+ "je": "conditional branch may leak timing information if condition depends on secret data",
301
+ "jne": "conditional branch may leak timing information if condition depends on secret data",
302
+ "jh": "conditional branch may leak timing information if condition depends on secret data",
303
+ "jl": "conditional branch may leak timing information if condition depends on secret data",
304
+ "jhe": "conditional branch may leak timing information if condition depends on secret data",
305
+ "jle": "conditional branch may leak timing information if condition depends on secret data",
306
+ "jo": "conditional branch may leak timing information if condition depends on secret data",
307
+ "jno": "conditional branch may leak timing information if condition depends on secret data",
308
+ "jp": "conditional branch may leak timing information if condition depends on secret data",
309
+ "jnp": "conditional branch may leak timing information if condition depends on secret data",
310
+ "jm": "conditional branch may leak timing information if condition depends on secret data",
311
+ "jnm": "conditional branch may leak timing information if condition depends on secret data",
312
+ "jz": "conditional branch may leak timing information if condition depends on secret data",
313
+ "jnz": "conditional branch may leak timing information if condition depends on secret data",
314
+ },
315
+ },
316
+ # i386 / x86 32-bit
317
+ "i386": {
318
+ "errors": {
319
+ "div": "DIV has data-dependent timing; execution time varies based on operand values",
320
+ "idiv": "IDIV has data-dependent timing; execution time varies based on operand values",
321
+ "divb": "DIVB has data-dependent timing",
322
+ "divw": "DIVW has data-dependent timing",
323
+ "divl": "DIVL has data-dependent timing",
324
+ "idivb": "IDIVB has data-dependent timing",
325
+ "idivw": "IDIVW has data-dependent timing",
326
+ "idivl": "IDIVL has data-dependent timing",
327
+ "fdiv": "FDIV has variable latency",
328
+ "fdivp": "FDIVP has variable latency",
329
+ "fidiv": "FIDIV has variable latency",
330
+ "fdivr": "FDIVR has variable latency",
331
+ "fdivrp": "FDIVRP has variable latency",
332
+ "fidivr": "FIDIVR has variable latency",
333
+ "fsqrt": "FSQRT has variable latency",
334
+ },
335
+ "warnings": {
336
+ "je": "conditional branch may leak timing information if condition depends on secret data",
337
+ "jne": "conditional branch may leak timing information if condition depends on secret data",
338
+ "jz": "conditional branch may leak timing information if condition depends on secret data",
339
+ "jnz": "conditional branch may leak timing information if condition depends on secret data",
340
+ "ja": "conditional branch may leak timing information if condition depends on secret data",
341
+ "jae": "conditional branch may leak timing information if condition depends on secret data",
342
+ "jb": "conditional branch may leak timing information if condition depends on secret data",
343
+ "jbe": "conditional branch may leak timing information if condition depends on secret data",
344
+ "jg": "conditional branch may leak timing information if condition depends on secret data",
345
+ "jge": "conditional branch may leak timing information if condition depends on secret data",
346
+ "jl": "conditional branch may leak timing information if condition depends on secret data",
347
+ "jle": "conditional branch may leak timing information if condition depends on secret data",
348
+ },
349
+ },
350
+ }
351
+
352
+ # Architecture aliases
353
+ ARCH_ALIASES = {
354
+ "amd64": "x86_64",
355
+ "x64": "x86_64",
356
+ "aarch64": "arm64",
357
+ "armv7": "arm",
358
+ "armhf": "arm",
359
+ "386": "i386",
360
+ "x86": "i386",
361
+ "ppc64": "ppc64le",
362
+ "riscv": "riscv64",
363
+ }
364
+
365
+
366
+ def normalize_arch(arch: str) -> str:
367
+ """Normalize architecture name to canonical form."""
368
+ arch = arch.lower()
369
+ return ARCH_ALIASES.get(arch, arch)
370
+
371
+
372
+ def get_native_arch() -> str:
373
+ """Get the native architecture of the current system."""
374
+ import platform
375
+
376
+ machine = platform.machine().lower()
377
+ return normalize_arch(machine)
378
+
379
+
380
+ def detect_language(source_file: str) -> str:
381
+ """Detect the programming language from file extension."""
382
+ ext = Path(source_file).suffix.lower()
383
+ language_map = {
384
+ ".c": "c",
385
+ ".h": "c",
386
+ ".cc": "cpp",
387
+ ".cpp": "cpp",
388
+ ".cxx": "cpp",
389
+ ".hpp": "cpp",
390
+ ".hxx": "cpp",
391
+ ".go": "go",
392
+ ".rs": "rust",
393
+ # VM-compiled languages (bytecode analysis)
394
+ ".java": "java",
395
+ ".cs": "csharp",
396
+ # Scripting languages
397
+ ".php": "php",
398
+ ".js": "javascript",
399
+ ".mjs": "javascript",
400
+ ".cjs": "javascript",
401
+ ".ts": "typescript",
402
+ ".tsx": "typescript",
403
+ ".mts": "typescript",
404
+ ".py": "python",
405
+ ".pyw": "python",
406
+ ".rb": "ruby",
407
+ # Kotlin (JVM bytecode)
408
+ ".kt": "kotlin",
409
+ ".kts": "kotlin",
410
+ # Swift (native compiled)
411
+ ".swift": "swift",
412
+ }
413
+ return language_map.get(ext, "unknown")
414
+
415
+
416
+ def is_bytecode_language(language: str) -> bool:
417
+ """Check if the language is analyzed via bytecode (scripting and VM-compiled)."""
418
+ return language in (
419
+ "php",
420
+ "javascript",
421
+ "typescript",
422
+ "python",
423
+ "ruby", # Scripting
424
+ "java",
425
+ "csharp",
426
+ "kotlin", # VM-compiled (JVM/CIL)
427
+ )
428
+
429
+
430
+ # Backward compatibility alias
431
+ is_scripting_language = is_bytecode_language
432
+
433
+
434
+ class Compiler:
435
+ """Base class for compiler interfaces."""
436
+
437
+ def __init__(self, name: str, path: str | None = None):
438
+ self.name = name
439
+ self.path = path or name
440
+
441
+ def compile_to_assembly(
442
+ self,
443
+ source_file: str,
444
+ output_file: str,
445
+ arch: str,
446
+ optimization: str,
447
+ extra_flags: list[str] = None,
448
+ ) -> tuple[bool, str]:
449
+ """Compile source to assembly. Returns (success, error_message)."""
450
+ raise NotImplementedError
451
+
452
+ def is_available(self) -> bool:
453
+ """Check if the compiler is available on the system."""
454
+ try:
455
+ subprocess.run(
456
+ [self.path, "--version"],
457
+ capture_output=True,
458
+ check=True,
459
+ )
460
+ return True
461
+ except (subprocess.CalledProcessError, FileNotFoundError):
462
+ return False
463
+
464
+
465
+ class GCCCompiler(Compiler):
466
+ """GCC compiler interface."""
467
+
468
+ ARCH_FLAGS = {
469
+ "x86_64": ["-m64"],
470
+ "i386": ["-m32"],
471
+ "arm64": ["-march=armv8-a"],
472
+ "arm": ["-march=armv7-a", "-mfloat-abi=hard"],
473
+ "riscv64": ["-march=rv64gc", "-mabi=lp64d"],
474
+ "ppc64le": ["-mcpu=power8", "-mlittle-endian"],
475
+ "s390x": ["-march=z13"],
476
+ }
477
+
478
+ def __init__(self, path: str | None = None):
479
+ super().__init__("gcc", path or "gcc")
480
+
481
+ def compile_to_assembly(
482
+ self,
483
+ source_file: str,
484
+ output_file: str,
485
+ arch: str,
486
+ optimization: str,
487
+ extra_flags: list[str] = None,
488
+ ) -> tuple[bool, str]:
489
+ arch = normalize_arch(arch)
490
+ arch_flags = self.ARCH_FLAGS.get(arch, [])
491
+
492
+ cmd = [
493
+ self.path,
494
+ f"-{optimization}",
495
+ "-S", # Generate assembly
496
+ "-fno-asynchronous-unwind-tables", # Cleaner output
497
+ "-fno-dwarf2-cfi-asm", # Cleaner output
498
+ *arch_flags,
499
+ *(extra_flags or []),
500
+ source_file,
501
+ "-o",
502
+ output_file,
503
+ ]
504
+
505
+ try:
506
+ result = subprocess.run(cmd, capture_output=True, text=True)
507
+ if result.returncode != 0:
508
+ return False, result.stderr
509
+ return True, ""
510
+ except FileNotFoundError:
511
+ return False, f"Compiler not found: {self.path}"
512
+
513
+
514
+ class ClangCompiler(Compiler):
515
+ """Clang compiler interface."""
516
+
517
+ ARCH_TARGETS = {
518
+ "x86_64": "x86_64-unknown-linux-gnu",
519
+ "i386": "i386-unknown-linux-gnu",
520
+ "arm64": "aarch64-unknown-linux-gnu",
521
+ "arm": "armv7-unknown-linux-gnueabihf",
522
+ "riscv64": "riscv64-unknown-linux-gnu",
523
+ "ppc64le": "powerpc64le-unknown-linux-gnu",
524
+ "s390x": "s390x-unknown-linux-gnu",
525
+ }
526
+
527
+ def __init__(self, path: str | None = None):
528
+ super().__init__("clang", path or "clang")
529
+
530
+ def compile_to_assembly(
531
+ self,
532
+ source_file: str,
533
+ output_file: str,
534
+ arch: str,
535
+ optimization: str,
536
+ extra_flags: list[str] = None,
537
+ ) -> tuple[bool, str]:
538
+ arch = normalize_arch(arch)
539
+ target = self.ARCH_TARGETS.get(arch)
540
+
541
+ cmd = [
542
+ self.path,
543
+ f"-{optimization}",
544
+ "-S", # Generate assembly
545
+ "-fno-asynchronous-unwind-tables",
546
+ *(["--target=" + target] if target else []),
547
+ *(extra_flags or []),
548
+ source_file,
549
+ "-o",
550
+ output_file,
551
+ ]
552
+
553
+ try:
554
+ result = subprocess.run(cmd, capture_output=True, text=True)
555
+ if result.returncode != 0:
556
+ return False, result.stderr
557
+ return True, ""
558
+ except FileNotFoundError:
559
+ return False, f"Compiler not found: {self.path}"
560
+
561
+
562
+ class GoCompiler(Compiler):
563
+ """Go compiler interface."""
564
+
565
+ ARCH_MAP = {
566
+ "x86_64": "amd64",
567
+ "i386": "386",
568
+ "arm64": "arm64",
569
+ "arm": "arm",
570
+ "riscv64": "riscv64",
571
+ "ppc64le": "ppc64le",
572
+ "s390x": "s390x",
573
+ }
574
+
575
+ def __init__(self, path: str | None = None):
576
+ super().__init__("go", path or "go")
577
+
578
+ def is_available(self) -> bool:
579
+ try:
580
+ subprocess.run(
581
+ [self.path, "version"],
582
+ capture_output=True,
583
+ check=True,
584
+ )
585
+ return True
586
+ except (subprocess.CalledProcessError, FileNotFoundError):
587
+ return False
588
+
589
+ def compile_to_assembly(
590
+ self,
591
+ source_file: str,
592
+ output_file: str,
593
+ arch: str,
594
+ optimization: str,
595
+ extra_flags: list[str] = None,
596
+ ) -> tuple[bool, str]:
597
+ arch = normalize_arch(arch)
598
+ goarch = self.ARCH_MAP.get(arch, arch)
599
+
600
+ # For Go, we need to build a binary and then disassemble it
601
+ with tempfile.TemporaryDirectory() as tmpdir:
602
+ binary_path = os.path.join(tmpdir, "binary")
603
+
604
+ env = os.environ.copy()
605
+ env["GOOS"] = "linux"
606
+ env["GOARCH"] = goarch
607
+ env["CGO_ENABLED"] = "0"
608
+
609
+ # Build command - use gcflags to control optimization
610
+ gcflags = ""
611
+ if optimization == "O0":
612
+ gcflags = "-N -l" # Disable optimizations and inlining
613
+
614
+ cmd = [
615
+ self.path,
616
+ "build",
617
+ "-o",
618
+ binary_path,
619
+ ]
620
+ if gcflags:
621
+ cmd.extend(["-gcflags", gcflags])
622
+ cmd.append(source_file)
623
+
624
+ try:
625
+ result = subprocess.run(cmd, capture_output=True, text=True, env=env)
626
+ if result.returncode != 0:
627
+ return False, result.stderr
628
+
629
+ # Now disassemble
630
+ disasm_cmd = [self.path, "tool", "objdump", binary_path]
631
+ result = subprocess.run(disasm_cmd, capture_output=True, text=True)
632
+ if result.returncode != 0:
633
+ return False, result.stderr
634
+
635
+ with open(output_file, "w") as f:
636
+ f.write(result.stdout)
637
+
638
+ return True, ""
639
+ except FileNotFoundError:
640
+ return False, f"Go not found: {self.path}"
641
+
642
+
643
+ class RustCompiler(Compiler):
644
+ """Rust compiler interface."""
645
+
646
+ ARCH_TARGETS = {
647
+ "x86_64": "x86_64-unknown-linux-gnu",
648
+ "i386": "i686-unknown-linux-gnu",
649
+ "arm64": "aarch64-unknown-linux-gnu",
650
+ "arm": "armv7-unknown-linux-gnueabihf",
651
+ "riscv64": "riscv64gc-unknown-linux-gnu",
652
+ "ppc64le": "powerpc64le-unknown-linux-gnu",
653
+ "s390x": "s390x-unknown-linux-gnu",
654
+ }
655
+
656
+ def __init__(self, path: str | None = None):
657
+ super().__init__("rustc", path or "rustc")
658
+
659
+ def compile_to_assembly(
660
+ self,
661
+ source_file: str,
662
+ output_file: str,
663
+ arch: str,
664
+ optimization: str,
665
+ extra_flags: list[str] = None,
666
+ ) -> tuple[bool, str]:
667
+ arch = normalize_arch(arch)
668
+ target = self.ARCH_TARGETS.get(arch)
669
+
670
+ opt_level = {
671
+ "O0": "0",
672
+ "O1": "1",
673
+ "O2": "2",
674
+ "O3": "3",
675
+ "Os": "s",
676
+ "Oz": "z",
677
+ }.get(optimization, "2")
678
+
679
+ cmd = [
680
+ self.path,
681
+ "--emit=asm",
682
+ "-C",
683
+ f"opt-level={opt_level}",
684
+ *(["--target", target] if target else []),
685
+ *(extra_flags or []),
686
+ source_file,
687
+ "-o",
688
+ output_file,
689
+ ]
690
+
691
+ try:
692
+ result = subprocess.run(cmd, capture_output=True, text=True)
693
+ if result.returncode != 0:
694
+ return False, result.stderr
695
+ return True, ""
696
+ except FileNotFoundError:
697
+ return False, f"Rustc not found: {self.path}"
698
+
699
+
700
+ class SwiftCompiler(Compiler):
701
+ """Swift compiler interface for iOS/macOS development."""
702
+
703
+ ARCH_TARGETS = {
704
+ "x86_64": "x86_64-apple-macosx10.15",
705
+ "arm64": "arm64-apple-macosx11.0",
706
+ # iOS targets
707
+ "arm64-ios": "arm64-apple-ios13.0",
708
+ "arm64-ios-sim": "arm64-apple-ios13.0-simulator",
709
+ "x86_64-ios-sim": "x86_64-apple-ios13.0-simulator",
710
+ }
711
+
712
+ def __init__(self, path: str | None = None):
713
+ super().__init__("swiftc", path or "swiftc")
714
+
715
+ def compile_to_assembly(
716
+ self,
717
+ source_file: str,
718
+ output_file: str,
719
+ arch: str,
720
+ optimization: str,
721
+ extra_flags: list[str] = None,
722
+ ) -> tuple[bool, str]:
723
+ arch = normalize_arch(arch)
724
+ target = self.ARCH_TARGETS.get(arch)
725
+
726
+ opt_level = {
727
+ "O0": "-Onone",
728
+ "O1": "-O",
729
+ "O2": "-O",
730
+ "O3": "-O",
731
+ "Os": "-Osize",
732
+ "Oz": "-Osize",
733
+ }.get(optimization, "-O")
734
+
735
+ cmd = [
736
+ self.path,
737
+ "-emit-assembly",
738
+ opt_level,
739
+ *(["-target", target] if target else []),
740
+ *(extra_flags or []),
741
+ source_file,
742
+ "-o",
743
+ output_file,
744
+ ]
745
+
746
+ try:
747
+ result = subprocess.run(cmd, capture_output=True, text=True)
748
+ if result.returncode != 0:
749
+ return False, result.stderr
750
+ return True, ""
751
+ except FileNotFoundError:
752
+ return False, f"Swift compiler not found: {self.path}"
753
+
754
+
755
+ def get_compiler(name: str, language: str) -> Compiler:
756
+ """Get a compiler instance by name or detect from language."""
757
+ compilers = {
758
+ "gcc": GCCCompiler,
759
+ "clang": ClangCompiler,
760
+ "go": GoCompiler,
761
+ "rustc": RustCompiler,
762
+ "swiftc": SwiftCompiler,
763
+ }
764
+
765
+ if name:
766
+ if name in compilers:
767
+ return compilers[name]()
768
+ # Assume it's a path to a compiler
769
+ return ClangCompiler(name)
770
+
771
+ # Auto-detect based on language
772
+ if language == "go":
773
+ return GoCompiler()
774
+ elif language == "rust":
775
+ return RustCompiler()
776
+ elif language == "swift":
777
+ return SwiftCompiler()
778
+ else:
779
+ # Default to clang for C/C++
780
+ return ClangCompiler()
781
+
782
+
783
+ class AssemblyParser:
784
+ """Parser for assembly output from various compilers."""
785
+
786
+ def __init__(self, arch: str, compiler: str):
787
+ self.arch = normalize_arch(arch)
788
+ self.compiler = compiler
789
+
790
+ # Get dangerous instructions for this architecture
791
+ if self.arch not in DANGEROUS_INSTRUCTIONS:
792
+ print(
793
+ f"Warning: Architecture '{self.arch}' is not supported. "
794
+ f"Supported architectures: {', '.join(DANGEROUS_INSTRUCTIONS.keys())}. "
795
+ "No timing violations will be detected.",
796
+ file=sys.stderr,
797
+ )
798
+ self.errors = {}
799
+ self.warnings = {}
800
+ else:
801
+ arch_instructions = DANGEROUS_INSTRUCTIONS[self.arch]
802
+ self.errors = arch_instructions.get("errors", {})
803
+ self.warnings = arch_instructions.get("warnings", {})
804
+
805
+ def parse(
806
+ self, assembly_text: str, include_warnings: bool = False
807
+ ) -> tuple[list[dict], list[Violation]]:
808
+ """
809
+ Parse assembly text and detect violations.
810
+ Returns (functions, violations).
811
+ """
812
+ functions = []
813
+ violations = []
814
+
815
+ current_function = None
816
+ current_file = None
817
+ current_line = None
818
+ instruction_count = 0
819
+
820
+ for line in assembly_text.split("\n"):
821
+ line = line.strip()
822
+
823
+ # Skip empty lines and comments
824
+ if not line or line.startswith("#") or line.startswith("//") or line.startswith(";"):
825
+ # Check for file/line info in comments
826
+ file_match = re.search(r"#\s*([^:]+):(\d+)", line)
827
+ if file_match:
828
+ current_file = file_match.group(1)
829
+ current_line = int(file_match.group(2))
830
+ continue
831
+
832
+ # Detect function start (various formats)
833
+ func_match = (
834
+ # GCC/Clang: function_name:
835
+ re.match(r"^([a-zA-Z_][a-zA-Z0-9_]*):$", line)
836
+ or
837
+ # Go objdump: TEXT symbol_name(SB) file
838
+ re.match(r"^TEXT\s+([^\s(]+)\(SB\)", line)
839
+ or
840
+ # With .type directive
841
+ re.match(r"\.type\s+([a-zA-Z_][a-zA-Z0-9_]*),\s*@function", line)
842
+ )
843
+
844
+ if func_match:
845
+ if current_function:
846
+ functions.append(
847
+ {
848
+ "name": current_function,
849
+ "instructions": instruction_count,
850
+ }
851
+ )
852
+ current_function = func_match.group(1)
853
+ instruction_count = 0
854
+ continue
855
+
856
+ # Skip directives
857
+ if line.startswith("."):
858
+ continue
859
+
860
+ # Parse instruction
861
+ # Handle various formats:
862
+ # - " mov %rax, %rbx"
863
+ # - " 0x1234 mov %rax, %rbx"
864
+ # - " file:10 0x1234 aabbccdd mov %rax, %rbx"
865
+
866
+ instruction = line
867
+ address = ""
868
+
869
+ # Extract address if present
870
+ addr_match = re.search(r"0x([0-9a-fA-F]+)", line)
871
+ if addr_match:
872
+ address = "0x" + addr_match.group(1)
873
+
874
+ # Extract mnemonic (first word-like token that's not an address or file ref)
875
+ parts = line.split()
876
+ mnemonic = ""
877
+ for part in parts:
878
+ # Skip addresses, hex bytes, file references
879
+ if part.startswith("0x") or re.match(r"^[0-9a-fA-F]{2,}$", part):
880
+ continue
881
+ if ":" in part and not part.endswith(":"): # file:line reference
882
+ continue
883
+ # This should be the mnemonic
884
+ mnemonic = part.lower().rstrip(":")
885
+ break
886
+
887
+ if not mnemonic:
888
+ continue
889
+
890
+ instruction_count += 1
891
+
892
+ # Check for violations
893
+ if mnemonic in self.errors:
894
+ violations.append(
895
+ Violation(
896
+ function=current_function or "<unknown>",
897
+ file=current_file or "",
898
+ line=current_line,
899
+ address=address,
900
+ instruction=instruction,
901
+ mnemonic=mnemonic.upper(),
902
+ reason=self.errors[mnemonic],
903
+ severity=Severity.ERROR,
904
+ )
905
+ )
906
+ elif include_warnings and mnemonic in self.warnings:
907
+ violations.append(
908
+ Violation(
909
+ function=current_function or "<unknown>",
910
+ file=current_file or "",
911
+ line=current_line,
912
+ address=address,
913
+ instruction=instruction,
914
+ mnemonic=mnemonic.upper(),
915
+ reason=self.warnings[mnemonic],
916
+ severity=Severity.WARNING,
917
+ )
918
+ )
919
+
920
+ # Don't forget the last function
921
+ if current_function:
922
+ functions.append(
923
+ {
924
+ "name": current_function,
925
+ "instructions": instruction_count,
926
+ }
927
+ )
928
+
929
+ return functions, violations
930
+
931
+
932
+ def analyze_source(
933
+ source_file: str,
934
+ arch: str = None,
935
+ compiler: str = None,
936
+ optimization: str = "O2",
937
+ include_warnings: bool = False,
938
+ function_filter: str = None,
939
+ extra_flags: list[str] = None,
940
+ ) -> AnalysisReport:
941
+ """
942
+ Analyze a source file for constant-time violations.
943
+
944
+ Args:
945
+ source_file: Path to the source file to analyze
946
+ arch: Target architecture (default: native, ignored for scripting languages)
947
+ compiler: Compiler to use (default: auto-detect from language)
948
+ optimization: Optimization level (default: O2, ignored for scripting languages)
949
+ include_warnings: Include warning-level violations
950
+ function_filter: Regex pattern to filter functions
951
+ extra_flags: Extra flags to pass to the compiler (ignored for scripting languages)
952
+
953
+ Returns:
954
+ AnalysisReport with results
955
+ """
956
+ source_path = Path(source_file)
957
+ if not source_path.exists():
958
+ raise FileNotFoundError(f"Source file not found: {source_file}")
959
+
960
+ language = detect_language(source_file)
961
+
962
+ # Route scripting/bytecode languages to specialized analyzers
963
+ if is_bytecode_language(language):
964
+ try:
965
+ from .script_analyzers import get_script_analyzer
966
+ except ImportError:
967
+ from script_analyzers import get_script_analyzer
968
+
969
+ analyzer = get_script_analyzer(language)
970
+ if analyzer is None:
971
+ raise RuntimeError(f"No analyzer available for language: {language}")
972
+
973
+ if not analyzer.is_available():
974
+ runtime_map = {
975
+ "php": "PHP",
976
+ "javascript": "Node.js",
977
+ "typescript": "Node.js",
978
+ "python": "Python",
979
+ "ruby": "Ruby",
980
+ "java": "Java (javac/javap)",
981
+ "csharp": ".NET SDK",
982
+ "kotlin": "Kotlin (kotlinc)",
983
+ }
984
+ runtime = runtime_map.get(language, language)
985
+ raise RuntimeError(
986
+ f"{runtime} is not available. Please install it to analyze {language} files."
987
+ )
988
+
989
+ return analyzer.analyze(
990
+ str(source_path.absolute()),
991
+ include_warnings=include_warnings,
992
+ function_filter=function_filter,
993
+ )
994
+
995
+ # Compiled languages use assembly analysis
996
+ arch = normalize_arch(arch or get_native_arch())
997
+
998
+ compiler_obj = get_compiler(compiler, language)
999
+ if not compiler_obj.is_available():
1000
+ raise RuntimeError(f"Compiler not available: {compiler_obj.name}")
1001
+
1002
+ # Compile to assembly
1003
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".s", delete=False) as asm_file:
1004
+ asm_path = asm_file.name
1005
+
1006
+ try:
1007
+ success, error = compiler_obj.compile_to_assembly(
1008
+ str(source_path.absolute()),
1009
+ asm_path,
1010
+ arch,
1011
+ optimization,
1012
+ extra_flags,
1013
+ )
1014
+
1015
+ if not success:
1016
+ raise RuntimeError(f"Compilation failed: {error}")
1017
+
1018
+ with open(asm_path) as f:
1019
+ assembly_text = f.read()
1020
+
1021
+ # Parse and analyze
1022
+ parser = AssemblyParser(arch, compiler_obj.name)
1023
+ functions, violations = parser.parse(assembly_text, include_warnings)
1024
+
1025
+ # Filter functions if requested
1026
+ if function_filter:
1027
+ pattern = re.compile(function_filter)
1028
+ violations = [v for v in violations if pattern.search(v.function)]
1029
+ functions = [f for f in functions if pattern.search(f["name"])]
1030
+
1031
+ return AnalysisReport(
1032
+ architecture=arch,
1033
+ compiler=compiler_obj.name,
1034
+ optimization=optimization,
1035
+ source_file=str(source_file),
1036
+ total_functions=len(functions),
1037
+ total_instructions=sum(f["instructions"] for f in functions),
1038
+ violations=violations,
1039
+ )
1040
+
1041
+ finally:
1042
+ if os.path.exists(asm_path):
1043
+ os.unlink(asm_path)
1044
+
1045
+
1046
+ def analyze_assembly(
1047
+ assembly_file: str,
1048
+ arch: str,
1049
+ include_warnings: bool = False,
1050
+ function_filter: str = None,
1051
+ ) -> AnalysisReport:
1052
+ """
1053
+ Analyze pre-compiled assembly for constant-time violations.
1054
+
1055
+ Args:
1056
+ assembly_file: Path to the assembly file
1057
+ arch: Target architecture
1058
+ include_warnings: Include warning-level violations
1059
+ function_filter: Regex pattern to filter functions
1060
+
1061
+ Returns:
1062
+ AnalysisReport with results
1063
+ """
1064
+ arch = normalize_arch(arch)
1065
+
1066
+ with open(assembly_file) as f:
1067
+ assembly_text = f.read()
1068
+
1069
+ parser = AssemblyParser(arch, "unknown")
1070
+ functions, violations = parser.parse(assembly_text, include_warnings)
1071
+
1072
+ if function_filter:
1073
+ pattern = re.compile(function_filter)
1074
+ violations = [v for v in violations if pattern.search(v.function)]
1075
+ functions = [f for f in functions if pattern.search(f["name"])]
1076
+
1077
+ return AnalysisReport(
1078
+ architecture=arch,
1079
+ compiler="unknown",
1080
+ optimization="unknown",
1081
+ source_file=assembly_file,
1082
+ total_functions=len(functions),
1083
+ total_instructions=sum(f["instructions"] for f in functions),
1084
+ violations=violations,
1085
+ )
1086
+
1087
+
1088
+ def format_report(report: AnalysisReport, format_type: OutputFormat) -> str:
1089
+ """Format an analysis report for output."""
1090
+
1091
+ if format_type == OutputFormat.JSON:
1092
+ return json.dumps(
1093
+ {
1094
+ "architecture": report.architecture,
1095
+ "compiler": report.compiler,
1096
+ "optimization": report.optimization,
1097
+ "source_file": report.source_file,
1098
+ "total_functions": report.total_functions,
1099
+ "total_instructions": report.total_instructions,
1100
+ "error_count": report.error_count,
1101
+ "warning_count": report.warning_count,
1102
+ "passed": report.passed,
1103
+ "violations": [
1104
+ {
1105
+ "function": v.function,
1106
+ "file": v.file,
1107
+ "line": v.line,
1108
+ "address": v.address,
1109
+ "instruction": v.instruction,
1110
+ "mnemonic": v.mnemonic,
1111
+ "reason": v.reason,
1112
+ "severity": v.severity.value,
1113
+ }
1114
+ for v in report.violations
1115
+ ],
1116
+ },
1117
+ indent=2,
1118
+ )
1119
+
1120
+ elif format_type == OutputFormat.GITHUB:
1121
+ lines = []
1122
+ for v in report.violations:
1123
+ level = "error" if v.severity == Severity.ERROR else "warning"
1124
+ file_ref = f"file={v.file}" if v.file else ""
1125
+ line_ref = f",line={v.line}" if v.line else ""
1126
+ lines.append(
1127
+ f"::{level} {file_ref}{line_ref}::{v.mnemonic} in {v.function}: {v.reason}"
1128
+ )
1129
+ return "\n".join(lines)
1130
+
1131
+ else: # TEXT
1132
+ lines = []
1133
+ lines.append("=" * 60)
1134
+ lines.append("Constant-Time Analysis Report")
1135
+ lines.append("=" * 60)
1136
+ lines.append(f"Source: {report.source_file}")
1137
+ lines.append(f"Architecture: {report.architecture}")
1138
+ lines.append(f"Compiler: {report.compiler}")
1139
+ lines.append(f"Optimization: {report.optimization}")
1140
+ lines.append(f"Functions analyzed: {report.total_functions}")
1141
+ lines.append(f"Instructions analyzed: {report.total_instructions}")
1142
+ lines.append("")
1143
+
1144
+ if report.violations:
1145
+ lines.append("VIOLATIONS FOUND:")
1146
+ lines.append("-" * 40)
1147
+ for v in report.violations:
1148
+ severity_marker = "ERROR" if v.severity == Severity.ERROR else "WARN"
1149
+ lines.append(f"[{severity_marker}] {v.mnemonic}")
1150
+ lines.append(f" Function: {v.function}")
1151
+ if v.file:
1152
+ file_info = f" File: {v.file}"
1153
+ if v.line:
1154
+ file_info += f":{v.line}"
1155
+ lines.append(file_info)
1156
+ if v.address:
1157
+ lines.append(f" Address: {v.address}")
1158
+ lines.append(f" Reason: {v.reason}")
1159
+ lines.append("")
1160
+ else:
1161
+ lines.append("No violations found.")
1162
+
1163
+ lines.append("-" * 40)
1164
+ status = "PASSED" if report.passed else "FAILED"
1165
+ lines.append(f"Result: {status}")
1166
+ lines.append(f"Errors: {report.error_count}, Warnings: {report.warning_count}")
1167
+
1168
+ return "\n".join(lines)
1169
+
1170
+
1171
+ def main():
1172
+ parser = argparse.ArgumentParser(
1173
+ description="Analyze code for constant-time violations",
1174
+ formatter_class=argparse.RawDescriptionHelpFormatter,
1175
+ epilog="""
1176
+ Examples:
1177
+ %(prog)s crypto.c # Analyze C file with defaults
1178
+ %(prog)s --compiler gcc --opt O3 crypto.c # Use GCC with -O3
1179
+ %(prog)s --arch arm64 crypto.go # Analyze Go for ARM64
1180
+ %(prog)s --warnings crypto.c # Include branch warnings
1181
+ %(prog)s --json crypto.c # Output as JSON
1182
+ %(prog)s CryptoUtils.java # Analyze Java (JVM bytecode)
1183
+ %(prog)s CryptoUtils.kt # Analyze Kotlin (JVM bytecode)
1184
+ %(prog)s CryptoUtils.cs # Analyze C# (CIL bytecode)
1185
+ %(prog)s crypto.swift # Analyze Swift (native code)
1186
+ %(prog)s crypto.php # Analyze PHP (uses VLD/opcache)
1187
+ %(prog)s crypto.ts # Analyze TypeScript (transpiles first)
1188
+ %(prog)s crypto.js # Analyze JavaScript (V8 bytecode)
1189
+
1190
+ Supported languages:
1191
+ Native compiled: C, C++, Go, Rust, Swift
1192
+ VM-compiled: Java, Kotlin, C#
1193
+ Scripting: PHP, JavaScript, TypeScript, Python, Ruby
1194
+
1195
+ Supported architectures (native compiled languages only):
1196
+ x86_64, arm64, arm, riscv64, ppc64le, s390x, i386
1197
+
1198
+ Note: VM-compiled and scripting languages analyze bytecode and don't use --arch or --opt-level.
1199
+ """,
1200
+ )
1201
+
1202
+ parser.add_argument("source_file", help="Source file to analyze")
1203
+ parser.add_argument("--arch", "-a", help="Target architecture (default: native)")
1204
+ parser.add_argument("--compiler", "-c", help="Compiler to use (gcc, clang, go, rustc)")
1205
+ parser.add_argument(
1206
+ "--opt-level", "-O", default="O2", help="Optimization level (O0, O1, O2, O3, Os, Oz)"
1207
+ )
1208
+ parser.add_argument(
1209
+ "--warnings",
1210
+ "-w",
1211
+ action="store_true",
1212
+ help="Include warning-level violations (conditional branches)",
1213
+ )
1214
+ parser.add_argument("--func", "-f", help="Regex pattern to filter functions")
1215
+ parser.add_argument("--json", action="store_true", help="Output in JSON format")
1216
+ parser.add_argument("--github", action="store_true", help="Output GitHub Actions annotations")
1217
+ parser.add_argument(
1218
+ "--assembly", action="store_true", help="Input is already assembly (requires --arch)"
1219
+ )
1220
+ parser.add_argument(
1221
+ "--list-arch", action="store_true", help="List supported architectures and exit"
1222
+ )
1223
+ parser.add_argument(
1224
+ "--extra-flags",
1225
+ "-X",
1226
+ action="append",
1227
+ default=[],
1228
+ help="Extra flags to pass to the compiler",
1229
+ )
1230
+
1231
+ args = parser.parse_args()
1232
+
1233
+ if args.list_arch:
1234
+ print("Supported Architectures:")
1235
+ print("=" * 40)
1236
+ for arch, instructions in DANGEROUS_INSTRUCTIONS.items():
1237
+ print(f"\n{arch}:")
1238
+ print(f" Errors: {len(instructions.get('errors', {}))}")
1239
+ print(f" Warnings: {len(instructions.get('warnings', {}))}")
1240
+ return 0
1241
+
1242
+ # Determine output format
1243
+ if args.json:
1244
+ output_format = OutputFormat.JSON
1245
+ elif args.github:
1246
+ output_format = OutputFormat.GITHUB
1247
+ else:
1248
+ output_format = OutputFormat.TEXT
1249
+
1250
+ try:
1251
+ if args.assembly:
1252
+ if not args.arch:
1253
+ print("Error: --arch is required when analyzing assembly files", file=sys.stderr)
1254
+ return 1
1255
+ report = analyze_assembly(
1256
+ args.source_file,
1257
+ args.arch,
1258
+ include_warnings=args.warnings,
1259
+ function_filter=args.func,
1260
+ )
1261
+ else:
1262
+ report = analyze_source(
1263
+ args.source_file,
1264
+ arch=args.arch,
1265
+ compiler=args.compiler,
1266
+ optimization=args.opt_level,
1267
+ include_warnings=args.warnings,
1268
+ function_filter=args.func,
1269
+ extra_flags=args.extra_flags,
1270
+ )
1271
+
1272
+ print(format_report(report, output_format))
1273
+ return 0 if report.passed else 1
1274
+
1275
+ except (FileNotFoundError, RuntimeError, subprocess.CalledProcessError) as e:
1276
+ if output_format == OutputFormat.JSON:
1277
+ print(json.dumps({"error": str(e)}))
1278
+ else:
1279
+ print(f"Error: {e}", file=sys.stderr)
1280
+ return 1
1281
+
1282
+
1283
+ if __name__ == "__main__":
1284
+ sys.exit(main())