functionalscript 0.0.294 → 0.0.298
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/LANGUAGE.md +208 -0
- package/README.md +6 -213
- package/package.json +1 -1
- package/test.js +1 -0
- package/types/btree/find/index.js +22 -0
- package/types/btree/find/test.js +2 -7
- package/types/btree/index.js +1 -373
- package/types/btree/remove/test.js +78 -0
- package/types/btree/set/index.js +4 -4
- package/types/btree/test.js +7 -53
- package/types/crypto/index.js +193 -0
- package/types/crypto/test.js +62 -0
- package/types/map/index.js +5 -7
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {{
|
|
3
|
+
* readonly input: number[]
|
|
4
|
+
* readonly length: number
|
|
5
|
+
* }} HashInput
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {readonly[number, number, number, number, number, number, number, number]} HashOutput8
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** @type {(input: number) => (pos: number) => number} */
|
|
13
|
+
const appendOne = input => pos =>
|
|
14
|
+
{
|
|
15
|
+
return input | (1 << 31 - pos)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** @type {(input: number) => (pos: number) => number} */
|
|
19
|
+
const unsignedMod = a => b =>
|
|
20
|
+
{
|
|
21
|
+
return (a % b + b) % b
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** @type {(input: number[]) => (length: number) => readonly number[]} */
|
|
25
|
+
const padding = input => length =>
|
|
26
|
+
{
|
|
27
|
+
const appendBlockIndex = Math.floor(length / 32)
|
|
28
|
+
//console.log(appendBlockIndex)
|
|
29
|
+
const k = unsignedMod(447 - length)(512)
|
|
30
|
+
//console.log(k)
|
|
31
|
+
const outputLength = length + k + 65
|
|
32
|
+
//console.log(outputLength)
|
|
33
|
+
let o = new Array(outputLength / 32)
|
|
34
|
+
//console.log(o.length)
|
|
35
|
+
for(let i = 0; i < o.length; i++)
|
|
36
|
+
{
|
|
37
|
+
if (i < appendBlockIndex)
|
|
38
|
+
o[i] = input[i];
|
|
39
|
+
else if (i == appendBlockIndex)
|
|
40
|
+
o[i] = appendBlockIndex >= input.length ? 0x80000000 : appendOne(input[appendBlockIndex])(length % 32);
|
|
41
|
+
else if (i == o.length - 2)
|
|
42
|
+
o[i] = Math.floor(length / 4294967296)
|
|
43
|
+
else if (i == o.length - 1)
|
|
44
|
+
o[i] = length % 4294967296
|
|
45
|
+
else
|
|
46
|
+
o[i] = 0
|
|
47
|
+
}
|
|
48
|
+
return o;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @type {(x: number) => (y: number) => (z: number) => number} */
|
|
52
|
+
const ch = x => y => z =>
|
|
53
|
+
{
|
|
54
|
+
return x & y ^ ~x & z
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** @type {(x: number) => (y: number) => (z: number) => number} */
|
|
58
|
+
const maj = x => y => z =>
|
|
59
|
+
{
|
|
60
|
+
return x & y ^ x & z ^ y & z
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @type {(n: number) => (d: number) => number} */
|
|
64
|
+
const rotr = n => d =>
|
|
65
|
+
{
|
|
66
|
+
return n >>> d | n << (32-d)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @type {(n: number) => (d: number) => number} */
|
|
70
|
+
const shr = n => d =>
|
|
71
|
+
{
|
|
72
|
+
return n >>> d
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** @type {(x: number) => number} */
|
|
76
|
+
const bsig0 = x =>
|
|
77
|
+
{
|
|
78
|
+
return rotr(x)(2) ^ rotr(x)(13) ^ rotr(x)(22)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** @type {(x: number) => number} */
|
|
82
|
+
const bsig1 = x =>
|
|
83
|
+
{
|
|
84
|
+
return rotr(x)(6) ^ rotr(x)(11) ^ rotr(x)(25)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** @type {(x: number) => number} */
|
|
88
|
+
const ssig0 = x =>
|
|
89
|
+
{
|
|
90
|
+
return rotr(x)(7) ^ rotr(x)(18) ^ shr(x)(3)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** @type {(x: number) => number} */
|
|
94
|
+
const ssig1 = x =>
|
|
95
|
+
{
|
|
96
|
+
return rotr(x)(17) ^ rotr(x)(19) ^ shr(x)(10)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** @type {(x: number) => number} */
|
|
100
|
+
const mod2pow32 = x =>
|
|
101
|
+
{
|
|
102
|
+
return x % 4294967296
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** @type {(input: number[]) => (length: number) => HashOutput8} */
|
|
106
|
+
const computeSha256 = input => length =>
|
|
107
|
+
{
|
|
108
|
+
const padded = padding(input)(length)
|
|
109
|
+
|
|
110
|
+
let h0 = 0x6a09e667
|
|
111
|
+
let h1 = 0xbb67ae85
|
|
112
|
+
let h2 = 0x3c6ef372
|
|
113
|
+
let h3 = 0xa54ff53a
|
|
114
|
+
let h4 = 0x510e527f
|
|
115
|
+
let h5 = 0x9b05688c
|
|
116
|
+
let h6 = 0x1f83d9ab
|
|
117
|
+
let h7 = 0x5be0cd19
|
|
118
|
+
|
|
119
|
+
const k = [
|
|
120
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
121
|
+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
122
|
+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
123
|
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
124
|
+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
125
|
+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
126
|
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
127
|
+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
// /** @type {(a: number) => string} */
|
|
131
|
+
// const toHexString = x =>
|
|
132
|
+
// {
|
|
133
|
+
// return x >= 0 ? x.toString(16).padStart(8, '0') : (x + 0x100000000).toString(16).padStart(8, '0')
|
|
134
|
+
// }
|
|
135
|
+
|
|
136
|
+
let w = new Array(64)
|
|
137
|
+
const chunkCount = padded.length / 16
|
|
138
|
+
for(let i = 0; i < chunkCount; i++)
|
|
139
|
+
{
|
|
140
|
+
for(let t = 0; t < 16; t++)
|
|
141
|
+
{
|
|
142
|
+
w[t] = padded[t + i * 16]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
for(let t = 16; t < 64; t++)
|
|
146
|
+
{
|
|
147
|
+
w[t] = mod2pow32(ssig1(w[t - 2]) + w[t - 7] + ssig0(w[t-15]) + w[t - 16])
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
//console.log(w.map(toHexString))
|
|
151
|
+
|
|
152
|
+
let a = h0
|
|
153
|
+
let b = h1
|
|
154
|
+
let c = h2
|
|
155
|
+
let d = h3
|
|
156
|
+
let e = h4
|
|
157
|
+
let f = h5
|
|
158
|
+
let g = h6
|
|
159
|
+
let h = h7
|
|
160
|
+
|
|
161
|
+
for(let t = 0; t < 64; t++)
|
|
162
|
+
{
|
|
163
|
+
let t1 = mod2pow32(h + bsig1(e) + ch(e)(f)(g) + k[t] + w[t])
|
|
164
|
+
let t2 = mod2pow32(bsig0(a) + maj(a)(b)(c))
|
|
165
|
+
h = g
|
|
166
|
+
g = f
|
|
167
|
+
f = e
|
|
168
|
+
e = mod2pow32(d + t1)
|
|
169
|
+
d = c
|
|
170
|
+
c = b
|
|
171
|
+
b = a
|
|
172
|
+
a = mod2pow32(t1 + t2)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
h0 = mod2pow32(h0 + a)
|
|
176
|
+
h1 = mod2pow32(h1 + b)
|
|
177
|
+
h2 = mod2pow32(h2+ c)
|
|
178
|
+
h3 = mod2pow32(h3 + d)
|
|
179
|
+
h4 = mod2pow32(h4 + e)
|
|
180
|
+
h5 = mod2pow32(h5 + f)
|
|
181
|
+
h6 = mod2pow32(h6 + g)
|
|
182
|
+
h7 = mod2pow32(h7 + h)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return [h0, h1, h2, h3, h4, h5, h6, h7]
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
module.exports = {
|
|
189
|
+
/** @readonly */
|
|
190
|
+
padding,
|
|
191
|
+
/** @readonly */
|
|
192
|
+
computeSha256,
|
|
193
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const _ = require('.')
|
|
2
|
+
const json = require('../../json')
|
|
3
|
+
const { sort } = require('../object')
|
|
4
|
+
|
|
5
|
+
/** @type {(a: number) => string} */
|
|
6
|
+
const toHexString = x =>
|
|
7
|
+
{
|
|
8
|
+
return x >= 0 ? x.toString(16).padStart(8, '0') : (x + 0x100000000).toString(16).padStart(8, '0')
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** @type {(a: readonly json.Unknown[]) => string} */
|
|
12
|
+
const stringify = a => json.stringify(sort)(a)
|
|
13
|
+
|
|
14
|
+
// {
|
|
15
|
+
// const result = _.padding([])(0)
|
|
16
|
+
// console.log(result.map(toHexString))
|
|
17
|
+
// }
|
|
18
|
+
|
|
19
|
+
// {
|
|
20
|
+
// const result = _.padding([0x61626364, 0x65000000])(40)
|
|
21
|
+
// console.log(result.map(toHexString))
|
|
22
|
+
// }
|
|
23
|
+
|
|
24
|
+
// {
|
|
25
|
+
// const result = _.padding([0x11111110])(31)
|
|
26
|
+
// console.log(result.map(toHexString))
|
|
27
|
+
// }
|
|
28
|
+
|
|
29
|
+
// {
|
|
30
|
+
// const result = _.padding([0x11111110])(32)
|
|
31
|
+
// console.log(result.map(toHexString))
|
|
32
|
+
// }
|
|
33
|
+
|
|
34
|
+
{
|
|
35
|
+
const hash = _.computeSha256([])(0)
|
|
36
|
+
const result = stringify(hash.map(toHexString))
|
|
37
|
+
if (result !== '["e3b0c442","98fc1c14","9afbf4c8","996fb924","27ae41e4","649b934c","a495991b","7852b855"]') { throw result }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
//[0x68656C6C, 0x6F20776F, 0x726C6400] represents phrase 'hello world'
|
|
42
|
+
const hash = _.computeSha256([0x68656C6C, 0x6F20776F, 0x726C6400])(88)
|
|
43
|
+
const result = stringify(hash.map(toHexString))
|
|
44
|
+
if (result !== '["b94d27b9","934d3e08","a52e52d7","da7dabfa","c484efe3","7a5380ee","9088f7ac","e2efcde9"]') { throw result }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
{
|
|
48
|
+
const input = Array(8).fill(0x31313131)
|
|
49
|
+
const result = _.computeSha256(input)(256)
|
|
50
|
+
if (result[0] !== 0x8a83665f) { throw result[0] }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
const input = Array(16).fill(0x31313131)
|
|
55
|
+
const hash = _.computeSha256(input)(512)
|
|
56
|
+
const result = stringify(hash.map(toHexString))
|
|
57
|
+
if (result !== '["3138bb9b","c78df27c","473ecfd1","410f7bd4","5ebac1f5","9cf3ff9c","fe4db77a","ab7aedd3"]') { throw result }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
|
|
62
|
+
}
|
package/types/map/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const option = require("../option")
|
|
2
2
|
const btree = require('../btree')
|
|
3
|
-
const {
|
|
3
|
+
const { values } = require("../btree")
|
|
4
|
+
const find = require('../btree/find')
|
|
5
|
+
const s = require('../btree/set')
|
|
4
6
|
const compare = require("../function/compare")
|
|
5
7
|
const { stringCmp } = require("../function/compare")
|
|
6
8
|
const list = require("../list")
|
|
@@ -38,7 +40,7 @@ const keyCmp = a => ([b]) => stringCmp(a)(b)
|
|
|
38
40
|
/** @type {(name: string) => <T>(map: Map<T>) => T|undefined} */
|
|
39
41
|
const at = name => map => {
|
|
40
42
|
if (map === undefined) { return undefined }
|
|
41
|
-
const result =
|
|
43
|
+
const result = find.value(find.find(keyCmp(name))(map).first)
|
|
42
44
|
return result === undefined ? undefined : result[1]
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -47,11 +49,7 @@ const set = name => value => map => {
|
|
|
47
49
|
/** @type {Entry<typeof value>} */
|
|
48
50
|
const entry = [name, value]
|
|
49
51
|
if (map === undefined) { return [entry] }
|
|
50
|
-
|
|
51
|
-
switch (result[0]) {
|
|
52
|
-
case 'replace': case 'overflow': { return result[1] }
|
|
53
|
-
default: { throw 'invalid BTree operation' }
|
|
54
|
-
}
|
|
52
|
+
return s.set(keyCmp(name))(entry)(map)
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
/** @type {<T>(map: Map<T>) => list.List<Entry<T>>} */
|