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,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,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
|
})
|
package/gs/crypto/rand/index.ts
CHANGED
|
@@ -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(
|
|
160
|
+
return new RandError(
|
|
161
|
+
'crypto/rand: Web Crypto getRandomValues is unavailable',
|
|
162
|
+
)
|
|
61
163
|
}
|
|
62
164
|
|
|
63
165
|
if (dst instanceof Uint8Array) {
|
package/gs/crypto/rand/meta.json
CHANGED
|
@@ -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
|
+
})
|