functionalscript 0.0.295 → 0.0.299

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 ADDED
@@ -0,0 +1,208 @@
1
+ # FunctionaScript Programming Language
2
+
3
+ ## 1. Module Ecosystem
4
+
5
+ FunctionalScript uses [CommonJS](https://en.wikipedia.org/wiki/CommonJS) conventions as a module ecosystem. For example,
6
+
7
+ ```js
8
+ const thirdPartyModule = require('third-party-package/module')
9
+
10
+ const result = thirdPartyModule.someFunction('hello')
11
+ ```
12
+
13
+ ## 2. Packages
14
+
15
+ FunctionalScript uses a `package.json` file to define a package. This file is compatible with [Node.js `package.json`](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/).
16
+ The prefered way to refence dependencies is to use a GitHub URL. These dependencies in a `package.json` file could look like this,
17
+
18
+ ```json
19
+ {
20
+ // ...
21
+ "dependencies": {
22
+ "third-party-package": "github:exampleorg/thirdpartypackage"
23
+ }
24
+ // ...
25
+ }
26
+ ```
27
+
28
+ **Note:** this repository is also a FunctionalScript package, and it can be used as a library. To install this package, use
29
+
30
+ ```
31
+ npm install -S github:functionalscript/functionalscript
32
+ ```
33
+
34
+ ## 3. Module Structure
35
+
36
+ A module is a file with the `.js` extention. It contains three parts: references to other modules, definitions, and exports. For example
37
+
38
+ `./first.js`
39
+ ```js
40
+ // 1. references
41
+ const math = require('math')
42
+
43
+ // 2. definitions
44
+ const myConst = 42
45
+ // addition(a)(b) = a + b
46
+ const addition = a => b => a + b
47
+ const add42 = addition(42)
48
+ const _10digitsOfPi = math.calculatePi(10)
49
+
50
+ // 3. exports
51
+ module.exports = {
52
+ addition,
53
+ add42,
54
+ _10digitsOfPi,
55
+ }
56
+ ```
57
+
58
+ `./second.js`
59
+ ```js
60
+ // 1. references
61
+ const first = require('./first.js')
62
+
63
+ // 2. definitions
64
+ const _42plus7 = first.add42(7)
65
+
66
+ // 3. exports
67
+ module.exports = {
68
+ _42plus7,
69
+ }
70
+ ```
71
+
72
+ ## 4. References To Other Modules
73
+
74
+ The format of references is `const ANYNAME = require('PATH_TO_A_MODULE')`. For example,
75
+
76
+ ```js
77
+ const math = require('math')
78
+ const algebra = require('math/algebra')
79
+ const localFile = require('../some-directory/some-file.js')
80
+ ```
81
+
82
+ ## 5. Definitions
83
+
84
+ The format of defintions is `const NAME = EXPRESSION`, where the `EXPRESSION` is a subset of [JavaScript expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators).
85
+
86
+ ```js
87
+ const myConst = 42
88
+ const functionDouble = a => a * 2
89
+ const structure = { name: "John", surname: "Smith" }
90
+ const array = [1, 2, 3]
91
+ const nestedStructure = {
92
+ address: undefined,
93
+ serialNumber: "123-45-78",
94
+ sum: 14 + myConst + functionDouble(4),
95
+ moreInfo: {
96
+ name: "Ivan",
97
+ surname: "Terrible",
98
+ }
99
+ }
100
+ ```
101
+
102
+ See [Expressions](#7-Expressions).
103
+
104
+ ### 6. Exports
105
+
106
+ The format of exports is `module.exports = { A_LIST_OF_EXPORTED_DEFINITIONS }`. There should be only one `module.exports` at
107
+ the end of a FunctionalScript file. For example,
108
+
109
+ ```js
110
+ module.exports = {
111
+ nestedStructure,
112
+ array,
113
+ structure,
114
+ }
115
+ ```
116
+
117
+ ## 7. Expressions
118
+
119
+ Expressions could fall under these categories:
120
+
121
+ - Literals:
122
+ - Number Literals, e.g. `0`, `3.14`, `4e8`
123
+ - Boolean Literals: `true` or `false`
124
+ - A `null` Literal
125
+ - An `undefined` Literal
126
+ - String Literals, e.g. `"Hello world!"`
127
+ - Complex Structures
128
+ - Arrays, e.g. `[2, 5]`
129
+ - Objects, e.g. `{ a: "Hello", b: "world!" }`
130
+ - Arrow functions, e.g. `x => x * 2`
131
+ - Operators
132
+ - Comparison Operators: `===`, `!==`, `>`, `>=`, `<`, `<=`
133
+ - Arithmetic Operators: `+`, `-`, `*`, `/`, `%`, `**`
134
+ - Bitwise Operators: `&`, `|`, `^`, `~`, `<<`, `>>`, `>>>`
135
+ - Logical Operators: `&&`, `||`, `!`, `??`
136
+ - Conditional Operator, e.g. `condition ? val1 : val2`
137
+ - Template Literals, e.g. `string ${expression}`
138
+ - `typeof`
139
+ - Relations Operators: `in`, `instanceof`.
140
+ - Member Operators: `.`, `[]`.
141
+
142
+ Note: the `.` member operator has prohibitted property names, such as `constructor` and `push`. To access such properties, it's recommeded to use the [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) function.
143
+
144
+ ## 8. Arrow Functions
145
+
146
+ An arrow function is also known as [a lambda function](https://en.wikipedia.org/wiki/Anonymous_function).
147
+ The format of an arrow function is `ARGUMENT_NAME => FUNCTION_BODY`. An arrow function must have either a single argument or no arguments at all. For example
148
+
149
+ ```js
150
+ x => x * 2
151
+ a => a + 4
152
+ s => `template literal ${s}`
153
+ a => b => a + b // an arrow functions that returns another arrow functions.
154
+ () => 'hello' // an arrow function with no arguments
155
+ ```
156
+
157
+ A function body is either an expression or a block statement. A block statement format is `{ A_LIST_OF_STATEMENTS }`. For example
158
+
159
+ ```js
160
+ // a function with one argument and a block statement
161
+ const f = x => {
162
+ const a = 2 + x
163
+ const r = a + 4
164
+ return r
165
+ }
166
+ ```
167
+
168
+ ## 9. Statements
169
+
170
+ `{ A_LIST_OF_STATEMENTS }` is one or many statements seperated by the newline control character. One of these statements mentioned earlier was [definition](#5-Definitions), also known as a [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statement. The other statements are described below.
171
+
172
+ ### 9.1. Let
173
+
174
+ [Let](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) declares a local mutable alias for immutable objects. For example
175
+
176
+ ```js
177
+ let x = [5]
178
+ // you can assign another immutable object to the alias at any time.
179
+ x = [3, 4]
180
+ //but you can't change the properties of the immutable object.
181
+ x[0] = 3 // < invalid
182
+ //let aliases can not be referenced from another arrow function.
183
+ const f = () => x // < invalid
184
+ ```
185
+
186
+ ### 9.2. Return
187
+
188
+ [Return](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return)
189
+
190
+ ### 9.3. If...Else
191
+
192
+ [If...Else](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)
193
+
194
+ ### 9.4. Switch
195
+
196
+ [Switch](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch)
197
+
198
+ ### 9.5. Throw
199
+
200
+ [Throw](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw). FunctionalScript allows to throw exceptions but it doesn't catch them. You should only be using Statement throw in non-recoverable situations. It could be compared to [panic in Rust](https://doc.rust-lang.org/std/macro.panic.html).
201
+
202
+ ### 9.6. While
203
+
204
+ [While](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while)
205
+
206
+ ### 9.7. Block
207
+
208
+ [Block](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block)
package/README.md CHANGED
@@ -1,228 +1,21 @@
1
1
  # FunctionalScript
2
2
 
3
- FunctionalScript is a pure functional programming language and a strict subset of
4
- [ECMAScript](https://en.wikipedia.org/wiki/ECMAScript)/[JavaScript](https://en.wikipedia.org/wiki/JavaScript). It's inspired by
3
+ FunctionalScript is a pure functional programming language and a strict subset of
4
+ [ECMAScript](https://en.wikipedia.org/wiki/ECMAScript)/[JavaScript](https://en.wikipedia.org/wiki/JavaScript). It's inspired by
5
5
 
6
6
  - [JSON](https://en.wikipedia.org/wiki/JSON) as a subset of JavaScript. JSON is also a subset of FunctionalScript.
7
7
  - [asm.JS](https://en.wikipedia.org/wiki/Asm.js)/[WebAssembly](https://en.wikipedia.org/wiki/WebAssembly), as a subset of JavaScript.
8
8
  - [TypeScript](https://en.wikipedia.org/wiki/TypeScript), as a superset of JavaScript.
9
9
 
10
+ [A brief description of FunctionalScript Programming Language](./LANGUAGE.md).
11
+
10
12
  Create a new FunctionalScript repository on GitHub [here](https://github.com/functionalscript/template/generate).
11
13
 
12
- ## 1. Design Principles
14
+ ## Design Principles
13
15
 
14
16
  In FunctionalScript:
15
17
 
16
18
  - Any module is a valid JavaScript module. No additional build steps are required.
17
19
  - Code should not have [side-effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)). Any JavaScript statement, expression, or function which has a side effect is not allowed in FunctionalScript. There are no exceptions to this rule, such as `unsafe` code which can be found in Rust, C#, and other languages.
18
- - A module can't depend on non FunctionalScript module.
20
+ - A module can't depend on non FunctionalScript module.
19
21
  - It also has no standard library, only a safe subset of standard JavaScript API can be used without referencing other modules.
20
-
21
- ## 2. Outlines
22
-
23
- ### 2.1. Module Ecosystem
24
-
25
- FunctionalScript uses [CommonJS](https://en.wikipedia.org/wiki/CommonJS) conventions as a module ecosystem. For example,
26
-
27
- ```js
28
- const thirdPartyModule = require('third-party-package/module')
29
-
30
- const result = thirdPartyModule.someFunction('hello')
31
- ```
32
-
33
- ### 2.2. Packages
34
-
35
- FunctionalScript uses a `package.json` file to define a package. This file is compatible with [Node.js `package.json`](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/).
36
- The prefered way to refence dependencies is to use a GitHub URL. These dependencies in a `package.json` file could look like this,
37
-
38
- ```json
39
- {
40
- // ...
41
- "dependencies": {
42
- "third-party-package": "github:exampleorg/thirdpartypackage"
43
- }
44
- // ...
45
- }
46
- ```
47
-
48
- **Note:** this repository is also a FunctionalScript package, and it can be used as a library. To install this package, use
49
-
50
- ```
51
- npm install -S github:functionalscript/functionalscript
52
- ```
53
-
54
- ### 2.3. Module Structure
55
-
56
- A module is a file with the `.js` extention. It contains three parts: references to other modules, definitions, and exports. For example
57
-
58
- `./first.js`
59
- ```js
60
- // 1. references
61
- const math = require('math')
62
-
63
- // 2. definitions
64
- const myConst = 42
65
- // addition(a)(b) = a + b
66
- const addition = a => b => a + b
67
- const add42 = addition(42)
68
- const _10digitsOfPi = math.calculatePi(10)
69
-
70
- // 3. exports
71
- module.exports = {
72
- addition,
73
- add42,
74
- _10digitsOfPi,
75
- }
76
- ```
77
-
78
- `./second.js`
79
- ```js
80
- // 1. references
81
- const first = require('./first.js')
82
-
83
- // 2. definitions
84
- const _42plus7 = first.add42(7)
85
-
86
- // 3. exports
87
- module.exports = {
88
- _42plus7,
89
- }
90
- ```
91
-
92
- ### 2.4. References To Other Modules
93
-
94
- The format of references is `const ANYNAME = require('PATH_TO_A_MODULE')`. For example,
95
-
96
- ```js
97
- const math = require('math')
98
- const algebra = require('math/algebra')
99
- const localFile = require('../some-directory/some-file.js')
100
- ```
101
-
102
- ### 2.5. Definitions
103
-
104
- The format of defintions is `const NAME = EXPRESSION`, where the `EXPRESSION` is a subset of [JavaScript expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators).
105
-
106
- ```js
107
- const myConst = 42
108
- const functionDouble = a => a * 2
109
- const structure = { name: "John", surname: "Smith" }
110
- const array = [1, 2, 3]
111
- const nestedStructure = {
112
- address: undefined,
113
- serialNumber: "123-45-78",
114
- sum: 14 + myConst + functionDouble(4),
115
- moreInfo: {
116
- name: "Ivan",
117
- surname: "Terrible",
118
- }
119
- }
120
- ```
121
-
122
- See [3. Expressions](#3-Expressions).
123
-
124
- ### 2.6. Exports
125
-
126
- The format of exports is `module.exports = { A_LIST_OF_EXPORTED_DEFINITIONS }`. There should be only one `module.exports` at
127
- the end of a FunctionalScript file. For example,
128
-
129
- ```js
130
- module.exports = {
131
- nestedStructure,
132
- array,
133
- structure,
134
- }
135
- ```
136
-
137
- ## 3. Expressions
138
-
139
- Expressions could fall under these categories:
140
-
141
- - Literals:
142
- - Number Literals, e.g. `0`, `3.14`, `4e8`
143
- - Boolean Literals: `true` or `false`
144
- - A `null` Literal
145
- - An `undefined` Literal
146
- - String Literals, e.g. `"Hello world!"`
147
- - Complex Structures
148
- - Arrays, e.g. `[2, 5]`
149
- - Objects, e.g. `{ a: "Hello", b: "world!" }`
150
- - Arrow functions, e.g. `x => x * 2`
151
- - Operators
152
- - Comparison Operators: `===`, `!==`, `>`, `>=`, `<`, `<=`
153
- - Arithmetic Operators: `+`, `-`, `*`, `/`, `%`, `**`
154
- - Bitwise Operators: `&`, `|`, `^`, `~`, `<<`, `>>`, `>>>`
155
- - Logical Operators: `&&`, `||`, `!`, `??`
156
- - Conditional Operator, e.g. `condition ? val1 : val2`
157
- - Template Literals, e.g. `string ${expression}`
158
- - `typeof`
159
- - Relations Operators: `in`, `instanceof`.
160
- - Member Operators: `.`, `[]`.
161
-
162
- Note: the `.` member operator has prohibitted property names, such as `constructor` and `push`. To access such properties, it's recommeded to use the [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) function.
163
-
164
- ## 4. Arrow Functions
165
-
166
- An arrow function is also known as [a lambda function](https://en.wikipedia.org/wiki/Anonymous_function).
167
- The format of an arrow function is `ARGUMENT_NAME => FUNCTION_BODY`. An arrow function must have either a single argument or no arguments at all. For example
168
-
169
- ```js
170
- x => x * 2
171
- a => a + 4
172
- s => `template literal ${s}`
173
- a => b => a + b // an arrow functions that returns another arrow functions.
174
- () => 'hello' // an arrow function with no arguments
175
- ```
176
-
177
- A function body is either an expression or a block statement. A block statement format is `{ A_LIST_OF_STATEMENTS }`. For example
178
-
179
- ```js
180
- // a function with one argument and a block statement
181
- const f = x => {
182
- const a = 2 + x
183
- const r = a + 4
184
- return r
185
- }
186
- ```
187
-
188
- ## 5. Statements
189
-
190
- `{ A_LIST_OF_STATEMENTS }` is one or many statements seperated by the newline control character. One of these statements mentioned earlier was [definition](#25-Definitions), also known as a [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statement. The other statements are described below.
191
-
192
- ### 5.1 Let
193
-
194
- [Let](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) declares a local mutable alias for immutable objects. For example
195
-
196
- ```js
197
- let x = [5]
198
- // you can assign another immutable object to the alias at any time.
199
- x = [3, 4]
200
- //but you can't change the properties of the immutable object.
201
- x[0] = 3 // < invalid
202
- //let aliases can not be referenced from another arrow function.
203
- const f = () => x // < invalid
204
- ```
205
-
206
- ### 5.2 Return
207
-
208
- [Return](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return)
209
-
210
- ### 5.3 If...Else
211
-
212
- [If...Else](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)
213
-
214
- ### 5.4 Switch
215
-
216
- [Switch](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch)
217
-
218
- ### 5.5 Throw
219
-
220
- [Throw](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw). FunctionalScript allows to throw exceptions but it doesn't catch them. You should only be using Statement throw in non-recoverable situations. It could be compared to [panic in Rust](https://doc.rust-lang.org/std/macro.panic.html).
221
-
222
- ### 5.6 While
223
-
224
- [While](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while)
225
-
226
- ### 5.7 Block
227
-
228
- [Block](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.295",
3
+ "version": "0.0.299",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test.js CHANGED
@@ -3,6 +3,7 @@ const i = require('./')
3
3
  require('./types/list/test')
4
4
  require('./types/array/test')
5
5
  require('./types/btree/test')
6
+ require('./types/crypto/test')
6
7
  require('./json/test')
7
8
  require('./types/object/test')
8
9
  require('./io/commonjs/test')
@@ -48,11 +48,6 @@ const seq = require('../list')
48
48
  * @typedef { Leaf1<T> | Leaf2<T> | Branch3<T> | Branch5<T>} Node
49
49
  */
50
50
 
51
- /**
52
- * @template T
53
- * @typedef { readonly[...Branch5<T>, T, Node<T>] } Branch7
54
- */
55
-
56
51
  /** @type {<T>(node: Node<T>) => seq.Thunk<T>} */
57
52
  const values = node => () => {
58
53
  switch (node.length) {
@@ -81,6 +76,11 @@ const values = node => () => {
81
76
  * @typedef {readonly[Node<T>]} Branch1
82
77
  */
83
78
 
79
+ /**
80
+ * @template T
81
+ * @typedef { readonly[...Branch5<T>, T, Node<T>] } Branch7
82
+ */
83
+
84
84
  module.exports = {
85
85
  /** @readonly */
86
86
  values,
@@ -0,0 +1,192 @@
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
+ /** @type {(i: number) => number} */
36
+ const f = i =>
37
+ i < appendBlockIndex ?
38
+ input[i] :
39
+ i === appendBlockIndex ?
40
+ (appendBlockIndex >= input.length ? 0x80000000 : appendOne(input[appendBlockIndex])(length % 32)) :
41
+ i === o.length - 2 ? (length / 4294967296) | 0 :
42
+ i === o.length - 1 ? length % 4294967296 : 0
43
+ for(let i = 0; i < o.length; i++)
44
+ {
45
+ o[i] = f(i)
46
+ }
47
+ return o;
48
+ }
49
+
50
+ /** @type {(x: number) => (y: number) => (z: number) => number} */
51
+ const ch = x => y => z =>
52
+ {
53
+ return x & y ^ ~x & z
54
+ }
55
+
56
+ /** @type {(x: number) => (y: number) => (z: number) => number} */
57
+ const maj = x => y => z =>
58
+ {
59
+ return x & y ^ x & z ^ y & z
60
+ }
61
+
62
+ /** @type {(n: number) => (d: number) => number} */
63
+ const rotr = n => d =>
64
+ {
65
+ return n >>> d | n << (32-d)
66
+ }
67
+
68
+ /** @type {(n: number) => (d: number) => number} */
69
+ const shr = n => d =>
70
+ {
71
+ return n >>> d
72
+ }
73
+
74
+ /** @type {(x: number) => number} */
75
+ const bsig0 = x =>
76
+ {
77
+ return rotr(x)(2) ^ rotr(x)(13) ^ rotr(x)(22)
78
+ }
79
+
80
+ /** @type {(x: number) => number} */
81
+ const bsig1 = x =>
82
+ {
83
+ return rotr(x)(6) ^ rotr(x)(11) ^ rotr(x)(25)
84
+ }
85
+
86
+ /** @type {(x: number) => number} */
87
+ const ssig0 = x =>
88
+ {
89
+ return rotr(x)(7) ^ rotr(x)(18) ^ shr(x)(3)
90
+ }
91
+
92
+ /** @type {(x: number) => number} */
93
+ const ssig1 = x =>
94
+ {
95
+ return rotr(x)(17) ^ rotr(x)(19) ^ shr(x)(10)
96
+ }
97
+
98
+ /** @type {(x: number) => number} */
99
+ const mod2pow32 = x =>
100
+ {
101
+ return x % 4294967296
102
+ }
103
+
104
+ /** @type {(input: number[]) => (length: number) => HashOutput8} */
105
+ const computeSha256 = input => length =>
106
+ {
107
+ const padded = padding(input)(length)
108
+
109
+ let h0 = 0x6a09e667
110
+ let h1 = 0xbb67ae85
111
+ let h2 = 0x3c6ef372
112
+ let h3 = 0xa54ff53a
113
+ let h4 = 0x510e527f
114
+ let h5 = 0x9b05688c
115
+ let h6 = 0x1f83d9ab
116
+ let h7 = 0x5be0cd19
117
+
118
+ const k = [
119
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
120
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
121
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
122
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
123
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
124
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
125
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
126
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
127
+ ];
128
+
129
+ // /** @type {(a: number) => string} */
130
+ // const toHexString = x =>
131
+ // {
132
+ // return x >= 0 ? x.toString(16).padStart(8, '0') : (x + 0x100000000).toString(16).padStart(8, '0')
133
+ // }
134
+
135
+ let w = new Array(64)
136
+ const chunkCount = padded.length / 16
137
+ for(let i = 0; i < chunkCount; i++)
138
+ {
139
+ for(let t = 0; t < 16; t++)
140
+ {
141
+ w[t] = padded[t + i * 16]
142
+ }
143
+
144
+ for(let t = 16; t < 64; t++)
145
+ {
146
+ w[t] = mod2pow32(ssig1(w[t - 2]) + w[t - 7] + ssig0(w[t-15]) + w[t - 16])
147
+ }
148
+
149
+ //console.log(w.map(toHexString))
150
+
151
+ let a = h0
152
+ let b = h1
153
+ let c = h2
154
+ let d = h3
155
+ let e = h4
156
+ let f = h5
157
+ let g = h6
158
+ let h = h7
159
+
160
+ for(let t = 0; t < 64; t++)
161
+ {
162
+ let t1 = mod2pow32(h + bsig1(e) + ch(e)(f)(g) + k[t] + w[t])
163
+ let t2 = mod2pow32(bsig0(a) + maj(a)(b)(c))
164
+ h = g
165
+ g = f
166
+ f = e
167
+ e = mod2pow32(d + t1)
168
+ d = c
169
+ c = b
170
+ b = a
171
+ a = mod2pow32(t1 + t2)
172
+ }
173
+
174
+ h0 = mod2pow32(h0 + a)
175
+ h1 = mod2pow32(h1 + b)
176
+ h2 = mod2pow32(h2+ c)
177
+ h3 = mod2pow32(h3 + d)
178
+ h4 = mod2pow32(h4 + e)
179
+ h5 = mod2pow32(h5 + f)
180
+ h6 = mod2pow32(h6 + g)
181
+ h7 = mod2pow32(h7 + h)
182
+ }
183
+
184
+ return [h0, h1, h2, h3, h4, h5, h6, h7]
185
+ }
186
+
187
+ module.exports = {
188
+ /** @readonly */
189
+ padding,
190
+ /** @readonly */
191
+ computeSha256,
192
+ }
@@ -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
+ }