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.
- package/cmd/goscript/cmd-test.go +104 -11
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript/cmd_compile.go +9 -0
- package/compiler/compile-request.go +31 -0
- package/compiler/compiler.go +1 -1
- package/compiler/compliance_test.go +0 -2
- package/compiler/config.go +2 -0
- package/compiler/gotest/package-result.go +2 -0
- package/compiler/gotest/request.go +85 -20
- package/compiler/gotest/runner.go +733 -96
- package/compiler/gotest/runner_test.go +647 -3
- package/compiler/lowered-program.go +9 -2
- package/compiler/lowering.go +2001 -345
- package/compiler/override-facts.go +77 -27
- package/compiler/override-registry.go +5 -4
- package/compiler/override-registry_test.go +135 -0
- package/compiler/package-graph_test.go +62 -7
- package/compiler/package-test-graph-variant.go +40 -16
- package/compiler/package-test-graph.go +0 -5
- package/compiler/package-test-graph_test.go +61 -3
- package/compiler/runtime-contract.go +40 -0
- package/compiler/semantic-model-types.go +16 -0
- package/compiler/semantic-model.go +336 -91
- package/compiler/semantic-model_test.go +50 -1
- package/compiler/service.go +9 -3
- package/compiler/skeleton_test.go +1921 -298
- package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
- package/compiler/tsworkspace/owner.go +8 -0
- package/compiler/tsworkspace/tool-process-other.go +14 -0
- package/compiler/tsworkspace/tool-process-unix.go +19 -0
- package/compiler/typescript-emitter.go +122 -9
- package/dist/gs/builtin/builtin.d.ts +20 -1
- package/dist/gs/builtin/builtin.js +246 -26
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +24 -10
- package/dist/gs/builtin/channel.js +107 -25
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/defer.d.ts +1 -0
- package/dist/gs/builtin/defer.js +12 -2
- package/dist/gs/builtin/defer.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +9 -0
- package/dist/gs/builtin/hostio.js +25 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/map.js +40 -6
- package/dist/gs/builtin/map.js.map +1 -1
- package/dist/gs/builtin/print.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +43 -9
- package/dist/gs/builtin/slice.js +437 -234
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +2 -0
- package/dist/gs/builtin/type.js +47 -7
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +2 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +28 -28
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/iter.gs.js +13 -13
- package/dist/gs/bytes/iter.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +26 -0
- package/dist/gs/compress/zlib/index.js +168 -0
- package/dist/gs/compress/zlib/index.js.map +1 -0
- package/dist/gs/context/context.d.ts +1 -1
- package/dist/gs/context/context.js +8 -3
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/ecdh/index.d.ts +52 -0
- package/dist/gs/crypto/ecdh/index.js +226 -0
- package/dist/gs/crypto/ecdh/index.js.map +1 -0
- package/dist/gs/crypto/ed25519/index.d.ts +34 -0
- package/dist/gs/crypto/ed25519/index.js +160 -0
- package/dist/gs/crypto/ed25519/index.js.map +1 -0
- package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
- package/dist/gs/crypto/internal/constanttime/index.js +18 -0
- package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
- package/dist/gs/crypto/rand/index.d.ts +2 -0
- package/dist/gs/crypto/rand/index.js +85 -0
- package/dist/gs/crypto/rand/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.d.ts +8 -0
- package/dist/gs/crypto/sha256/index.js +118 -0
- package/dist/gs/crypto/sha256/index.js.map +1 -0
- package/dist/gs/crypto/sha512/index.d.ts +14 -0
- package/dist/gs/crypto/sha512/index.js +129 -0
- package/dist/gs/crypto/sha512/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +3 -0
- package/dist/gs/encoding/json/index.js +15 -0
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.js +29 -6
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +7 -7
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +52 -18
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +56 -20
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +57 -3
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +366 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +3 -2
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -1
- package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
- package/dist/gs/go/token/index.js +11 -4
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/fnv/index.d.ts +57 -0
- package/dist/gs/hash/fnv/index.js +299 -0
- package/dist/gs/hash/fnv/index.js.map +1 -0
- package/dist/gs/hash/index.d.ts +17 -0
- package/dist/gs/hash/index.js +94 -0
- package/dist/gs/hash/index.js.map +1 -0
- package/dist/gs/io/fs/readlink.js +2 -6
- package/dist/gs/io/fs/readlink.js.map +1 -1
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/iter/iter.d.ts +3 -2
- package/dist/gs/iter/iter.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +5 -5
- package/dist/gs/maps/iter.js +48 -21
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +6 -6
- package/dist/gs/math/bits/index.js +14 -24
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.js +3 -1
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +20 -1
- package/dist/gs/net/http/httptest/index.js +83 -3
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +110 -6
- package/dist/gs/net/http/index.js +262 -16
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/net/http/pprof/index.d.ts +8 -0
- package/dist/gs/net/http/pprof/index.js +59 -0
- package/dist/gs/net/http/pprof/index.js.map +1 -0
- package/dist/gs/os/error.gs.js +9 -7
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +95 -15
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +5 -3
- package/dist/gs/path/filepath/path.js +65 -10
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +3 -2
- package/dist/gs/reflect/index.js +2 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/iter.js +2 -2
- package/dist/gs/reflect/iter.js.map +1 -1
- package/dist/gs/reflect/map.js +26 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +24 -5
- package/dist/gs/reflect/type.js +390 -38
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +1 -0
- package/dist/gs/reflect/types.js +3 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +4 -1
- package/dist/gs/reflect/value.js +39 -1
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +1 -1
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +39 -0
- package/dist/gs/runtime/debug/index.js +58 -0
- package/dist/gs/runtime/debug/index.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +20 -0
- package/dist/gs/runtime/pprof/index.js +85 -0
- package/dist/gs/runtime/pprof/index.js.map +1 -0
- package/dist/gs/runtime/trace/index.d.ts +19 -0
- package/dist/gs/runtime/trace/index.js +64 -0
- package/dist/gs/runtime/trace/index.js.map +1 -0
- package/dist/gs/slices/slices.d.ts +24 -9
- package/dist/gs/slices/slices.js +229 -24
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +5 -3
- package/dist/gs/sort/slice.gs.js +55 -17
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/strings/builder.js +26 -17
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/strings/iter.js +140 -75
- package/dist/gs/strings/iter.js.map +1 -1
- package/dist/gs/strings/replace.js +2 -2
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.js +52 -6
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +6 -3
- package/dist/gs/sync/sync.js +39 -11
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +116 -112
- package/dist/gs/syscall/errors.js +38 -1
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +2 -8
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.js +20 -12
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/syscall/types.d.ts +4 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/testing.d.ts +4 -3
- package/dist/gs/testing/testing.js +21 -4
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.js +22 -0
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unique/index.js +7 -2
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +8 -8
- package/go.sum +14 -23
- package/gs/builtin/builtin.ts +364 -37
- package/gs/builtin/channel.ts +161 -29
- package/gs/builtin/defer.ts +13 -2
- package/gs/builtin/hostio.test.ts +1 -0
- package/gs/builtin/hostio.ts +38 -0
- package/gs/builtin/map.ts +46 -6
- package/gs/builtin/print.ts +12 -3
- package/gs/builtin/runtime-contract.test.ts +257 -10
- package/gs/builtin/slice.test.ts +70 -0
- package/gs/builtin/slice.ts +566 -255
- package/gs/builtin/type.ts +53 -9
- package/gs/builtin/varRef.ts +2 -0
- package/gs/bytes/buffer.gs.ts +28 -28
- package/gs/bytes/iter.gs.ts +13 -14
- package/gs/compress/zlib/index.test.ts +28 -0
- package/gs/compress/zlib/index.ts +200 -0
- package/gs/compress/zlib/meta.json +3 -0
- package/gs/context/context.test.ts +31 -1
- package/gs/context/context.ts +9 -4
- package/gs/crypto/ecdh/index.test.ts +43 -0
- package/gs/crypto/ecdh/index.ts +274 -0
- package/gs/crypto/ed25519/index.test.ts +41 -0
- package/gs/crypto/ed25519/index.ts +238 -0
- package/gs/crypto/ed25519/meta.json +13 -0
- package/gs/crypto/internal/constanttime/index.test.ts +25 -0
- package/gs/crypto/internal/constanttime/index.ts +22 -0
- package/gs/crypto/rand/index.test.ts +89 -1
- package/gs/crypto/rand/index.ts +103 -1
- package/gs/crypto/rand/meta.json +4 -1
- package/gs/crypto/sha256/index.test.ts +78 -0
- package/gs/crypto/sha256/index.ts +150 -0
- package/gs/crypto/sha256/meta.json +9 -0
- package/gs/crypto/sha512/index.test.ts +31 -0
- package/gs/crypto/sha512/index.ts +161 -0
- package/gs/crypto/sha512/meta.json +11 -0
- package/gs/encoding/json/index.test.ts +25 -3
- package/gs/encoding/json/index.ts +21 -3
- package/gs/errors/errors.test.ts +4 -1
- package/gs/errors/errors.ts +32 -8
- package/gs/fmt/fmt.test.ts +3 -1
- package/gs/fmt/fmt.ts +1 -5
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +62 -7
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +78 -36
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +32 -11
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +122 -43
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +518 -4
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +6 -0
- package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
- package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
- package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
- package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
- package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +2 -1
- package/gs/github.com/klauspost/compress/internal/le/index.ts +6 -5
- package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
- package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
- package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
- package/gs/go/token/index.ts +17 -4
- package/gs/hash/fnv/index.test.ts +67 -0
- package/gs/hash/fnv/index.ts +351 -0
- package/gs/hash/fnv/meta.json +3 -0
- package/gs/hash/index.test.ts +37 -0
- package/gs/hash/index.ts +118 -0
- package/gs/hash/meta.json +5 -0
- package/gs/internal/byteorder/index.test.ts +6 -6
- package/gs/io/fs/readlink.ts +40 -48
- package/gs/io/fs/walk.ts +10 -2
- package/gs/io/io.ts +4 -1
- package/gs/iter/iter.ts +8 -2
- package/gs/maps/iter.ts +69 -26
- package/gs/maps/maps.test.ts +23 -0
- package/gs/maps/maps.ts +6 -6
- package/gs/math/bits/index.test.ts +20 -0
- package/gs/math/bits/index.ts +15 -28
- package/gs/mime/index.ts +8 -2
- package/gs/net/http/httptest/index.test.ts +53 -0
- package/gs/net/http/httptest/index.ts +98 -3
- package/gs/net/http/index.test.ts +129 -1
- package/gs/net/http/index.ts +370 -19
- package/gs/net/http/meta.json +6 -0
- package/gs/net/http/pprof/index.test.ts +47 -0
- package/gs/net/http/pprof/index.ts +65 -0
- package/gs/os/error.gs.ts +9 -10
- package/gs/os/error.test.ts +41 -0
- package/gs/os/file_unix_js.test.ts +55 -0
- package/gs/os/tempfile.gs.test.ts +37 -10
- package/gs/os/types_js.gs.ts +94 -15
- package/gs/path/filepath/match.ts +4 -1
- package/gs/path/filepath/meta.json +6 -0
- package/gs/path/filepath/path.test.ts +57 -2
- package/gs/path/filepath/path.ts +91 -12
- package/gs/reflect/field.test.ts +63 -0
- package/gs/reflect/index.ts +4 -1
- package/gs/reflect/iter.ts +2 -2
- package/gs/reflect/map.test.ts +24 -2
- package/gs/reflect/map.ts +35 -0
- package/gs/reflect/type.ts +543 -60
- package/gs/reflect/typefor.test.ts +100 -0
- package/gs/reflect/types.ts +3 -1
- package/gs/reflect/value.ts +50 -1
- package/gs/reflect/visiblefields.ts +1 -1
- package/gs/runtime/debug/index.test.ts +22 -1
- package/gs/runtime/debug/index.ts +88 -0
- package/gs/runtime/pprof/index.test.ts +36 -0
- package/gs/runtime/pprof/index.ts +104 -0
- package/gs/runtime/pprof/meta.json +6 -0
- package/gs/runtime/trace/index.test.ts +45 -0
- package/gs/runtime/trace/index.ts +97 -0
- package/gs/runtime/trace/meta.json +7 -0
- package/gs/slices/meta.json +2 -1
- package/gs/slices/slices.test.ts +86 -0
- package/gs/slices/slices.ts +284 -37
- package/gs/sort/slice.gs.ts +73 -23
- package/gs/sort/slice.test.ts +40 -0
- package/gs/strings/builder.test.ts +8 -0
- package/gs/strings/builder.ts +29 -17
- package/gs/strings/iter.test.ts +5 -7
- package/gs/strings/iter.ts +146 -71
- package/gs/strings/replace.test.ts +1 -4
- package/gs/strings/replace.ts +6 -6
- package/gs/strings/strings.test.ts +4 -0
- package/gs/strings/strings.ts +54 -6
- package/gs/sync/sync.test.ts +57 -1
- package/gs/sync/sync.ts +45 -13
- package/gs/syscall/errors.ts +158 -115
- package/gs/syscall/fs.ts +8 -8
- package/gs/syscall/js/index.ts +49 -22
- package/gs/syscall/net.test.ts +26 -0
- package/gs/syscall/types.ts +7 -2
- package/gs/testing/testing.test.ts +56 -0
- package/gs/testing/testing.ts +27 -10
- package/gs/time/meta.json +2 -2
- package/gs/time/time.test.ts +4 -0
- package/gs/time/time.ts +33 -2
- package/gs/unicode/unicode.test.ts +14 -3
- package/gs/unicode/unicode.ts +1 -5
- package/gs/unique/index.ts +9 -2
- package/package.json +3 -3
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
import * as errors from '@goscript/errors/index.js'
|
|
3
|
+
import * as io from '@goscript/io/index.js'
|
|
4
|
+
|
|
5
|
+
export type Resetter = {
|
|
6
|
+
Reset(r: io.Reader | null, dict: $.Bytes | null): Promise<$.GoError>
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export let ErrChecksum = errors.New('zlib: invalid checksum')
|
|
10
|
+
export let ErrDictionary = errors.New('zlib: invalid dictionary')
|
|
11
|
+
export let ErrHeader = errors.New('zlib: invalid header')
|
|
12
|
+
|
|
13
|
+
export function __goscript_set_ErrChecksum(value: $.GoError): void {
|
|
14
|
+
ErrChecksum = value
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function __goscript_set_ErrDictionary(value: $.GoError): void {
|
|
18
|
+
ErrDictionary = value
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function __goscript_set_ErrHeader(value: $.GoError): void {
|
|
22
|
+
ErrHeader = value
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class zlibReader implements io.ReadCloser {
|
|
26
|
+
private offset = 0
|
|
27
|
+
|
|
28
|
+
constructor(private data: Uint8Array) {}
|
|
29
|
+
|
|
30
|
+
Read(p: $.Bytes): [number, $.GoError] {
|
|
31
|
+
if (this.offset >= this.data.length) {
|
|
32
|
+
return [0, io.EOF]
|
|
33
|
+
}
|
|
34
|
+
const out = $.bytesToUint8Array(p)
|
|
35
|
+
const n = Math.min(out.length, this.data.length - this.offset)
|
|
36
|
+
out.set(this.data.subarray(this.offset, this.offset + n))
|
|
37
|
+
this.offset += n
|
|
38
|
+
return [n, null]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
Close(): $.GoError {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class Writer {
|
|
47
|
+
private chunks: Uint8Array[] = []
|
|
48
|
+
private closed = false
|
|
49
|
+
|
|
50
|
+
constructor(private w: io.Writer | null) {}
|
|
51
|
+
|
|
52
|
+
Write(p: $.Bytes): [number, $.GoError] {
|
|
53
|
+
if (this.closed) {
|
|
54
|
+
return [0, errors.New('zlib: writer closed')]
|
|
55
|
+
}
|
|
56
|
+
const data = $.bytesToUint8Array(p)
|
|
57
|
+
this.chunks.push(data.slice())
|
|
58
|
+
return [data.length, null]
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
Close(): $.GoError {
|
|
62
|
+
if (this.closed) {
|
|
63
|
+
return null
|
|
64
|
+
}
|
|
65
|
+
this.closed = true
|
|
66
|
+
if (this.w == null) {
|
|
67
|
+
return errors.New('zlib: nil writer')
|
|
68
|
+
}
|
|
69
|
+
const compressed = deflate(concat(this.chunks))
|
|
70
|
+
const [, err] = this.w.Write(compressed)
|
|
71
|
+
return err
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Flush(): $.GoError {
|
|
75
|
+
return null
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
Reset(w: io.Writer | null): void {
|
|
79
|
+
this.w = w
|
|
80
|
+
this.chunks = []
|
|
81
|
+
this.closed = false
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function NewWriter(w: io.Writer | null): Writer {
|
|
86
|
+
return new Writer(w)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function NewWriterLevel(
|
|
90
|
+
w: io.Writer | null,
|
|
91
|
+
_level: number,
|
|
92
|
+
): [Writer | null, $.GoError] {
|
|
93
|
+
return [new Writer(w), null]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function NewWriterLevelDict(
|
|
97
|
+
w: io.Writer | null,
|
|
98
|
+
_level: number,
|
|
99
|
+
_dict: $.Bytes | null,
|
|
100
|
+
): [Writer | null, $.GoError] {
|
|
101
|
+
return [new Writer(w), null]
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function NewReader(
|
|
105
|
+
r: io.Reader | null,
|
|
106
|
+
): [io.ReadCloser | null, $.GoError] {
|
|
107
|
+
return NewReaderDict(r, null)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function NewReaderDict(
|
|
111
|
+
r: io.Reader | null,
|
|
112
|
+
_dict: $.Bytes | null,
|
|
113
|
+
): [io.ReadCloser | null, $.GoError] {
|
|
114
|
+
if (r == null) {
|
|
115
|
+
return [null, errors.New('zlib: nil reader')]
|
|
116
|
+
}
|
|
117
|
+
const [data, readErr] = readAll(r)
|
|
118
|
+
if (readErr != null) {
|
|
119
|
+
return [null, readErr]
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
const out = inflate($.bytesToUint8Array(data))
|
|
123
|
+
return [new zlibReader(out), null]
|
|
124
|
+
} catch {
|
|
125
|
+
return [null, ErrHeader]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function deflate(data: Uint8Array): Uint8Array {
|
|
130
|
+
const zlib = nodeZlib()
|
|
131
|
+
return new Uint8Array(zlib.deflateSync(data))
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function inflate(data: Uint8Array): Uint8Array {
|
|
135
|
+
const zlib = nodeZlib()
|
|
136
|
+
return new Uint8Array(zlib.inflateSync(data))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function nodeZlib(): any {
|
|
140
|
+
const processObj = (globalThis as any).process
|
|
141
|
+
if (processObj && typeof processObj.getBuiltinModule === 'function') {
|
|
142
|
+
const mod = processObj.getBuiltinModule('zlib')
|
|
143
|
+
if (mod && typeof mod.deflateSync === 'function') {
|
|
144
|
+
return mod
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const requireFn = (() => {
|
|
148
|
+
try {
|
|
149
|
+
return Function(
|
|
150
|
+
"return typeof require !== 'undefined' ? require : null",
|
|
151
|
+
)() as ((specifier: string) => unknown) | null
|
|
152
|
+
} catch {
|
|
153
|
+
return null
|
|
154
|
+
}
|
|
155
|
+
})()
|
|
156
|
+
if (requireFn != null) {
|
|
157
|
+
for (const specifier of ['node:zlib', 'zlib']) {
|
|
158
|
+
try {
|
|
159
|
+
const mod = requireFn(specifier) as any
|
|
160
|
+
if (mod && typeof mod.deflateSync === 'function') {
|
|
161
|
+
return mod
|
|
162
|
+
}
|
|
163
|
+
} catch {
|
|
164
|
+
// Try the next fallback.
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
throw new Error('compress/zlib: node zlib module unavailable')
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function readAll(r: io.Reader): [Uint8Array, $.GoError] {
|
|
172
|
+
const chunks: Uint8Array[] = []
|
|
173
|
+
const buf = $.makeSlice<number>(32 * 1024, undefined, 'byte')
|
|
174
|
+
while (true) {
|
|
175
|
+
const [n, err] = r.Read(buf)
|
|
176
|
+
if (n > 0) {
|
|
177
|
+
chunks.push($.bytesToUint8Array($.goSlice(buf, 0, n)).slice())
|
|
178
|
+
}
|
|
179
|
+
if (err != null) {
|
|
180
|
+
if (err === io.EOF) {
|
|
181
|
+
return [concat(chunks), null]
|
|
182
|
+
}
|
|
183
|
+
return [new Uint8Array(0), err]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function concat(chunks: Uint8Array[]): Uint8Array {
|
|
189
|
+
let total = 0
|
|
190
|
+
for (const chunk of chunks) {
|
|
191
|
+
total += chunk.length
|
|
192
|
+
}
|
|
193
|
+
const out = new Uint8Array(total)
|
|
194
|
+
let offset = 0
|
|
195
|
+
for (const chunk of chunks) {
|
|
196
|
+
out.set(chunk, offset)
|
|
197
|
+
offset += chunk.length
|
|
198
|
+
}
|
|
199
|
+
return out
|
|
200
|
+
}
|
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
4
|
+
|
|
5
|
+
import { AfterFunc, WithCancel, Background, WithValue } from './index.js'
|
|
4
6
|
|
|
5
7
|
async function nextMicrotask(): Promise<void> {
|
|
6
8
|
await new Promise<void>((resolve) => queueMicrotask(resolve))
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
describe('context override', () => {
|
|
12
|
+
it('matches generated struct keys by Go comparable value', () => {
|
|
13
|
+
class Key {
|
|
14
|
+
public _fields: Record<string, $.VarRef<unknown>>
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
this._fields = {}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const ctx = WithValue(
|
|
22
|
+
Background(),
|
|
23
|
+
$.interfaceValue($.markAsStructValue(new Key()), 'example.key'),
|
|
24
|
+
'stored',
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
expect(
|
|
28
|
+
ctx.Value($.interfaceValue($.markAsStructValue(new Key()), 'example.key')),
|
|
29
|
+
).toBe('stored')
|
|
30
|
+
})
|
|
31
|
+
|
|
10
32
|
it('runs AfterFunc after cancellation', async () => {
|
|
11
33
|
const [ctx, cancel] = WithCancel(Background())
|
|
12
34
|
let called = false
|
|
@@ -38,4 +60,12 @@ describe('context override', () => {
|
|
|
38
60
|
|
|
39
61
|
expect(called).toBe(false)
|
|
40
62
|
})
|
|
63
|
+
|
|
64
|
+
it('accepts nil AfterFunc callbacks for type compatibility', () => {
|
|
65
|
+
const [ctx] = WithCancel(Background())
|
|
66
|
+
|
|
67
|
+
const stop = AfterFunc(ctx, null)
|
|
68
|
+
|
|
69
|
+
expect(stop()).toBe(true)
|
|
70
|
+
})
|
|
41
71
|
})
|
package/gs/context/context.ts
CHANGED
|
@@ -87,7 +87,7 @@ class valueContext extends baseContext {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
Value(key: any): any {
|
|
90
|
-
if (this.key === key) {
|
|
90
|
+
if (this.key === key || $.comparableEqual(this.key, key)) {
|
|
91
91
|
return this.val
|
|
92
92
|
}
|
|
93
93
|
return this.parent.Value(key)
|
|
@@ -388,8 +388,8 @@ export function Cause(ctx: Context): $.GoError {
|
|
|
388
388
|
return c.Err()
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
// AfterFunc runs f in a separate goroutine after ctx is done
|
|
392
|
-
export function AfterFunc(ctx: Context, f: () => void): () => boolean {
|
|
391
|
+
// AfterFunc runs f in a separate goroutine after ctx is done.
|
|
392
|
+
export function AfterFunc(ctx: Context, f: (() => void) | null): () => boolean {
|
|
393
393
|
if (ctx === null) {
|
|
394
394
|
throw new Error('cannot create context from nil parent')
|
|
395
395
|
}
|
|
@@ -405,7 +405,12 @@ export function AfterFunc(ctx: Context, f: () => void): () => boolean {
|
|
|
405
405
|
if (!stopped) {
|
|
406
406
|
done = true
|
|
407
407
|
// Run in next tick to simulate goroutine
|
|
408
|
-
queueMicrotask(
|
|
408
|
+
queueMicrotask(() => {
|
|
409
|
+
if (f === null) {
|
|
410
|
+
throw new Error('context: nil AfterFunc callback')
|
|
411
|
+
}
|
|
412
|
+
f()
|
|
413
|
+
})
|
|
409
414
|
}
|
|
410
415
|
})()
|
|
411
416
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { X25519 } from './index.js'
|
|
4
|
+
|
|
5
|
+
describe('crypto/ecdh override', () => {
|
|
6
|
+
it('matches the RFC 7748 X25519 test vector', () => {
|
|
7
|
+
const curve = X25519()
|
|
8
|
+
const [alice, aliceErr] = curve.NewPrivateKey(
|
|
9
|
+
hex('77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a'),
|
|
10
|
+
)
|
|
11
|
+
const [bobPub, bobPubErr] = curve.NewPublicKey(
|
|
12
|
+
hex('de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f'),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
expect(aliceErr).toBeNull()
|
|
16
|
+
expect(bobPubErr).toBeNull()
|
|
17
|
+
expect(toHex(alice!.PublicKey().Bytes())).toBe(
|
|
18
|
+
'8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a',
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
const [shared, sharedErr] = alice!.ECDH(bobPub)
|
|
22
|
+
expect(sharedErr).toBeNull()
|
|
23
|
+
expect(toHex(shared)).toBe(
|
|
24
|
+
'4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742',
|
|
25
|
+
)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('rejects low-order remote points', () => {
|
|
29
|
+
const [priv] = X25519().NewPrivateKey(new Uint8Array(32).fill(7))
|
|
30
|
+
const [zero] = X25519().NewPublicKey(new Uint8Array(32))
|
|
31
|
+
const [, err] = priv!.ECDH(zero)
|
|
32
|
+
|
|
33
|
+
expect(err?.Error()).toContain('low order point')
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
function hex(value: string): Uint8Array {
|
|
38
|
+
return new Uint8Array(value.match(/../g)!.map((byte) => Number.parseInt(byte, 16)))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function toHex(value: Uint8Array | null): string {
|
|
42
|
+
return Array.from(value ?? [], (byte) => byte.toString(16).padStart(2, '0')).join('')
|
|
43
|
+
}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
import * as io from '@goscript/io/index.js'
|
|
3
|
+
|
|
4
|
+
export type Curve = x25519Curve | unsupportedCurve
|
|
5
|
+
export type KeyExchanger = PrivateKey
|
|
6
|
+
|
|
7
|
+
const x25519PublicKeySize = 32
|
|
8
|
+
const x25519PrivateKeySize = 32
|
|
9
|
+
const x25519SharedSecretSize = 32
|
|
10
|
+
const p = (1n << 255n) - 19n
|
|
11
|
+
const a24 = 121665n
|
|
12
|
+
|
|
13
|
+
export class PublicKey {
|
|
14
|
+
public curve: Curve
|
|
15
|
+
public publicKey: $.Bytes
|
|
16
|
+
|
|
17
|
+
constructor(init?: Partial<{ curve: Curve; publicKey: $.Bytes }>) {
|
|
18
|
+
this.curve = init?.curve ?? x25519
|
|
19
|
+
this.publicKey = copyBytes(init?.publicKey ?? null)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public Bytes(): $.Bytes {
|
|
23
|
+
return copyBytes(this.publicKey)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public Curve(): Curve {
|
|
27
|
+
return this.curve
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public Equal(x: PublicKey | $.VarRef<PublicKey> | null): boolean {
|
|
31
|
+
const other = $.pointerValueOrNil(x)
|
|
32
|
+
return other instanceof PublicKey && bytesEqual(this.publicKey, other.publicKey)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class PrivateKey {
|
|
37
|
+
public curve: Curve
|
|
38
|
+
public privateKey: $.Bytes
|
|
39
|
+
public publicKey: PublicKey
|
|
40
|
+
|
|
41
|
+
constructor(
|
|
42
|
+
init?: Partial<{ curve: Curve; privateKey: $.Bytes; publicKey: PublicKey }>,
|
|
43
|
+
) {
|
|
44
|
+
this.curve = init?.curve ?? x25519
|
|
45
|
+
this.privateKey = copyBytes(init?.privateKey ?? null)
|
|
46
|
+
this.publicKey = init?.publicKey ?? new PublicKey({ curve: this.curve })
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public Bytes(): $.Bytes {
|
|
50
|
+
return copyBytes(this.privateKey)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public Curve(): Curve {
|
|
54
|
+
return this.curve
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public ECDH(remote: PublicKey | $.VarRef<PublicKey> | null): [$.Bytes, $.GoError] {
|
|
58
|
+
const remoteKey = $.pointerValueOrNil(remote)
|
|
59
|
+
if (remoteKey == null || remoteKey.curve !== this.curve) {
|
|
60
|
+
return [null, $.newError('crypto/ecdh: private key and public key curves do not match')]
|
|
61
|
+
}
|
|
62
|
+
return this.curve.ecdh(this, remoteKey)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public Equal(x: PrivateKey | $.VarRef<PrivateKey> | null): boolean {
|
|
66
|
+
const other = $.pointerValueOrNil(x)
|
|
67
|
+
return other instanceof PrivateKey && bytesEqual(this.privateKey, other.privateKey)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public Public(): PublicKey {
|
|
71
|
+
return this.publicKey
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public PublicKey(): PublicKey {
|
|
75
|
+
return this.publicKey
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export class x25519Curve {
|
|
80
|
+
public GenerateKey(r: io.Reader | null): [PrivateKey | null, $.GoError] {
|
|
81
|
+
const key = new Uint8Array(x25519PrivateKeySize)
|
|
82
|
+
if (r != null) {
|
|
83
|
+
throw new Error('crypto/ecdh: custom random readers are not implemented in GoScript')
|
|
84
|
+
}
|
|
85
|
+
globalThis.crypto.getRandomValues(key)
|
|
86
|
+
return this.NewPrivateKey(key)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public NewPrivateKey(key: $.Bytes): [PrivateKey | null, $.GoError] {
|
|
90
|
+
if ($.len(key) !== x25519PrivateKeySize) {
|
|
91
|
+
return [null, $.newError('crypto/ecdh: invalid private key size')]
|
|
92
|
+
}
|
|
93
|
+
const privateKey = copyBytes(key)
|
|
94
|
+
const publicKey = scalarMult(privateKey, basepoint())
|
|
95
|
+
return [
|
|
96
|
+
new PrivateKey({
|
|
97
|
+
curve: this,
|
|
98
|
+
privateKey,
|
|
99
|
+
publicKey: new PublicKey({ curve: this, publicKey }),
|
|
100
|
+
}),
|
|
101
|
+
null,
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public NewPublicKey(key: $.Bytes): [PublicKey | null, $.GoError] {
|
|
106
|
+
if ($.len(key) !== x25519PublicKeySize) {
|
|
107
|
+
return [null, $.newError('crypto/ecdh: invalid public key')]
|
|
108
|
+
}
|
|
109
|
+
return [new PublicKey({ curve: this, publicKey: key }), null]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public String(): string {
|
|
113
|
+
return 'X25519'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public ecdh(local: PrivateKey | null, remote: PublicKey | null): [$.Bytes, $.GoError] {
|
|
117
|
+
const out = scalarMult(local?.privateKey ?? null, remote?.publicKey ?? null)
|
|
118
|
+
if (isZero(out)) {
|
|
119
|
+
return [null, $.newError('crypto/ecdh: bad X25519 remote ECDH input: low order point')]
|
|
120
|
+
}
|
|
121
|
+
return [out, null]
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function X25519(): Curve {
|
|
126
|
+
return x25519
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export const x25519 = new x25519Curve()
|
|
130
|
+
|
|
131
|
+
export class unsupportedCurve {
|
|
132
|
+
constructor(private readonly name: string) {}
|
|
133
|
+
|
|
134
|
+
public GenerateKey(_r: io.Reader | null): [PrivateKey | null, $.GoError] {
|
|
135
|
+
return [null, $.newError(`crypto/ecdh: ${this.name} is not implemented in GoScript`)]
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public NewPrivateKey(_key: $.Bytes): [PrivateKey | null, $.GoError] {
|
|
139
|
+
return [null, $.newError(`crypto/ecdh: ${this.name} is not implemented in GoScript`)]
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public NewPublicKey(_key: $.Bytes): [PublicKey | null, $.GoError] {
|
|
143
|
+
return [null, $.newError(`crypto/ecdh: ${this.name} is not implemented in GoScript`)]
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public String(): string {
|
|
147
|
+
return this.name
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public ecdh(_local: PrivateKey | null, _remote: PublicKey | null): [$.Bytes, $.GoError] {
|
|
151
|
+
return [null, $.newError(`crypto/ecdh: ${this.name} is not implemented in GoScript`)]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function P256(): Curve {
|
|
156
|
+
return p256
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function P384(): Curve {
|
|
160
|
+
return p384
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function P521(): Curve {
|
|
164
|
+
return p521
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const p256 = new unsupportedCurve('P-256')
|
|
168
|
+
const p384 = new unsupportedCurve('P-384')
|
|
169
|
+
const p521 = new unsupportedCurve('P-521')
|
|
170
|
+
|
|
171
|
+
function scalarMult(scalar: $.Bytes, point: $.Bytes): Uint8Array {
|
|
172
|
+
const e = copyBytes(scalar)
|
|
173
|
+
const uBytes = copyBytes(point)
|
|
174
|
+
e[0] &= 248
|
|
175
|
+
e[31] &= 127
|
|
176
|
+
e[31] |= 64
|
|
177
|
+
uBytes[31] &= 127
|
|
178
|
+
|
|
179
|
+
const x1 = decodeLittleEndian(uBytes)
|
|
180
|
+
let x2 = 1n
|
|
181
|
+
let z2 = 0n
|
|
182
|
+
let x3 = x1
|
|
183
|
+
let z3 = 1n
|
|
184
|
+
let swap = 0n
|
|
185
|
+
|
|
186
|
+
for (let t = 254; t >= 0; t--) {
|
|
187
|
+
const k = (BigInt(e[Math.floor(t / 8)]) >> BigInt(t & 7)) & 1n
|
|
188
|
+
swap ^= k
|
|
189
|
+
;[x2, x3] = cswap(swap, x2, x3)
|
|
190
|
+
;[z2, z3] = cswap(swap, z2, z3)
|
|
191
|
+
swap = k
|
|
192
|
+
|
|
193
|
+
const a = mod(x2 + z2)
|
|
194
|
+
const aa = mod(a * a)
|
|
195
|
+
const b = mod(x2 - z2)
|
|
196
|
+
const bb = mod(b * b)
|
|
197
|
+
const eDiff = mod(aa - bb)
|
|
198
|
+
const c = mod(x3 + z3)
|
|
199
|
+
const d = mod(x3 - z3)
|
|
200
|
+
const da = mod(d * a)
|
|
201
|
+
const cb = mod(c * b)
|
|
202
|
+
x3 = mod((da + cb) ** 2n)
|
|
203
|
+
z3 = mod(x1 * mod((da - cb) ** 2n))
|
|
204
|
+
x2 = mod(aa * bb)
|
|
205
|
+
z2 = mod(eDiff * mod(aa + a24 * eDiff))
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
x2 = cswap(swap, x2, x3)[0]
|
|
209
|
+
z2 = cswap(swap, z2, z3)[0]
|
|
210
|
+
|
|
211
|
+
return encodeLittleEndian(mod(x2 * modInverse(z2)))
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function cswap(swap: bigint, x: bigint, y: bigint): [bigint, bigint] {
|
|
215
|
+
const mask = -swap
|
|
216
|
+
const t = mask & (x ^ y)
|
|
217
|
+
return [x ^ t, y ^ t]
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function mod(value: bigint): bigint {
|
|
221
|
+
const result = value % p
|
|
222
|
+
return result >= 0n ? result : result + p
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function modInverse(value: bigint): bigint {
|
|
226
|
+
let lm = 1n
|
|
227
|
+
let hm = 0n
|
|
228
|
+
let low = mod(value)
|
|
229
|
+
let high = p
|
|
230
|
+
while (low > 1n) {
|
|
231
|
+
const r = high / low
|
|
232
|
+
;[lm, hm] = [hm - lm * r, lm]
|
|
233
|
+
;[low, high] = [high - low * r, low]
|
|
234
|
+
}
|
|
235
|
+
return mod(lm)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function decodeLittleEndian(bytes: Uint8Array): bigint {
|
|
239
|
+
let out = 0n
|
|
240
|
+
for (let i = bytes.length - 1; i >= 0; i--) {
|
|
241
|
+
out = (out << 8n) | BigInt(bytes[i])
|
|
242
|
+
}
|
|
243
|
+
return out
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function encodeLittleEndian(value: bigint): Uint8Array {
|
|
247
|
+
const out = new Uint8Array(x25519SharedSecretSize)
|
|
248
|
+
let v = mod(value)
|
|
249
|
+
for (let i = 0; i < out.length; i++) {
|
|
250
|
+
out[i] = Number(v & 0xffn)
|
|
251
|
+
v >>= 8n
|
|
252
|
+
}
|
|
253
|
+
return out
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function basepoint(): Uint8Array {
|
|
257
|
+
const out = new Uint8Array(x25519PublicKeySize)
|
|
258
|
+
out[0] = 9
|
|
259
|
+
return out
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function copyBytes(bytes: $.Bytes | null): Uint8Array {
|
|
263
|
+
return new Uint8Array($.bytesToUint8Array(bytes ?? null))
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function bytesEqual(a: $.Bytes, b: $.Bytes): boolean {
|
|
267
|
+
const aa = $.bytesToUint8Array(a)
|
|
268
|
+
const bb = $.bytesToUint8Array(b)
|
|
269
|
+
return aa.length === bb.length && aa.every((v, i) => v === bb[i])
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function isZero(bytes: Uint8Array): boolean {
|
|
273
|
+
return bytes.every((b) => b === 0)
|
|
274
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
GenerateKey,
|
|
6
|
+
PrivateKeySize,
|
|
7
|
+
PrivateKey_Public,
|
|
8
|
+
PublicKeySize,
|
|
9
|
+
SignatureSize,
|
|
10
|
+
Sign,
|
|
11
|
+
Verify,
|
|
12
|
+
} from './index.js'
|
|
13
|
+
|
|
14
|
+
describe('crypto/ed25519 override', () => {
|
|
15
|
+
test('generates keys and verifies signatures', async () => {
|
|
16
|
+
const [pub, priv, err] = await GenerateKey(null)
|
|
17
|
+
expect(err).toBeNull()
|
|
18
|
+
expect($.len(pub)).toBe(PublicKeySize)
|
|
19
|
+
expect($.len(priv)).toBe(PrivateKeySize)
|
|
20
|
+
|
|
21
|
+
const message = $.stringToBytes('goscript')
|
|
22
|
+
const sig = await Sign(priv, message)
|
|
23
|
+
expect($.len(sig)).toBe(SignatureSize)
|
|
24
|
+
expect(await Verify(pub, message, sig)).toBe(true)
|
|
25
|
+
expect(await Verify(pub, $.stringToBytes('wrong'), sig)).toBe(false)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('boxes public keys as crypto public keys', async () => {
|
|
29
|
+
const [pub, priv, err] = await GenerateKey(null)
|
|
30
|
+
expect(err).toBeNull()
|
|
31
|
+
|
|
32
|
+
const boxed = PrivateKey_Public(priv)
|
|
33
|
+
const [unboxed, ok] = $.typeAssertTuple<Uint8Array>(
|
|
34
|
+
boxed,
|
|
35
|
+
'ed25519.PublicKey',
|
|
36
|
+
)
|
|
37
|
+
expect(ok).toBe(true)
|
|
38
|
+
expect(Array.from(unboxed)).toEqual(Array.from(pub))
|
|
39
|
+
expect((boxed as any).Equal(boxed)).toBe(true)
|
|
40
|
+
})
|
|
41
|
+
})
|