quarkdash 1.0.0
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/.idea/modules.xml +8 -0
- package/.idea/quarkdash.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/coverage/clover.xml +470 -0
- package/coverage/coverage-final.json +8 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/cipher.ts.html +862 -0
- package/coverage/lcov-report/crypto.ts.html +1000 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +206 -0
- package/coverage/lcov-report/index.ts.html +151 -0
- package/coverage/lcov-report/kdf.ts.html +274 -0
- package/coverage/lcov-report/mac.ts.html +277 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/ringlwe.ts.html +895 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/utils.ts.html +1111 -0
- package/coverage/lcov.info +740 -0
- package/dist/cjs/cipher.js +265 -0
- package/dist/cjs/cipher.js.map +1 -0
- package/dist/cjs/crypto.js +284 -0
- package/dist/cjs/crypto.js.map +1 -0
- package/dist/cjs/index.js +37 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/kdf.js +56 -0
- package/dist/cjs/kdf.js.map +1 -0
- package/dist/cjs/mac.js +55 -0
- package/dist/cjs/mac.js.map +1 -0
- package/dist/cjs/ringlwe.js +267 -0
- package/dist/cjs/ringlwe.js.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils.js +320 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/esm/cipher.js +259 -0
- package/dist/esm/cipher.js.map +1 -0
- package/dist/esm/crypto.js +280 -0
- package/dist/esm/crypto.js.map +1 -0
- package/dist/esm/index.js +21 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/kdf.js +52 -0
- package/dist/esm/kdf.js.map +1 -0
- package/dist/esm/mac.js +51 -0
- package/dist/esm/mac.js.map +1 -0
- package/dist/esm/ringlwe.js +263 -0
- package/dist/esm/ringlwe.js.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils.js +313 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/types/cipher.d.ts +153 -0
- package/dist/types/crypto.d.ts +155 -0
- package/dist/types/index.d.ts +16 -0
- package/dist/types/kdf.d.ts +34 -0
- package/dist/types/mac.d.ts +47 -0
- package/dist/types/ringlwe.d.ts +127 -0
- package/dist/types/types.d.ts +69 -0
- package/dist/types/utils.d.ts +132 -0
- package/img/cover.png +0 -0
- package/package.json +63 -0
- package/src/cipher.ts +260 -0
- package/src/crypto.ts +306 -0
- package/src/index.ts +23 -0
- package/src/kdf.ts +64 -0
- package/src/mac.ts +65 -0
- package/src/ringlwe.ts +271 -0
- package/src/types.ts +75 -0
- package/src/utils.ts +343 -0
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crypto Utils Class
|
|
3
|
+
*/
|
|
4
|
+
export declare class QuarkDashUtils {
|
|
5
|
+
private static HEXChars;
|
|
6
|
+
/**
|
|
7
|
+
* Run SHA256 async
|
|
8
|
+
* @param data {Uint8Array} Bytes buffer
|
|
9
|
+
* @return {Promise<Uint8Array>} Result
|
|
10
|
+
*/
|
|
11
|
+
static sha256(data: Uint8Array): Promise<Uint8Array>;
|
|
12
|
+
/**
|
|
13
|
+
* Run SHA256 sync
|
|
14
|
+
* @param data {Uint8Array} Bytes buffer
|
|
15
|
+
* @return {Uint8Array} Result
|
|
16
|
+
*/
|
|
17
|
+
static sha256Sync(data: Uint8Array): Uint8Array;
|
|
18
|
+
/**
|
|
19
|
+
* Get Shake-256 result async
|
|
20
|
+
* @param data {Uint8Array} Bytes buffer
|
|
21
|
+
* @param len {number} Buffer length
|
|
22
|
+
* @return {Promise<Uint8Array>} Result buffer
|
|
23
|
+
*/
|
|
24
|
+
static shake256(data: Uint8Array, len: number): Promise<Uint8Array>;
|
|
25
|
+
/**
|
|
26
|
+
* Get Shake-256 result sync
|
|
27
|
+
* @param data {Uint8Array} Bytes buffer
|
|
28
|
+
* @param len {number} Buffer length
|
|
29
|
+
* @return {Uint8Array} Result buffer
|
|
30
|
+
*/
|
|
31
|
+
static shake256Sync(data: Uint8Array, len: number): Uint8Array;
|
|
32
|
+
/**
|
|
33
|
+
* Concat bytes
|
|
34
|
+
* @param arrays {Uint8Array|null|undefined} Input arrays for concat
|
|
35
|
+
* @returns {Uint8Array} Result buffer
|
|
36
|
+
*/
|
|
37
|
+
static concatBytes(...arrays: (Uint8Array | null | undefined)[]): Uint8Array;
|
|
38
|
+
/**
|
|
39
|
+
* Coerce Array
|
|
40
|
+
* @param arg {any} Argument
|
|
41
|
+
* @param copy {any} Copy
|
|
42
|
+
* @protected
|
|
43
|
+
*/
|
|
44
|
+
static coerceArray(arg: any, copy?: any): any;
|
|
45
|
+
/**
|
|
46
|
+
* Check if value is int
|
|
47
|
+
* @param value {any} Value
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
* @protected
|
|
50
|
+
*/
|
|
51
|
+
static checkInt(value: any): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Check Ints inside array
|
|
54
|
+
* @param arrayish {any} Array
|
|
55
|
+
* @returns {boolean} Any value is integer and between 0 and 255
|
|
56
|
+
* @protected
|
|
57
|
+
*/
|
|
58
|
+
static checkInts(arrayish: any): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Get random bytes
|
|
61
|
+
* @param len {number} buffer length
|
|
62
|
+
* @returns {Uint8Array} Random bytes buffer
|
|
63
|
+
*/
|
|
64
|
+
static randomBytes(len: number): Uint8Array;
|
|
65
|
+
/**
|
|
66
|
+
* Convert raw text to bytes array
|
|
67
|
+
* @param text {string} raw string
|
|
68
|
+
* @returns {any} bytes array
|
|
69
|
+
*/
|
|
70
|
+
static textToBytes(text: string): any;
|
|
71
|
+
/**
|
|
72
|
+
* Convert bytes array to raw string
|
|
73
|
+
* @param bytes {number[]|Uint8Array} Bytes array
|
|
74
|
+
* @returns {string} raw string
|
|
75
|
+
*/
|
|
76
|
+
static bytesToText(bytes: number[] | Uint8Array): string;
|
|
77
|
+
/**
|
|
78
|
+
* Convert HEX string to bytes array
|
|
79
|
+
* @param text {string} HEX string
|
|
80
|
+
* @returns {number[]} bytes array
|
|
81
|
+
* @constructor
|
|
82
|
+
*/
|
|
83
|
+
static HEXToBytes(text: string): number[];
|
|
84
|
+
/**
|
|
85
|
+
* Convert bytes array to HEX string
|
|
86
|
+
* @param bytes {number[]|Uint8Array} Bytes array
|
|
87
|
+
* @returns {string} HEX String
|
|
88
|
+
*/
|
|
89
|
+
static bytesToHEX(bytes: number[] | Uint8Array): string;
|
|
90
|
+
/**
|
|
91
|
+
* Constant time equal
|
|
92
|
+
* @param a {Uint8Array} first buffer
|
|
93
|
+
* @param b {Uint8Array} second buffer
|
|
94
|
+
* @returns {boolean} Equal or not
|
|
95
|
+
*/
|
|
96
|
+
static constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Secure zero
|
|
99
|
+
* @param bytes {Uint8Array} bytes buffer
|
|
100
|
+
*/
|
|
101
|
+
static secureZero(bytes: Uint8Array): void;
|
|
102
|
+
/**
|
|
103
|
+
* Read U32 from buffer
|
|
104
|
+
* @param arr {Uint8Array} buffer
|
|
105
|
+
* @param off {number} Offset
|
|
106
|
+
* @returns {number} U32
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
109
|
+
static readU32(arr: Uint8Array, off: number): number;
|
|
110
|
+
/**
|
|
111
|
+
* Write U32 to buffer
|
|
112
|
+
* @param v {number} U32
|
|
113
|
+
* @param arr {Uint8Array} Target buffer
|
|
114
|
+
* @param off {number} Offset
|
|
115
|
+
* @private
|
|
116
|
+
*/
|
|
117
|
+
static writeU32(v: number, arr: Uint8Array, off: number): void;
|
|
118
|
+
/**
|
|
119
|
+
* Read Uint32 Value
|
|
120
|
+
* @param arr {Uint8Array} Bytes buffer
|
|
121
|
+
* @param off {number} Offset
|
|
122
|
+
* @returns {number} Uint32 Value
|
|
123
|
+
*/
|
|
124
|
+
static readUint32(arr: Uint8Array, off: number): number;
|
|
125
|
+
/**
|
|
126
|
+
* Read Uint64 Value
|
|
127
|
+
* @param arr {Uint8Array} Bytes buffer
|
|
128
|
+
* @param off {number} offset
|
|
129
|
+
* @returns {bigint} Bigint
|
|
130
|
+
*/
|
|
131
|
+
static readUint64(arr: Uint8Array, off: number): bigint;
|
|
132
|
+
}
|
package/img/cover.png
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "quarkdash",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "QuarkDash - pure typescript hybrid cryptographic protocol that provides post-quantum security, high performance, and attack resistance.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"quark",
|
|
7
|
+
"dash",
|
|
8
|
+
"qd-256",
|
|
9
|
+
"quarkdash",
|
|
10
|
+
"encryption",
|
|
11
|
+
"crypto",
|
|
12
|
+
"protocol",
|
|
13
|
+
"binary",
|
|
14
|
+
"hybrid",
|
|
15
|
+
"fast",
|
|
16
|
+
"secure",
|
|
17
|
+
"quantum"
|
|
18
|
+
],
|
|
19
|
+
"homepage": "https://github.com/DevsDaddy/quarkdash#readme",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/DevsDaddy/quarkdash/issues"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/DevsDaddy/quarkdash.git"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"author": "Elijah Rastroguev",
|
|
29
|
+
"main": "dist/cjs/index.js",
|
|
30
|
+
"module": "dist/esm/index.js",
|
|
31
|
+
"types": "dist/types/index.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"import": "./dist/esm/index.js",
|
|
35
|
+
"require": "./dist/cjs/index.js",
|
|
36
|
+
"types": "./dist/types/index.d.ts"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"clean": "rm -rf dist",
|
|
41
|
+
"build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:types",
|
|
42
|
+
"build:esm": "tsc -p tsconfig.json",
|
|
43
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
44
|
+
"build:types": "tsc -p tsconfig.json --emitDeclarationOnly --declaration --outDir dist/types",
|
|
45
|
+
"test": "jest --coverage",
|
|
46
|
+
"test:watch": "jest --watch",
|
|
47
|
+
"bench": "ts-node --compiler-options '{\"module\":\"CommonJS\"}' benchmarks/bench.ts",
|
|
48
|
+
"prepublishOnly": "npm run build && npm test"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/jest": "^29.5.0",
|
|
52
|
+
"@types/node": "^20.0.0",
|
|
53
|
+
"jest": "^29.5.0",
|
|
54
|
+
"ts-jest": "^29.1.0",
|
|
55
|
+
"ts-node": "^10.9.0",
|
|
56
|
+
"typescript": "^5.0.0",
|
|
57
|
+
"ws": "^8.14.0"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {},
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=16.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|
package/src/cipher.ts
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QuarkDash Ciphers Implementation
|
|
3
|
+
*
|
|
4
|
+
* @git https://github.com/devsdaddy/quarkdash
|
|
5
|
+
* @version 1.0.0
|
|
6
|
+
* @author Elijah Rastorguev
|
|
7
|
+
* @build 1000
|
|
8
|
+
* @website https://dev.to/devsdaddy
|
|
9
|
+
*/
|
|
10
|
+
/* Import Required Modules */
|
|
11
|
+
import {ICipher} from "./types";
|
|
12
|
+
import {QuarkDashUtils} from "./utils";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Cipher Type
|
|
16
|
+
*/
|
|
17
|
+
export enum CipherType {
|
|
18
|
+
ChaCha20 = 0,
|
|
19
|
+
Gimli = 1
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Cipher Factory
|
|
24
|
+
*/
|
|
25
|
+
export class CipherFactory {
|
|
26
|
+
/**
|
|
27
|
+
* Create Cipher
|
|
28
|
+
* @param algorithm {CipherType} Current cipher type
|
|
29
|
+
* @param key {Uint8Array} Key buffer
|
|
30
|
+
* @param nonce {Uint8Array} Nonce buffer
|
|
31
|
+
* @returns {ICipher} Cipher class instance
|
|
32
|
+
*/
|
|
33
|
+
static create(algorithm: CipherType, key: Uint8Array, nonce: Uint8Array): ICipher {
|
|
34
|
+
switch(algorithm) {
|
|
35
|
+
case CipherType.ChaCha20: return new QuarkDashChaCha(key, nonce);
|
|
36
|
+
case CipherType.Gimli: return new QuarkDashGimli(key, nonce);
|
|
37
|
+
default: throw new Error('Unsupported cipher type');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* ChaCha20 Based Cipher Implementation
|
|
44
|
+
*/
|
|
45
|
+
export class QuarkDashChaCha implements ICipher {
|
|
46
|
+
// Key and Nonce
|
|
47
|
+
private readonly key: Uint8Array;
|
|
48
|
+
private readonly nonce: Uint8Array;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Create ChaCha20 Cipher
|
|
52
|
+
* @param key {Uint8Array} Key buffer
|
|
53
|
+
* @param nonce {Uint8Array} Nonce buffer
|
|
54
|
+
*/
|
|
55
|
+
constructor(key: Uint8Array, nonce: Uint8Array) {
|
|
56
|
+
if (key.length !== 32) throw new Error('Key must be 32 bytes');
|
|
57
|
+
if (nonce.length !== 12) throw new Error('Nonce must be 12 bytes');
|
|
58
|
+
this.key = key;
|
|
59
|
+
this.nonce = nonce;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Encrypt data async using ChaCha20
|
|
64
|
+
* @param data {Uint8Array} Raw data buffer
|
|
65
|
+
* @returns {Promise<Uint8Array>} Result buffer
|
|
66
|
+
* TODO: GPU Calculations
|
|
67
|
+
*/
|
|
68
|
+
public async encrypt(data: Uint8Array): Promise<Uint8Array> { return this.process(data); }
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Decrypt data async using ChaCha20
|
|
72
|
+
* @param data {Uint8Array} Encrypted raw data buffer
|
|
73
|
+
* @returns {Promise<Uint8Array>} Result buffer
|
|
74
|
+
* TODO: GPU Calculations
|
|
75
|
+
*/
|
|
76
|
+
public async decrypt(data: Uint8Array): Promise<Uint8Array> { return this.process(data); }
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Encrypt data sync using ChaCha20
|
|
80
|
+
* @param data {Uint8Array} Raw data buffer
|
|
81
|
+
* @returns {Uint8Array} Result buffer
|
|
82
|
+
*/
|
|
83
|
+
public encryptSync(data: Uint8Array): Uint8Array { return this.process(data); }
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Decrypt data sync using ChaCha20
|
|
87
|
+
* @param data {Uint8Array} Encrypted raw data buffer
|
|
88
|
+
* @returns {Uint8Array} Result buffer
|
|
89
|
+
*/
|
|
90
|
+
public decryptSync(data: Uint8Array): Uint8Array { return this.process(data); }
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Process ChaCha20 Cipher
|
|
94
|
+
* @param data {Uint8Array} Data for processing
|
|
95
|
+
* @returns {Uint8Array} Processing result
|
|
96
|
+
* @private
|
|
97
|
+
*/
|
|
98
|
+
private process(data: Uint8Array): Uint8Array {
|
|
99
|
+
const out = new Uint8Array(data.length);
|
|
100
|
+
let block = 0;
|
|
101
|
+
let pos = 0;
|
|
102
|
+
while (pos < data.length) {
|
|
103
|
+
const ks = this.keystreamBlock(block);
|
|
104
|
+
const len = Math.min(64, data.length - pos);
|
|
105
|
+
for (let i = 0; i < len; i++) out[pos+i] = data[pos+i] ^ ks[i];
|
|
106
|
+
pos += len;
|
|
107
|
+
block++;
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get keystream block
|
|
114
|
+
* @param counter {number} counter
|
|
115
|
+
* @returns {Uint8Array} result buffer
|
|
116
|
+
* @private
|
|
117
|
+
*/
|
|
118
|
+
private keystreamBlock(counter: number): Uint8Array {
|
|
119
|
+
const state = new Uint32Array(16);
|
|
120
|
+
state[0]=0x61707865; state[1]=0x3320646e; state[2]=0x79622d32; state[3]=0x6b206574;
|
|
121
|
+
for (let i=0;i<8;i++) state[4+i] = QuarkDashUtils.readU32(this.key, i*4);
|
|
122
|
+
state[12] = counter;
|
|
123
|
+
for (let i=0;i<3;i++) state[13+i] = QuarkDashUtils.readU32(this.nonce, i*4);
|
|
124
|
+
const working = new Uint32Array(state);
|
|
125
|
+
for (let r=0;r<10;r++) {
|
|
126
|
+
this.quarterRound(working,0,4,8,12); this.quarterRound(working,1,5,9,13);
|
|
127
|
+
this.quarterRound(working,2,6,10,14); this.quarterRound(working,3,7,11,15);
|
|
128
|
+
this.quarterRound(working,0,5,10,15); this.quarterRound(working,1,6,11,12);
|
|
129
|
+
this.quarterRound(working,2,7,8,13); this.quarterRound(working,3,4,9,14);
|
|
130
|
+
}
|
|
131
|
+
for(let i=0;i<16;i++) working[i] += state[i];
|
|
132
|
+
const out = new Uint8Array(64);
|
|
133
|
+
for(let i=0;i<16;i++) QuarkDashUtils.writeU32(working[i], out, i*4);
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Quarter Round
|
|
139
|
+
* @param s {Uint8Array} Buffer
|
|
140
|
+
* @param a {number}
|
|
141
|
+
* @param b {number}
|
|
142
|
+
* @param c {number}
|
|
143
|
+
* @param d {number}
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
private quarterRound(s:Uint32Array, a:number,b:number,c:number,d:number){
|
|
147
|
+
s[a] += s[b]; s[d] ^= s[a]; s[d] = (s[d]<<16)|(s[d]>>>16);
|
|
148
|
+
s[c] += s[d]; s[b] ^= s[c]; s[b] = (s[b]<<12)|(s[b]>>>20);
|
|
149
|
+
s[a] += s[b]; s[d] ^= s[a]; s[d] = (s[d]<<8)|(s[d]>>>24);
|
|
150
|
+
s[c] += s[d]; s[b] ^= s[c]; s[b] = (s[b]<<7)|(s[b]>>>25);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Gimli Cipher
|
|
156
|
+
*/
|
|
157
|
+
export class QuarkDashGimli implements ICipher {
|
|
158
|
+
// Key and Nonce
|
|
159
|
+
private readonly key: Uint8Array;
|
|
160
|
+
private readonly nonce: Uint8Array;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Create Gimli Cipher
|
|
164
|
+
* @param key {Uint8Array} Key buffer
|
|
165
|
+
* @param nonce {Uint8Array} Nonce buffer
|
|
166
|
+
*/
|
|
167
|
+
constructor(key: Uint8Array, nonce: Uint8Array) {
|
|
168
|
+
if (key.length !== 32) throw new Error('Key must be 32 bytes');
|
|
169
|
+
if (nonce.length !== 12) throw new Error('Nonce must be 12 bytes');
|
|
170
|
+
this.key = key;
|
|
171
|
+
this.nonce = nonce;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Encrypt data async using Gimli
|
|
176
|
+
* @param data {Uint8Array} Raw data buffer
|
|
177
|
+
* @returns {Promise<Uint8Array>} Result buffer
|
|
178
|
+
* TODO: GPU Calculations
|
|
179
|
+
*/
|
|
180
|
+
public async encrypt(data: Uint8Array): Promise<Uint8Array> { return this.process(data); }
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Decrypt data async using Gimli
|
|
184
|
+
* @param data {Uint8Array} Encrypted raw data buffer
|
|
185
|
+
* @returns {Promise<Uint8Array>} Result buffer
|
|
186
|
+
* TODO: GPU Calculations
|
|
187
|
+
*/
|
|
188
|
+
public async decrypt(data: Uint8Array): Promise<Uint8Array> { return this.process(data); }
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Encrypt data sync using Gimli
|
|
192
|
+
* @param data {Uint8Array} Raw data buffer
|
|
193
|
+
* @returns {Uint8Array} Result buffer
|
|
194
|
+
*/
|
|
195
|
+
public encryptSync(data: Uint8Array): Uint8Array { return this.process(data); }
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Decrypt data sync using Gimli
|
|
199
|
+
* @param data {Uint8Array} Encrypted raw data buffer
|
|
200
|
+
* @returns {Uint8Array} Result buffer
|
|
201
|
+
*/
|
|
202
|
+
public decryptSync(data: Uint8Array): Uint8Array { return this.process(data); }
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Process Gimli Cipher
|
|
206
|
+
* @param data {Uint8Array} Input buffer
|
|
207
|
+
* @returns {Uint8Array} Output buffer
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
210
|
+
private process(data: Uint8Array): Uint8Array {
|
|
211
|
+
const out = new Uint8Array(data.length);
|
|
212
|
+
let block = 0;
|
|
213
|
+
let pos = 0;
|
|
214
|
+
while (pos < data.length) {
|
|
215
|
+
const ks = this.keystreamBlock(block);
|
|
216
|
+
const len = Math.min(48, data.length - pos);
|
|
217
|
+
for (let i = 0; i < len; i++) out[pos+i] = data[pos+i] ^ ks[i];
|
|
218
|
+
pos += len;
|
|
219
|
+
block++;
|
|
220
|
+
}
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Get keystream block
|
|
226
|
+
* @param counter {number} Counter
|
|
227
|
+
* @returns {Uint8Array} Result buffer
|
|
228
|
+
* @private
|
|
229
|
+
*/
|
|
230
|
+
private keystreamBlock(counter: number): Uint8Array {
|
|
231
|
+
const state = new Uint32Array(12);
|
|
232
|
+
for (let i=0;i<8;i++) state[i] = QuarkDashUtils.readU32(this.key, i*4);
|
|
233
|
+
state[8] = QuarkDashUtils.readU32(this.nonce,0);
|
|
234
|
+
state[9] = QuarkDashUtils.readU32(this.nonce,4);
|
|
235
|
+
state[10] = QuarkDashUtils.readU32(this.nonce,8);
|
|
236
|
+
state[11] = counter;
|
|
237
|
+
for (let r=0;r<24;r++) this.gimliRound(state, r);
|
|
238
|
+
const out = new Uint8Array(48);
|
|
239
|
+
for(let i=0;i<12;i++) QuarkDashUtils.writeU32(state[i], out, i*4);
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Gimli Round
|
|
245
|
+
* @param state {Uint32Array} State buffer
|
|
246
|
+
* @param round {number} Round number
|
|
247
|
+
* @private
|
|
248
|
+
*/
|
|
249
|
+
private gimliRound(state:Uint32Array, round:number){
|
|
250
|
+
for(let i=0;i<4;i++){
|
|
251
|
+
const x=state[i], y=state[i+4], z=state[i+8];
|
|
252
|
+
const newX = x ^ (z<<1) ^ ((y&z)<<2);
|
|
253
|
+
const newY = y ^ x ^ ((x|z)<<1);
|
|
254
|
+
const newZ = z ^ y ^ ((x&y)<<3);
|
|
255
|
+
state[i]=newX; state[i+4]=newY; state[i+8]=newZ;
|
|
256
|
+
}
|
|
257
|
+
const t=state[1]; state[1]=state[2]; state[2]=state[3]; state[3]=t;
|
|
258
|
+
if((round&3)===0) state[0] ^= (0x9e377900 | round);
|
|
259
|
+
}
|
|
260
|
+
}
|