goscript 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/cmd/goscript/cmd-test.go +104 -11
  2. package/cmd/goscript/cmd-test_test.go +1 -1
  3. package/cmd/goscript/cmd_compile.go +9 -0
  4. package/compiler/compile-request.go +31 -0
  5. package/compiler/compiler.go +1 -1
  6. package/compiler/compliance_test.go +0 -2
  7. package/compiler/config.go +2 -0
  8. package/compiler/gotest/package-result.go +2 -0
  9. package/compiler/gotest/request.go +85 -20
  10. package/compiler/gotest/runner.go +733 -96
  11. package/compiler/gotest/runner_test.go +647 -3
  12. package/compiler/lowered-program.go +9 -2
  13. package/compiler/lowering.go +2001 -345
  14. package/compiler/override-facts.go +77 -27
  15. package/compiler/override-registry.go +5 -4
  16. package/compiler/override-registry_test.go +135 -0
  17. package/compiler/package-graph_test.go +62 -7
  18. package/compiler/package-test-graph-variant.go +40 -16
  19. package/compiler/package-test-graph.go +0 -5
  20. package/compiler/package-test-graph_test.go +61 -3
  21. package/compiler/runtime-contract.go +40 -0
  22. package/compiler/semantic-model-types.go +16 -0
  23. package/compiler/semantic-model.go +336 -91
  24. package/compiler/semantic-model_test.go +50 -1
  25. package/compiler/service.go +9 -3
  26. package/compiler/skeleton_test.go +1921 -298
  27. package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
  28. package/compiler/tsworkspace/owner.go +8 -0
  29. package/compiler/tsworkspace/tool-process-other.go +14 -0
  30. package/compiler/tsworkspace/tool-process-unix.go +19 -0
  31. package/compiler/typescript-emitter.go +122 -9
  32. package/dist/gs/builtin/builtin.d.ts +20 -1
  33. package/dist/gs/builtin/builtin.js +246 -26
  34. package/dist/gs/builtin/builtin.js.map +1 -1
  35. package/dist/gs/builtin/channel.d.ts +24 -10
  36. package/dist/gs/builtin/channel.js +107 -25
  37. package/dist/gs/builtin/channel.js.map +1 -1
  38. package/dist/gs/builtin/defer.d.ts +1 -0
  39. package/dist/gs/builtin/defer.js +12 -2
  40. package/dist/gs/builtin/defer.js.map +1 -1
  41. package/dist/gs/builtin/hostio.d.ts +9 -0
  42. package/dist/gs/builtin/hostio.js +25 -0
  43. package/dist/gs/builtin/hostio.js.map +1 -1
  44. package/dist/gs/builtin/map.js +40 -6
  45. package/dist/gs/builtin/map.js.map +1 -1
  46. package/dist/gs/builtin/print.js.map +1 -1
  47. package/dist/gs/builtin/slice.d.ts +43 -9
  48. package/dist/gs/builtin/slice.js +437 -234
  49. package/dist/gs/builtin/slice.js.map +1 -1
  50. package/dist/gs/builtin/type.d.ts +2 -0
  51. package/dist/gs/builtin/type.js +47 -7
  52. package/dist/gs/builtin/type.js.map +1 -1
  53. package/dist/gs/builtin/varRef.d.ts +2 -0
  54. package/dist/gs/builtin/varRef.js.map +1 -1
  55. package/dist/gs/bytes/buffer.gs.js +28 -28
  56. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  57. package/dist/gs/bytes/iter.gs.js +13 -13
  58. package/dist/gs/bytes/iter.gs.js.map +1 -1
  59. package/dist/gs/compress/zlib/index.d.ts +26 -0
  60. package/dist/gs/compress/zlib/index.js +168 -0
  61. package/dist/gs/compress/zlib/index.js.map +1 -0
  62. package/dist/gs/context/context.d.ts +1 -1
  63. package/dist/gs/context/context.js +8 -3
  64. package/dist/gs/context/context.js.map +1 -1
  65. package/dist/gs/crypto/ecdh/index.d.ts +52 -0
  66. package/dist/gs/crypto/ecdh/index.js +226 -0
  67. package/dist/gs/crypto/ecdh/index.js.map +1 -0
  68. package/dist/gs/crypto/ed25519/index.d.ts +34 -0
  69. package/dist/gs/crypto/ed25519/index.js +160 -0
  70. package/dist/gs/crypto/ed25519/index.js.map +1 -0
  71. package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
  72. package/dist/gs/crypto/internal/constanttime/index.js +18 -0
  73. package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
  74. package/dist/gs/crypto/rand/index.d.ts +2 -0
  75. package/dist/gs/crypto/rand/index.js +85 -0
  76. package/dist/gs/crypto/rand/index.js.map +1 -1
  77. package/dist/gs/crypto/sha256/index.d.ts +8 -0
  78. package/dist/gs/crypto/sha256/index.js +118 -0
  79. package/dist/gs/crypto/sha256/index.js.map +1 -0
  80. package/dist/gs/crypto/sha512/index.d.ts +14 -0
  81. package/dist/gs/crypto/sha512/index.js +129 -0
  82. package/dist/gs/crypto/sha512/index.js.map +1 -0
  83. package/dist/gs/encoding/json/index.d.ts +3 -0
  84. package/dist/gs/encoding/json/index.js +15 -0
  85. package/dist/gs/encoding/json/index.js.map +1 -1
  86. package/dist/gs/errors/errors.js +29 -6
  87. package/dist/gs/errors/errors.js.map +1 -1
  88. package/dist/gs/fmt/fmt.js.map +1 -1
  89. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +7 -7
  90. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +52 -18
  91. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  92. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +56 -20
  93. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
  94. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +57 -3
  95. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +366 -1
  96. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
  97. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
  98. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
  99. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
  100. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  101. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
  102. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
  103. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
  104. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +3 -2
  105. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -1
  106. package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
  107. package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
  108. package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
  109. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
  110. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
  111. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
  112. package/dist/gs/go/token/index.js +11 -4
  113. package/dist/gs/go/token/index.js.map +1 -1
  114. package/dist/gs/hash/fnv/index.d.ts +57 -0
  115. package/dist/gs/hash/fnv/index.js +299 -0
  116. package/dist/gs/hash/fnv/index.js.map +1 -0
  117. package/dist/gs/hash/index.d.ts +17 -0
  118. package/dist/gs/hash/index.js +94 -0
  119. package/dist/gs/hash/index.js.map +1 -0
  120. package/dist/gs/io/fs/readlink.js +2 -6
  121. package/dist/gs/io/fs/readlink.js.map +1 -1
  122. package/dist/gs/io/fs/walk.js.map +1 -1
  123. package/dist/gs/io/io.js.map +1 -1
  124. package/dist/gs/iter/iter.d.ts +3 -2
  125. package/dist/gs/iter/iter.js.map +1 -1
  126. package/dist/gs/maps/iter.d.ts +5 -5
  127. package/dist/gs/maps/iter.js +48 -21
  128. package/dist/gs/maps/iter.js.map +1 -1
  129. package/dist/gs/maps/maps.d.ts +6 -6
  130. package/dist/gs/math/bits/index.js +14 -24
  131. package/dist/gs/math/bits/index.js.map +1 -1
  132. package/dist/gs/mime/index.js +3 -1
  133. package/dist/gs/mime/index.js.map +1 -1
  134. package/dist/gs/net/http/httptest/index.d.ts +20 -1
  135. package/dist/gs/net/http/httptest/index.js +83 -3
  136. package/dist/gs/net/http/httptest/index.js.map +1 -1
  137. package/dist/gs/net/http/index.d.ts +110 -6
  138. package/dist/gs/net/http/index.js +262 -16
  139. package/dist/gs/net/http/index.js.map +1 -1
  140. package/dist/gs/net/http/pprof/index.d.ts +8 -0
  141. package/dist/gs/net/http/pprof/index.js +59 -0
  142. package/dist/gs/net/http/pprof/index.js.map +1 -0
  143. package/dist/gs/os/error.gs.js +9 -7
  144. package/dist/gs/os/error.gs.js.map +1 -1
  145. package/dist/gs/os/types_js.gs.js +95 -15
  146. package/dist/gs/os/types_js.gs.js.map +1 -1
  147. package/dist/gs/path/filepath/match.js.map +1 -1
  148. package/dist/gs/path/filepath/path.d.ts +5 -3
  149. package/dist/gs/path/filepath/path.js +65 -10
  150. package/dist/gs/path/filepath/path.js.map +1 -1
  151. package/dist/gs/reflect/index.d.ts +3 -2
  152. package/dist/gs/reflect/index.js +2 -1
  153. package/dist/gs/reflect/index.js.map +1 -1
  154. package/dist/gs/reflect/iter.js +2 -2
  155. package/dist/gs/reflect/iter.js.map +1 -1
  156. package/dist/gs/reflect/map.js +26 -0
  157. package/dist/gs/reflect/map.js.map +1 -1
  158. package/dist/gs/reflect/type.d.ts +24 -5
  159. package/dist/gs/reflect/type.js +390 -38
  160. package/dist/gs/reflect/type.js.map +1 -1
  161. package/dist/gs/reflect/types.d.ts +1 -0
  162. package/dist/gs/reflect/types.js +3 -1
  163. package/dist/gs/reflect/types.js.map +1 -1
  164. package/dist/gs/reflect/value.d.ts +4 -1
  165. package/dist/gs/reflect/value.js +39 -1
  166. package/dist/gs/reflect/value.js.map +1 -1
  167. package/dist/gs/reflect/visiblefields.js +1 -1
  168. package/dist/gs/reflect/visiblefields.js.map +1 -1
  169. package/dist/gs/runtime/debug/index.d.ts +39 -0
  170. package/dist/gs/runtime/debug/index.js +58 -0
  171. package/dist/gs/runtime/debug/index.js.map +1 -1
  172. package/dist/gs/runtime/pprof/index.d.ts +20 -0
  173. package/dist/gs/runtime/pprof/index.js +85 -0
  174. package/dist/gs/runtime/pprof/index.js.map +1 -0
  175. package/dist/gs/runtime/trace/index.d.ts +19 -0
  176. package/dist/gs/runtime/trace/index.js +64 -0
  177. package/dist/gs/runtime/trace/index.js.map +1 -0
  178. package/dist/gs/slices/slices.d.ts +24 -9
  179. package/dist/gs/slices/slices.js +229 -24
  180. package/dist/gs/slices/slices.js.map +1 -1
  181. package/dist/gs/sort/slice.gs.d.ts +5 -3
  182. package/dist/gs/sort/slice.gs.js +55 -17
  183. package/dist/gs/sort/slice.gs.js.map +1 -1
  184. package/dist/gs/strings/builder.js +26 -17
  185. package/dist/gs/strings/builder.js.map +1 -1
  186. package/dist/gs/strings/iter.js +140 -75
  187. package/dist/gs/strings/iter.js.map +1 -1
  188. package/dist/gs/strings/replace.js +2 -2
  189. package/dist/gs/strings/replace.js.map +1 -1
  190. package/dist/gs/strings/strings.js +52 -6
  191. package/dist/gs/strings/strings.js.map +1 -1
  192. package/dist/gs/sync/sync.d.ts +6 -3
  193. package/dist/gs/sync/sync.js +39 -11
  194. package/dist/gs/sync/sync.js.map +1 -1
  195. package/dist/gs/syscall/errors.d.ts +116 -112
  196. package/dist/gs/syscall/errors.js +38 -1
  197. package/dist/gs/syscall/errors.js.map +1 -1
  198. package/dist/gs/syscall/fs.d.ts +2 -8
  199. package/dist/gs/syscall/fs.js.map +1 -1
  200. package/dist/gs/syscall/js/index.js +20 -12
  201. package/dist/gs/syscall/js/index.js.map +1 -1
  202. package/dist/gs/syscall/types.d.ts +4 -1
  203. package/dist/gs/syscall/types.js.map +1 -1
  204. package/dist/gs/testing/testing.d.ts +4 -3
  205. package/dist/gs/testing/testing.js +21 -4
  206. package/dist/gs/testing/testing.js.map +1 -1
  207. package/dist/gs/time/time.js +22 -0
  208. package/dist/gs/time/time.js.map +1 -1
  209. package/dist/gs/unicode/unicode.js.map +1 -1
  210. package/dist/gs/unique/index.js +7 -2
  211. package/dist/gs/unique/index.js.map +1 -1
  212. package/go.mod +8 -8
  213. package/go.sum +14 -23
  214. package/gs/builtin/builtin.ts +364 -37
  215. package/gs/builtin/channel.ts +161 -29
  216. package/gs/builtin/defer.ts +13 -2
  217. package/gs/builtin/hostio.test.ts +1 -0
  218. package/gs/builtin/hostio.ts +38 -0
  219. package/gs/builtin/map.ts +46 -6
  220. package/gs/builtin/print.ts +12 -3
  221. package/gs/builtin/runtime-contract.test.ts +257 -10
  222. package/gs/builtin/slice.test.ts +70 -0
  223. package/gs/builtin/slice.ts +566 -255
  224. package/gs/builtin/type.ts +53 -9
  225. package/gs/builtin/varRef.ts +2 -0
  226. package/gs/bytes/buffer.gs.ts +28 -28
  227. package/gs/bytes/iter.gs.ts +13 -14
  228. package/gs/compress/zlib/index.test.ts +28 -0
  229. package/gs/compress/zlib/index.ts +200 -0
  230. package/gs/compress/zlib/meta.json +3 -0
  231. package/gs/context/context.test.ts +31 -1
  232. package/gs/context/context.ts +9 -4
  233. package/gs/crypto/ecdh/index.test.ts +43 -0
  234. package/gs/crypto/ecdh/index.ts +274 -0
  235. package/gs/crypto/ed25519/index.test.ts +41 -0
  236. package/gs/crypto/ed25519/index.ts +238 -0
  237. package/gs/crypto/ed25519/meta.json +13 -0
  238. package/gs/crypto/internal/constanttime/index.test.ts +25 -0
  239. package/gs/crypto/internal/constanttime/index.ts +22 -0
  240. package/gs/crypto/rand/index.test.ts +89 -1
  241. package/gs/crypto/rand/index.ts +103 -1
  242. package/gs/crypto/rand/meta.json +4 -1
  243. package/gs/crypto/sha256/index.test.ts +78 -0
  244. package/gs/crypto/sha256/index.ts +150 -0
  245. package/gs/crypto/sha256/meta.json +9 -0
  246. package/gs/crypto/sha512/index.test.ts +31 -0
  247. package/gs/crypto/sha512/index.ts +161 -0
  248. package/gs/crypto/sha512/meta.json +11 -0
  249. package/gs/encoding/json/index.test.ts +25 -3
  250. package/gs/encoding/json/index.ts +21 -3
  251. package/gs/errors/errors.test.ts +4 -1
  252. package/gs/errors/errors.ts +32 -8
  253. package/gs/fmt/fmt.test.ts +3 -1
  254. package/gs/fmt/fmt.ts +1 -5
  255. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +62 -7
  256. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +78 -36
  257. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +32 -11
  258. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +122 -43
  259. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
  260. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +518 -4
  261. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +6 -0
  262. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
  263. package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
  264. package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
  265. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
  266. package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
  267. package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
  268. package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
  269. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +2 -1
  270. package/gs/github.com/klauspost/compress/internal/le/index.ts +6 -5
  271. package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
  272. package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
  273. package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
  274. package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
  275. package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
  276. package/gs/go/token/index.ts +17 -4
  277. package/gs/hash/fnv/index.test.ts +67 -0
  278. package/gs/hash/fnv/index.ts +351 -0
  279. package/gs/hash/fnv/meta.json +3 -0
  280. package/gs/hash/index.test.ts +37 -0
  281. package/gs/hash/index.ts +118 -0
  282. package/gs/hash/meta.json +5 -0
  283. package/gs/internal/byteorder/index.test.ts +6 -6
  284. package/gs/io/fs/readlink.ts +40 -48
  285. package/gs/io/fs/walk.ts +10 -2
  286. package/gs/io/io.ts +4 -1
  287. package/gs/iter/iter.ts +8 -2
  288. package/gs/maps/iter.ts +69 -26
  289. package/gs/maps/maps.test.ts +23 -0
  290. package/gs/maps/maps.ts +6 -6
  291. package/gs/math/bits/index.test.ts +20 -0
  292. package/gs/math/bits/index.ts +15 -28
  293. package/gs/mime/index.ts +8 -2
  294. package/gs/net/http/httptest/index.test.ts +53 -0
  295. package/gs/net/http/httptest/index.ts +98 -3
  296. package/gs/net/http/index.test.ts +129 -1
  297. package/gs/net/http/index.ts +370 -19
  298. package/gs/net/http/meta.json +6 -0
  299. package/gs/net/http/pprof/index.test.ts +47 -0
  300. package/gs/net/http/pprof/index.ts +65 -0
  301. package/gs/os/error.gs.ts +9 -10
  302. package/gs/os/error.test.ts +41 -0
  303. package/gs/os/file_unix_js.test.ts +55 -0
  304. package/gs/os/tempfile.gs.test.ts +37 -10
  305. package/gs/os/types_js.gs.ts +94 -15
  306. package/gs/path/filepath/match.ts +4 -1
  307. package/gs/path/filepath/meta.json +6 -0
  308. package/gs/path/filepath/path.test.ts +57 -2
  309. package/gs/path/filepath/path.ts +91 -12
  310. package/gs/reflect/field.test.ts +63 -0
  311. package/gs/reflect/index.ts +4 -1
  312. package/gs/reflect/iter.ts +2 -2
  313. package/gs/reflect/map.test.ts +24 -2
  314. package/gs/reflect/map.ts +35 -0
  315. package/gs/reflect/type.ts +543 -60
  316. package/gs/reflect/typefor.test.ts +100 -0
  317. package/gs/reflect/types.ts +3 -1
  318. package/gs/reflect/value.ts +50 -1
  319. package/gs/reflect/visiblefields.ts +1 -1
  320. package/gs/runtime/debug/index.test.ts +22 -1
  321. package/gs/runtime/debug/index.ts +88 -0
  322. package/gs/runtime/pprof/index.test.ts +36 -0
  323. package/gs/runtime/pprof/index.ts +104 -0
  324. package/gs/runtime/pprof/meta.json +6 -0
  325. package/gs/runtime/trace/index.test.ts +45 -0
  326. package/gs/runtime/trace/index.ts +97 -0
  327. package/gs/runtime/trace/meta.json +7 -0
  328. package/gs/slices/meta.json +2 -1
  329. package/gs/slices/slices.test.ts +86 -0
  330. package/gs/slices/slices.ts +284 -37
  331. package/gs/sort/slice.gs.ts +73 -23
  332. package/gs/sort/slice.test.ts +40 -0
  333. package/gs/strings/builder.test.ts +8 -0
  334. package/gs/strings/builder.ts +29 -17
  335. package/gs/strings/iter.test.ts +5 -7
  336. package/gs/strings/iter.ts +146 -71
  337. package/gs/strings/replace.test.ts +1 -4
  338. package/gs/strings/replace.ts +6 -6
  339. package/gs/strings/strings.test.ts +4 -0
  340. package/gs/strings/strings.ts +54 -6
  341. package/gs/sync/sync.test.ts +57 -1
  342. package/gs/sync/sync.ts +45 -13
  343. package/gs/syscall/errors.ts +158 -115
  344. package/gs/syscall/fs.ts +8 -8
  345. package/gs/syscall/js/index.ts +49 -22
  346. package/gs/syscall/net.test.ts +26 -0
  347. package/gs/syscall/types.ts +7 -2
  348. package/gs/testing/testing.test.ts +56 -0
  349. package/gs/testing/testing.ts +27 -10
  350. package/gs/time/meta.json +2 -2
  351. package/gs/time/time.test.ts +4 -0
  352. package/gs/time/time.ts +33 -2
  353. package/gs/unicode/unicode.test.ts +14 -3
  354. package/gs/unicode/unicode.ts +1 -5
  355. package/gs/unique/index.ts +9 -2
  356. package/package.json +3 -3
@@ -0,0 +1,238 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import * as io from '@goscript/io/index.js'
3
+
4
+ export type PublicKey = $.Bytes
5
+ export type PrivateKey = $.Bytes
6
+ type Hash = number
7
+ type PublicKeyInterface = any
8
+ type PrivateKeyInterface = any
9
+ type SignerOpts = { HashFunc(): Hash }
10
+
11
+ export const PublicKeySize = 32
12
+ export const PrivateKeySize = 64
13
+ export const SignatureSize = 64
14
+ export const SeedSize = 32
15
+
16
+ const pkcs8Prefix = new Uint8Array([
17
+ 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70,
18
+ 0x04, 0x22, 0x04, 0x20,
19
+ ])
20
+
21
+ export class Options {
22
+ public Hash: Hash = 0
23
+ public Context = ''
24
+
25
+ constructor(init?: Partial<{ Hash: Hash; Context: string }>) {
26
+ this.Hash = init?.Hash ?? 0
27
+ this.Context = init?.Context ?? ''
28
+ }
29
+
30
+ public HashFunc(): Hash {
31
+ return this.Hash
32
+ }
33
+ }
34
+
35
+ export function PublicKey_Equal(pub: PublicKey, x: PublicKeyInterface | null): boolean {
36
+ const [xx, ok] = $.typeAssertTuple<PublicKey>(x, 'ed25519.PublicKey')
37
+ return ok && bytesEqual(pub, xx)
38
+ }
39
+
40
+ export function PrivateKey_Public(priv: PrivateKey): PublicKeyInterface | null {
41
+ const publicKey = new Uint8Array(PublicKeySize)
42
+ publicKey.set($.bytesToUint8Array(priv).subarray(SeedSize, PrivateKeySize))
43
+ return $.namedValueInterfaceValue<PublicKeyInterface | null>(
44
+ publicKey,
45
+ 'ed25519.PublicKey',
46
+ { Equal: PublicKey_Equal },
47
+ )
48
+ }
49
+
50
+ export function PrivateKey_Equal(priv: PrivateKey, x: PrivateKeyInterface | null): boolean {
51
+ const [xx, ok] = $.typeAssertTuple<PrivateKey>(x, 'ed25519.PrivateKey')
52
+ return ok && bytesEqual(priv, xx)
53
+ }
54
+
55
+ export function PrivateKey_Seed(priv: PrivateKey): $.Bytes {
56
+ return new Uint8Array($.bytesToUint8Array(priv).subarray(0, SeedSize))
57
+ }
58
+
59
+ export async function PrivateKey_Sign(
60
+ priv: PrivateKey,
61
+ _rand: io.Reader | null,
62
+ message: $.Bytes,
63
+ opts: SignerOpts | null,
64
+ ): Promise<[$.Bytes, $.GoError]> {
65
+ if (opts != null && opts.HashFunc() !== 0) {
66
+ return [null, new Ed25519Error('ed25519: expected opts.HashFunc() zero')]
67
+ }
68
+ return [await Sign(priv, message), null]
69
+ }
70
+
71
+ export async function GenerateKey(random: io.Reader | null): Promise<[PublicKey, PrivateKey, $.GoError]> {
72
+ const seed = new Uint8Array(SeedSize)
73
+ if (random == null) {
74
+ const subtle = subtleCrypto()
75
+ if (subtle == null) {
76
+ return [
77
+ null as PublicKey,
78
+ null as PrivateKey,
79
+ new Ed25519Error('crypto/ed25519: WebCrypto is unavailable'),
80
+ ]
81
+ }
82
+ globalThis.crypto.getRandomValues(seed)
83
+ } else {
84
+ const [, err] = await io.ReadFull(random, seed)
85
+ if (err != null) {
86
+ return [null as PublicKey, null as PrivateKey, err]
87
+ }
88
+ }
89
+
90
+ const privateKey = await NewKeyFromSeed(seed)
91
+ return [
92
+ $.mustTypeAssert<PublicKey>(
93
+ PrivateKey_Public(privateKey),
94
+ 'ed25519.PublicKey',
95
+ ),
96
+ privateKey,
97
+ null,
98
+ ]
99
+ }
100
+
101
+ export async function NewKeyFromSeed(seed: $.Bytes): Promise<PrivateKey> {
102
+ const seedBytes = $.bytesToUint8Array(seed)
103
+ if (seedBytes.length !== SeedSize) {
104
+ throw new Error(`ed25519: bad seed length: ${seedBytes.length}`)
105
+ }
106
+
107
+ const subtle = requireSubtle()
108
+ const key = await subtle.importKey(
109
+ 'pkcs8',
110
+ pkcs8FromSeed(seedBytes) as unknown as BufferSource,
111
+ { name: 'Ed25519' },
112
+ true,
113
+ ['sign'],
114
+ )
115
+ const jwk = await subtle.exportKey('jwk', key)
116
+ if (typeof jwk.x !== 'string') {
117
+ throw new Error('crypto/ed25519: imported key did not expose public key')
118
+ }
119
+
120
+ const publicKey = base64URLDecode(jwk.x)
121
+ const privateKey = new Uint8Array(PrivateKeySize)
122
+ privateKey.set(seedBytes, 0)
123
+ privateKey.set(publicKey, SeedSize)
124
+ return privateKey
125
+ }
126
+
127
+ export async function Sign(privateKey: PrivateKey, message: $.Bytes): Promise<$.Bytes> {
128
+ const priv = $.bytesToUint8Array(privateKey)
129
+ if (priv.length !== PrivateKeySize) {
130
+ throw new Error(`ed25519: bad private key length: ${priv.length}`)
131
+ }
132
+
133
+ const key = await requireSubtle().importKey(
134
+ 'pkcs8',
135
+ pkcs8FromSeed(priv.subarray(0, SeedSize)) as unknown as BufferSource,
136
+ { name: 'Ed25519' },
137
+ false,
138
+ ['sign'],
139
+ )
140
+ const sig = await requireSubtle().sign(
141
+ 'Ed25519',
142
+ key,
143
+ $.bytesToUint8Array(message) as unknown as BufferSource,
144
+ )
145
+ return new Uint8Array(sig)
146
+ }
147
+
148
+ export async function Verify(
149
+ publicKey: PublicKey,
150
+ message: $.Bytes,
151
+ sig: $.Bytes,
152
+ ): Promise<boolean> {
153
+ return (await VerifyWithOptions(publicKey, message, sig, new Options())) == null
154
+ }
155
+
156
+ export async function VerifyWithOptions(
157
+ publicKey: PublicKey,
158
+ message: $.Bytes,
159
+ sig: $.Bytes,
160
+ opts: Options | $.VarRef<Options> | null,
161
+ ): Promise<$.GoError> {
162
+ if ($.len(publicKey) !== PublicKeySize) {
163
+ throw new Error(`ed25519: bad public key length: ${$.len(publicKey)}`)
164
+ }
165
+ if ($.len(sig) !== SignatureSize) {
166
+ return new Ed25519Error('ed25519: bad signature length')
167
+ }
168
+
169
+ const options = $.pointerValueOrNil(opts)
170
+ if (options != null && (options.Hash !== 0 || options.Context !== '')) {
171
+ return new Ed25519Error('ed25519: only pure Ed25519 is supported')
172
+ }
173
+
174
+ const key = await requireSubtle().importKey(
175
+ 'raw',
176
+ $.bytesToUint8Array(publicKey) as unknown as BufferSource,
177
+ { name: 'Ed25519' },
178
+ false,
179
+ ['verify'],
180
+ )
181
+ const ok = await requireSubtle().verify(
182
+ 'Ed25519',
183
+ key,
184
+ $.bytesToUint8Array(sig) as unknown as BufferSource,
185
+ $.bytesToUint8Array(message) as unknown as BufferSource,
186
+ )
187
+ return ok ? null : new Ed25519Error('ed25519: invalid signature')
188
+ }
189
+
190
+ class Ed25519Error {
191
+ constructor(private readonly message: string) {}
192
+
193
+ Error(): string {
194
+ return this.message
195
+ }
196
+ }
197
+
198
+ function requireSubtle(): SubtleCrypto {
199
+ const subtle = subtleCrypto()
200
+ if (subtle == null) {
201
+ throw new Error('crypto/ed25519: WebCrypto Ed25519 is unavailable')
202
+ }
203
+ return subtle
204
+ }
205
+
206
+ function subtleCrypto(): SubtleCrypto | null {
207
+ const crypto = globalThis.crypto
208
+ if (crypto?.subtle && typeof crypto.subtle.importKey === 'function') {
209
+ return crypto.subtle
210
+ }
211
+ return null
212
+ }
213
+
214
+ function pkcs8FromSeed(seed: Uint8Array): Uint8Array {
215
+ const out = new Uint8Array(pkcs8Prefix.length + SeedSize)
216
+ out.set(pkcs8Prefix)
217
+ out.set(seed, pkcs8Prefix.length)
218
+ return out
219
+ }
220
+
221
+ function bytesEqual(a: $.Bytes, b: $.Bytes): boolean {
222
+ const aa = $.bytesToUint8Array(a)
223
+ const bb = $.bytesToUint8Array(b)
224
+ if (aa.length !== bb.length) {
225
+ return false
226
+ }
227
+ let diff = 0
228
+ for (let i = 0; i < aa.length; i++) {
229
+ diff |= aa[i] ^ bb[i]
230
+ }
231
+ return diff === 0
232
+ }
233
+
234
+ function base64URLDecode(value: string): Uint8Array {
235
+ const normalized = value.replace(/-/g, '+').replace(/_/g, '/')
236
+ const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=')
237
+ return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0))
238
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "dependencies": [
3
+ "io"
4
+ ],
5
+ "asyncFunctions": {
6
+ "GenerateKey": true,
7
+ "NewKeyFromSeed": true,
8
+ "Sign": true,
9
+ "Verify": true,
10
+ "VerifyWithOptions": true,
11
+ "PrivateKey_Sign": true
12
+ }
13
+ }
@@ -0,0 +1,25 @@
1
+ import { describe, expect, test } from 'vitest'
2
+
3
+ import { ByteEq, Eq, LessOrEq, Select } from './index.js'
4
+
5
+ describe('crypto/internal/constanttime override', () => {
6
+ test('selects on any non-zero selector', () => {
7
+ expect(Select(0, 11, 22)).toBe(22)
8
+ expect(Select(1, 11, 22)).toBe(11)
9
+ expect(Select(7, 11, 22)).toBe(11)
10
+ })
11
+
12
+ test('compares bytes and int32 values', () => {
13
+ expect(ByteEq(0xff, 0xff)).toBe(1)
14
+ expect(ByteEq(0x1ff, 0xff)).toBe(1)
15
+ expect(ByteEq(0x01, 0x02)).toBe(0)
16
+ expect(Eq(12, 12)).toBe(1)
17
+ expect(Eq(12, 13)).toBe(0)
18
+ })
19
+
20
+ test('compares integer ordering', () => {
21
+ expect(LessOrEq(1, 1)).toBe(1)
22
+ expect(LessOrEq(1, 2)).toBe(1)
23
+ expect(LessOrEq(2, 1)).toBe(0)
24
+ })
25
+ })
@@ -0,0 +1,22 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+
3
+ export function Select(v: number, x: number, y: number): number {
4
+ v = boolToUint8(v !== 0)
5
+ return (~(v - 1) & x) | ((v - 1) & y)
6
+ }
7
+
8
+ export function ByteEq(x: number, y: number): number {
9
+ return $.int(boolToUint8($.uint(x, 8) === $.uint(y, 8)))
10
+ }
11
+
12
+ export function Eq(x: number, y: number): number {
13
+ return $.int(boolToUint8($.int(x, 32) === $.int(y, 32)))
14
+ }
15
+
16
+ export function LessOrEq(x: number, y: number): number {
17
+ return $.int(boolToUint8(x <= y))
18
+ }
19
+
20
+ function boolToUint8(b: boolean): number {
21
+ return b ? 1 : 0
22
+ }
@@ -2,7 +2,58 @@ import { describe, expect, it } from 'vitest'
2
2
 
3
3
  import * as $ from '@goscript/builtin/index.js'
4
4
 
5
- import { Read, Reader, Text } from './index.js'
5
+ import { Int, Prime, Read, Reader, Text } from './index.js'
6
+
7
+ class TestInt {
8
+ private value = 0
9
+
10
+ constructor(value = 0) {
11
+ this.value = value
12
+ }
13
+
14
+ Sign(): number {
15
+ return Math.sign(this.value)
16
+ }
17
+
18
+ BitLen(): number {
19
+ return this.value.toString(2).length
20
+ }
21
+
22
+ SetBytes(bytes: Uint8Array): TestInt {
23
+ this.value = 0
24
+ for (const b of bytes) {
25
+ this.value = this.value * 256 + b
26
+ }
27
+ return this
28
+ }
29
+
30
+ Cmp(other: TestInt): number {
31
+ return Math.sign(this.value - other.value)
32
+ }
33
+
34
+ Value(): number {
35
+ return this.value
36
+ }
37
+
38
+ ProbablyPrime(): boolean {
39
+ if (this.value < 2) {
40
+ return false
41
+ }
42
+ for (let i = 2; i * i <= this.value; i++) {
43
+ if (this.value % i === 0) {
44
+ return false
45
+ }
46
+ }
47
+ return true
48
+ }
49
+ }
50
+
51
+ TestInt.__typeInfo = $.registerStructType(
52
+ 'big.Int',
53
+ () => new TestInt(),
54
+ [],
55
+ TestInt,
56
+ )
6
57
 
7
58
  describe('crypto/rand override', () => {
8
59
  it('fills byte slices from Web Crypto', () => {
@@ -29,4 +80,41 @@ describe('crypto/rand override', () => {
29
80
  expect(token).toHaveLength(26)
30
81
  expect(token).toMatch(/^[A-Z2-7]+$/)
31
82
  })
83
+
84
+ it('generates integers below max from an io.Reader', () => {
85
+ const reader = {
86
+ Read(dst: Uint8Array): [number, $.GoError] {
87
+ dst[0] = 42
88
+ return [dst.length, null]
89
+ },
90
+ }
91
+
92
+ const [n, err] = Int(reader, new TestInt(100))
93
+
94
+ expect(err).toBeNull()
95
+ expect(n.Value()).toBe(42)
96
+ })
97
+
98
+ it('generates probable primes with the requested bit length', async () => {
99
+ const reader = {
100
+ Read(dst: Uint8Array): [number, $.GoError] {
101
+ dst.fill(0)
102
+ return [dst.length, null]
103
+ },
104
+ }
105
+
106
+ const [prime, err] = await Prime(reader, 8)
107
+
108
+ expect(err).toBeNull()
109
+ expect(prime.Value()).toBe(193)
110
+ expect(prime.BitLen()).toBe(8)
111
+ expect(prime.ProbablyPrime()).toBe(true)
112
+ })
113
+
114
+ it('rejects prime sizes below two bits', async () => {
115
+ const [prime, err] = await Prime(Reader, 1)
116
+
117
+ expect(prime).toBeNull()
118
+ expect(err?.Error()).toBe('crypto/rand: prime size must be at least 2-bit')
119
+ })
32
120
  })
@@ -35,6 +35,75 @@ export function Read(b: $.Bytes): [number, $.GoError] {
35
35
  return [n, null]
36
36
  }
37
37
 
38
+ export function Int(rand: io.Reader | null, max: any): [any, $.GoError] {
39
+ if (max == null || typeof max.Sign !== 'function' || max.Sign() <= 0) {
40
+ return [null, new RandError('crypto/rand: argument to Int is <= 0')]
41
+ }
42
+
43
+ const bitLen = max.BitLen()
44
+ const byteLen = Math.ceil(bitLen / 8)
45
+ const excessBits = byteLen * 8 - bitLen
46
+ const reader = rand ?? Reader
47
+
48
+ while (true) {
49
+ const bytes = new Uint8Array(byteLen)
50
+ const [n, err] = reader.Read(bytes)
51
+ if (err != null) {
52
+ return [null, err]
53
+ }
54
+ if (n !== byteLen) {
55
+ return [null, io.ErrUnexpectedEOF]
56
+ }
57
+ if (excessBits > 0) {
58
+ bytes[0] &= 0xff >>> excessBits
59
+ }
60
+
61
+ const candidate = new max.constructor()
62
+ candidate.SetBytes(bytes)
63
+ if (candidate.Cmp(max) < 0) {
64
+ return [candidate, null]
65
+ }
66
+ }
67
+ }
68
+
69
+ export async function Prime(
70
+ rand: io.Reader | null,
71
+ bits: number,
72
+ ): Promise<[any, $.GoError]> {
73
+ if (bits < 2) {
74
+ return [null, new RandError('crypto/rand: prime size must be at least 2-bit')]
75
+ }
76
+
77
+ const bitOffset = bits % 8
78
+ const topBits = bitOffset === 0 ? 8 : bitOffset
79
+ const bytes = new Uint8Array(Math.ceil(bits / 8))
80
+ const reader = rand ?? Reader
81
+
82
+ while (true) {
83
+ const err = readFull(reader, bytes)
84
+ if (err != null) {
85
+ return [null, err]
86
+ }
87
+
88
+ bytes[0] &= (1 << topBits) - 1
89
+ if (topBits >= 2) {
90
+ bytes[0] |= 3 << (topBits - 2)
91
+ } else {
92
+ bytes[0] |= 1
93
+ if (bytes.length > 1) {
94
+ bytes[1] |= 0x80
95
+ }
96
+ }
97
+ bytes[bytes.length - 1] |= 1
98
+
99
+ const candidate = newBigInt()
100
+ candidate.SetBytes(bytes)
101
+ if (await candidate.ProbablyPrime(20)) {
102
+ return [candidate, null]
103
+ }
104
+ }
105
+ }
106
+
38
107
  export function Text(): string {
39
108
  const src = new Uint8Array(26)
40
109
  const [, err] = Read(src)
@@ -49,6 +118,37 @@ export function Text(): string {
49
118
  return out
50
119
  }
51
120
 
121
+ function newBigInt(): any {
122
+ const info = $.getTypeByName('big.Int') as
123
+ | { zeroValue?: unknown; ctor?: new () => unknown }
124
+ | undefined
125
+ if (info?.zeroValue !== undefined) {
126
+ return typeof info.zeroValue === 'function'
127
+ ? (info.zeroValue as () => unknown)()
128
+ : info.zeroValue
129
+ }
130
+ if (info?.ctor != null) {
131
+ return new info.ctor()
132
+ }
133
+ throw new Error('crypto/rand: math/big.Int type is not registered')
134
+ }
135
+
136
+ function readFull(reader: io.Reader, dst: Uint8Array): $.GoError {
137
+ let offset = 0
138
+ while (offset < dst.length) {
139
+ const chunk = dst.subarray(offset)
140
+ const [n, err] = reader.Read(chunk)
141
+ if (err != null) {
142
+ return err
143
+ }
144
+ if (n <= 0) {
145
+ return io.ErrUnexpectedEOF
146
+ }
147
+ offset += n
148
+ }
149
+ return null
150
+ }
151
+
52
152
  function fillSecureBytes(dst: $.Bytes): $.GoError {
53
153
  const length = $.len(dst)
54
154
  if (length === 0) {
@@ -57,7 +157,9 @@ function fillSecureBytes(dst: $.Bytes): $.GoError {
57
157
 
58
158
  const crypto = secureCrypto()
59
159
  if (crypto == null) {
60
- return new RandError('crypto/rand: Web Crypto getRandomValues is unavailable')
160
+ return new RandError(
161
+ 'crypto/rand: Web Crypto getRandomValues is unavailable',
162
+ )
61
163
  }
62
164
 
63
165
  if (dst instanceof Uint8Array) {
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "dependencies": [
3
3
  "io"
4
- ]
4
+ ],
5
+ "asyncFunctions": {
6
+ "Prime": true
7
+ }
5
8
  }
@@ -0,0 +1,78 @@
1
+ import { describe, expect, test } from 'vitest'
2
+ import * as $ from '@goscript/builtin/index.js'
3
+
4
+ import { New, New224, Size, Size224, Sum224, Sum256 } from './index.js'
5
+
6
+ describe('crypto/sha256 override', () => {
7
+ test('sums with WebCrypto', async () => {
8
+ const sum = await Sum256($.stringToBytes('abc'))
9
+ expect(Array.from(sum)).toEqual([
10
+ 186, 120, 22, 191, 143, 1, 207, 234, 65, 65, 64, 222, 93, 174, 34, 35,
11
+ 176, 3, 97, 163, 150, 23, 122, 156, 180, 16, 255, 97, 242, 0, 21, 173,
12
+ ])
13
+ })
14
+
15
+ test('streaming digest appends to prefix', async () => {
16
+ const digest = New()
17
+ expect(digest.Write($.stringToBytes('a'))).toEqual([1, null])
18
+ expect(digest.Write($.stringToBytes('bc'))).toEqual([2, null])
19
+
20
+ const out = await digest.Sum(new Uint8Array([1, 2]))
21
+ expect(Array.from(out).slice(0, 2)).toEqual([1, 2])
22
+ expect(out.length).toBe(Size + 2)
23
+ expect(Array.from(out).slice(2)).toEqual(
24
+ Array.from(await Sum256($.stringToBytes('abc'))),
25
+ )
26
+ })
27
+
28
+ test('sums SHA-224 with host crypto', async () => {
29
+ const sum = await Sum224($.stringToBytes('abc'))
30
+ expect(Array.from(sum)).toEqual([
31
+ 35, 9, 125, 34, 52, 5, 216, 34, 134, 66, 164, 119, 189, 162, 85, 179,
32
+ 42, 173, 188, 228, 189, 160, 179, 247, 227, 108, 157, 167,
33
+ ])
34
+ })
35
+
36
+ test('streaming SHA-224 digest appends to prefix', async () => {
37
+ const digest = New224()
38
+ expect(digest.Write($.stringToBytes('a'))).toEqual([1, null])
39
+ expect(digest.Write($.stringToBytes('bc'))).toEqual([2, null])
40
+
41
+ const out = await digest.Sum(new Uint8Array([1, 2]))
42
+ expect(Array.from(out).slice(0, 2)).toEqual([1, 2])
43
+ expect(out.length).toBe(Size224 + 2)
44
+ expect(Array.from(out).slice(2)).toEqual(
45
+ Array.from(await Sum224($.stringToBytes('abc'))),
46
+ )
47
+ })
48
+
49
+ test('streaming Sum does not finalize the digest', async () => {
50
+ const digest = New()
51
+ expect(digest.Write($.stringToBytes('abc'))).toEqual([3, null])
52
+
53
+ const first = await digest.Sum(null)
54
+ expect(Array.from(first)).toEqual(
55
+ Array.from(await Sum256($.stringToBytes('abc'))),
56
+ )
57
+
58
+ expect(digest.Write($.stringToBytes('d'))).toEqual([1, null])
59
+ const second = await digest.Sum(null)
60
+ expect(Array.from(second)).toEqual(
61
+ Array.from(await Sum256($.stringToBytes('abcd'))),
62
+ )
63
+ })
64
+
65
+ test('streaming digest handles many small writes', async () => {
66
+ const digest = New()
67
+ let data = ''
68
+ for (let i = 0; i < 4096; i++) {
69
+ const part = `key-${i};`
70
+ data += part
71
+ expect(digest.Write($.stringToBytes(part))).toEqual([part.length, null])
72
+ }
73
+
74
+ expect(Array.from(await digest.Sum(null))).toEqual(
75
+ Array.from(await Sum256($.stringToBytes(data))),
76
+ )
77
+ })
78
+ })