quarkdash 1.0.5 → 1.0.8

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.
@@ -4,8 +4,9 @@
4
4
  * @git https://github.com/devsdaddy/quarkdash
5
5
  * @version 1.0.0
6
6
  * @author Elijah Rastorguev
7
- * @build 1000
7
+ * @build 1002
8
8
  * @website https://dev.to/devsdaddy
9
+ * @updated 12.04.2026
9
10
  */
10
11
  import { ICryptoEncapsulated, ICryptoKeyPair, IKeyExchange } from "./types";
11
12
  /**
@@ -16,6 +17,47 @@ export declare class QuarkDashKeyExchange implements IKeyExchange {
16
17
  private static readonly Q;
17
18
  private static readonly ROOT;
18
19
  private static readonly INV_N;
20
+ /**
21
+ * Generate crypto key pair async
22
+ * @returns {ICryptoKeyPair} Crypto key pair
23
+ * TODO: GPU Calculations
24
+ */
25
+ generateKeyPair(): Promise<ICryptoKeyPair>;
26
+ /**
27
+ * Generate crypto key pair sync
28
+ * @returns {ICryptoKeyPair} Crypto key pair
29
+ */
30
+ generateKeyPairSync(): ICryptoKeyPair;
31
+ /**
32
+ * Encapsulate async
33
+ * @param publicKey {Uint8Array} Public key buffer
34
+ * @returns {Promise<ICryptoEncapsulated>} Encapsulated data
35
+ * TODO: GPU Calculations
36
+ */
37
+ encapsulate(publicKey: Uint8Array): Promise<ICryptoEncapsulated>;
38
+ /**
39
+ * Encapsulate sync
40
+ * @param publicKey {Uint8Array} Public key buffer
41
+ * @returns {ICryptoEncapsulated} Encapsulated data
42
+ */
43
+ encapsulateSync(publicKey: Uint8Array): ICryptoEncapsulated;
44
+ /**
45
+ * Decapsulate async
46
+ * @param privateKey {Uint8Array} Private key buffer
47
+ * @param peerPublicKey {Uint8Array} Peer public key
48
+ * @param ciphertext {Uint8Array} Cipher text buffer
49
+ * @returns {Promise<Uint8Array>} Buffer data
50
+ * TODO: GPU Calculations
51
+ */
52
+ decapsulate(privateKey: Uint8Array, peerPublicKey: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array>;
53
+ /**
54
+ * Decapsulate sync
55
+ * @param privateKey {Uint8Array} Private key buffer
56
+ * @param peerPublicKey{Uint8Array} Peer public key buffer
57
+ * @param ciphertext {Uint8Array} Cipher text buffer
58
+ * @returns {Uint8Array} Buffer data
59
+ */
60
+ decapsulateSync(privateKey: Uint8Array, peerPublicKey: Uint8Array, ciphertext: Uint8Array): Uint8Array;
19
61
  /**
20
62
  * Get small polygon
21
63
  * @returns {bigint[]} Small polygon
@@ -28,6 +70,11 @@ export declare class QuarkDashKeyExchange implements IKeyExchange {
28
70
  * @private
29
71
  */
30
72
  private static uniformPoly;
73
+ /**
74
+ * Error polygon
75
+ * @private
76
+ */
77
+ private static errorPoly;
31
78
  /**
32
79
  * NTT Operation
33
80
  * @param poly {bigint[]} Polygon
@@ -85,47 +132,6 @@ export declare class QuarkDashKeyExchange implements IKeyExchange {
85
132
  * @private
86
133
  */
87
134
  private static modInverse;
88
- /**
89
- * Generate crypto key pair async
90
- * @returns {ICryptoKeyPair} Crypto key pair
91
- * TODO: GPU Calculations
92
- */
93
- generateKeyPair(): Promise<ICryptoKeyPair>;
94
- /**
95
- * Generate crypto key pair sync
96
- * @returns {ICryptoKeyPair} Crypto key pair
97
- */
98
- generateKeyPairSync(): ICryptoKeyPair;
99
- /**
100
- * Encapsulate async
101
- * @param publicKey {Uint8Array} Public key buffer
102
- * @returns {Promise<ICryptoEncapsulated>} Encapsulated data
103
- * TODO: GPU Calculations
104
- */
105
- encapsulate(publicKey: Uint8Array): Promise<ICryptoEncapsulated>;
106
- /**
107
- * Encapsulate sync
108
- * @param publicKey {Uint8Array} Public key buffer
109
- * @returns {ICryptoEncapsulated} Encapsulated data
110
- */
111
- encapsulateSync(publicKey: Uint8Array): ICryptoEncapsulated;
112
- /**
113
- * Decapsulate async
114
- * @param privateKey {Uint8Array} Private key buffer
115
- * @param peerPublicKey {Uint8Array} Peer public key
116
- * @param ciphertext {Uint8Array} Cipher text buffer
117
- * @returns {Promise<Uint8Array>} Buffer data
118
- * TODO: GPU Calculations
119
- */
120
- decapsulate(privateKey: Uint8Array, peerPublicKey: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array>;
121
- /**
122
- * Decapsulate sync
123
- * @param privateKey {Uint8Array} Private key buffer
124
- * @param peerPublicKey{Uint8Array} Peer public key buffer
125
- * @param ciphertext {Uint8Array} Cipher text buffer
126
- * @returns {Uint8Array} Buffer data
127
- */
128
- decapsulateSync(privateKey: Uint8Array, peerPublicKey: Uint8Array, ciphertext: Uint8Array): Uint8Array;
129
135
  /**
130
136
  * Hash shared secret
131
137
  * @param ss {Uint8Array} Shared secret buffer
@@ -134,5 +140,5 @@ export declare class QuarkDashKeyExchange implements IKeyExchange {
134
140
  * @returns {Uint8Array} Shared secret hash
135
141
  * @private
136
142
  */
137
- private hashSharedSecret;
143
+ private static hashSharedSecret;
138
144
  }
package/docutil.ts ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * JSDoc Util to change headers
3
+ *
4
+ * @author Elijah Rastorguev
5
+ * @version 1.0.0
6
+ * @build 1005
7
+ * @git https://github.com/devsdaddy/bitwarp
8
+ * @license MIT
9
+ * @updated 12.04.2026
10
+ */
11
+ import { Project, SyntaxKind } from "ts-morph";
12
+ import { execSync } from "child_process";
13
+
14
+ /**
15
+ * JSDoc Change Util
16
+ */
17
+ async function updateJSDocInChangedFiles() {
18
+ // Get all changed files via GIT
19
+ const changedFiles = execSync("git diff --name-only").toString().trim().split("\n").filter(file => file.endsWith(".ts"));
20
+
21
+ if (changedFiles.length === 0) {
22
+ console.log("No changes found in project.");
23
+ return;
24
+ }
25
+
26
+ console.log(`Found changed files: ${changedFiles.length}`);
27
+
28
+ // Create ts-morph project
29
+ const project = new Project({
30
+ tsConfigFilePath: "tsconfig.json",
31
+ skipAddingFilesFromTsConfig: true, // Only changed
32
+ });
33
+
34
+ // Add changed files
35
+ changedFiles.forEach(file => project.addSourceFileAtPath(file));
36
+
37
+ // Prepare date for @updated
38
+ const today = new Date();
39
+ const formattedDate = `${today.getDate().toString().padStart(2, '0')}.${(today.getMonth() + 1).toString().padStart(2, '0')}.${today.getFullYear()}`;
40
+ let filesUpdatedCount = 0;
41
+
42
+ // Change every changed file
43
+ for (const sourceFile of project.getSourceFiles()) {
44
+ let fileWasModified = false;
45
+ const jsdocs = sourceFile.getDescendantsOfKind(SyntaxKind.JSDoc);
46
+
47
+ for (const jsdoc of jsdocs) {
48
+ const buildTag = jsdoc.getTags().find(tag => tag.getTagName() === "build");
49
+ const updatedTag = jsdoc.getTags().find(tag => tag.getTagName() === "updated");
50
+
51
+ // Work with @build
52
+ if (buildTag) {
53
+ const commentText = buildTag.getCommentText();
54
+ if (commentText) {
55
+ const currentBuild = parseInt(commentText.trim(), 10);
56
+ if (!isNaN(currentBuild)) {
57
+ const newBuild = currentBuild + 1;
58
+ buildTag.replaceWithText(`@build ${newBuild}`);
59
+ fileWasModified = true;
60
+ console.log(` -> File: ${sourceFile.getFilePath()}, @build updated from ${currentBuild} to ${newBuild}`);
61
+ }
62
+ }
63
+ }
64
+
65
+ // Work with @updated
66
+ if (updatedTag) {
67
+ updatedTag.replaceWithText(`@updated ${formattedDate}`);
68
+ fileWasModified = true;
69
+ console.log(` -> File: ${sourceFile.getFilePath()}, @updated changed to ${formattedDate}`);
70
+ }
71
+ }
72
+
73
+ // Save modified file
74
+ if (fileWasModified) {
75
+ await sourceFile.save();
76
+ filesUpdatedCount++;
77
+ }
78
+ }
79
+
80
+ console.log(`Done! Updated files: ${filesUpdatedCount}.`);
81
+ }
82
+
83
+ // Update JSDoc in Changed Files
84
+ updateJSDocInChangedFiles().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quarkdash",
3
- "version": "1.0.5",
3
+ "version": "1.0.8",
4
4
  "description": "QuarkDash - pure typescript hybrid cryptographic protocol that provides post-quantum security, high performance, and attack resistance.",
5
5
  "keywords": [
6
6
  "quark",
@@ -37,8 +37,9 @@
37
37
  }
38
38
  },
39
39
  "scripts": {
40
+ "update-docs": "ts-node docutil.ts",
40
41
  "clean": "rm -rf dist",
41
- "build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:types",
42
+ "build": "npm run clean && npm run update-docs && npm run build:esm && npm run build:cjs && npm run build:types",
42
43
  "build:esm": "tsc -p tsconfig.json",
43
44
  "build:cjs": "tsc -p tsconfig.cjs.json",
44
45
  "build:types": "tsc -p tsconfig.json --emitDeclarationOnly --declaration --outDir dist/types",
@@ -50,6 +51,7 @@
50
51
  "devDependencies": {
51
52
  "@types/jest": "^29.5.0",
52
53
  "@types/node": "^20.0.0",
54
+ "ts-morph": "^27.0.2",
53
55
  "jest": "^29.5.0",
54
56
  "ts-jest": "^29.1.0",
55
57
  "ts-node": "^10.9.0",
package/src/ringlwe.ts CHANGED
@@ -4,8 +4,9 @@
4
4
  * @git https://github.com/devsdaddy/quarkdash
5
5
  * @version 1.0.0
6
6
  * @author Elijah Rastorguev
7
- * @build 1000
7
+ * @build 1002
8
8
  * @website https://dev.to/devsdaddy
9
+ * @updated 12.04.2026
9
10
  */
10
11
  /* Import Required Modules */
11
12
  import {ICryptoEncapsulated, ICryptoKeyPair, IKeyExchange} from "./types";
@@ -22,6 +23,96 @@ export class QuarkDashKeyExchange implements IKeyExchange {
22
23
  private static readonly ROOT = 7n;
23
24
  private static readonly INV_N = this.modInverse(BigInt(this.N), this.Q);
24
25
 
26
+ /**
27
+ * Generate crypto key pair async
28
+ * @returns {ICryptoKeyPair} Crypto key pair
29
+ * TODO: GPU Calculations
30
+ */
31
+ public async generateKeyPair(): Promise<ICryptoKeyPair> {
32
+ return this.generateKeyPairSync();
33
+ }
34
+
35
+ /**
36
+ * Generate crypto key pair sync
37
+ * @returns {ICryptoKeyPair} Crypto key pair
38
+ */
39
+ public generateKeyPairSync(): ICryptoKeyPair {
40
+ const a = QuarkDashKeyExchange.uniformPoly();
41
+ const s = QuarkDashKeyExchange.smallPoly();
42
+ const e = QuarkDashKeyExchange.errorPoly();
43
+ const as = QuarkDashKeyExchange.multiply(a, s);
44
+ const b = new Array<bigint>(QuarkDashKeyExchange.N);
45
+ for (let i = 0; i < QuarkDashKeyExchange.N; i++) {
46
+ b[i] = (as[i] + e[i]) % QuarkDashKeyExchange.Q;
47
+ }
48
+ const publicKey = QuarkDashUtils.concatBytes(
49
+ QuarkDashKeyExchange.serializePoly(a),
50
+ QuarkDashKeyExchange.serializePoly(b)
51
+ );
52
+ const privateKey = QuarkDashKeyExchange.serializePoly(s);
53
+ return { publicKey, privateKey };
54
+ }
55
+
56
+ /**
57
+ * Encapsulate async
58
+ * @param publicKey {Uint8Array} Public key buffer
59
+ * @returns {Promise<ICryptoEncapsulated>} Encapsulated data
60
+ * TODO: GPU Calculations
61
+ */
62
+ public async encapsulate(publicKey: Uint8Array): Promise<ICryptoEncapsulated> {
63
+ return this.encapsulateSync(publicKey);
64
+ }
65
+
66
+ /**
67
+ * Encapsulate sync
68
+ * @param publicKey {Uint8Array} Public key buffer
69
+ * @returns {ICryptoEncapsulated} Encapsulated data
70
+ */
71
+ public encapsulateSync(publicKey: Uint8Array): ICryptoEncapsulated {
72
+ const aBytes = publicKey.slice(0, QuarkDashKeyExchange.N * 2);
73
+ const bBytes = publicKey.slice(QuarkDashKeyExchange.N * 2);
74
+ const a = QuarkDashKeyExchange.deserializePoly(aBytes);
75
+ const b = QuarkDashKeyExchange.deserializePoly(bBytes);
76
+ const sp = QuarkDashKeyExchange.smallPoly();
77
+ const ep = QuarkDashKeyExchange.errorPoly();
78
+ const uArr = QuarkDashKeyExchange.multiply(a, sp);
79
+ for (let i = 0; i < QuarkDashKeyExchange.N; i++) {
80
+ uArr[i] = (uArr[i] + ep[i]) % QuarkDashKeyExchange.Q;
81
+ }
82
+ const w = QuarkDashKeyExchange.multiply(b, sp);
83
+ const rawSecret = QuarkDashKeyExchange.roundToBits(w);
84
+ const ciphertext = QuarkDashKeyExchange.serializePoly(uArr);
85
+ const sharedSecret = QuarkDashKeyExchange.hashSharedSecret(rawSecret, publicKey, ciphertext);
86
+ return { ciphertext, sharedSecret };
87
+ }
88
+
89
+ /**
90
+ * Decapsulate async
91
+ * @param privateKey {Uint8Array} Private key buffer
92
+ * @param peerPublicKey {Uint8Array} Peer public key
93
+ * @param ciphertext {Uint8Array} Cipher text buffer
94
+ * @returns {Promise<Uint8Array>} Buffer data
95
+ * TODO: GPU Calculations
96
+ */
97
+ public async decapsulate(privateKey: Uint8Array, peerPublicKey: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array> {
98
+ return this.decapsulateSync(privateKey, peerPublicKey, ciphertext);
99
+ }
100
+
101
+ /**
102
+ * Decapsulate sync
103
+ * @param privateKey {Uint8Array} Private key buffer
104
+ * @param peerPublicKey{Uint8Array} Peer public key buffer
105
+ * @param ciphertext {Uint8Array} Cipher text buffer
106
+ * @returns {Uint8Array} Buffer data
107
+ */
108
+ public decapsulateSync(privateKey: Uint8Array, peerPublicKey: Uint8Array, ciphertext: Uint8Array): Uint8Array {
109
+ const s = QuarkDashKeyExchange.deserializePoly(privateKey);
110
+ const u = QuarkDashKeyExchange.deserializePoly(ciphertext);
111
+ const w = QuarkDashKeyExchange.multiply(u, s);
112
+ const rawSecret = QuarkDashKeyExchange.roundToBits(w);
113
+ return QuarkDashKeyExchange.hashSharedSecret(rawSecret, peerPublicKey, ciphertext);
114
+ }
115
+
25
116
  /**
26
117
  * Get small polygon
27
118
  * @returns {bigint[]} Small polygon
@@ -29,11 +120,18 @@ export class QuarkDashKeyExchange implements IKeyExchange {
29
120
  */
30
121
  private static smallPoly(): bigint[] {
31
122
  const poly = new Array<bigint>(this.N);
32
- for (let i=0;i<this.N;i++) {
33
- const r = Math.random();
34
- if (r<0.33) poly[i] = -1n;
35
- else if (r<0.66) poly[i] = 0n;
36
- else poly[i] = 1n;
123
+ const bytesNeeded = Math.ceil(this.N * 2 / 8);
124
+ const randomBytes = QuarkDashUtils.randomBytes(bytesNeeded);
125
+ for (let i = 0; i < this.N; i++) {
126
+ const byteIdx = Math.floor(i * 2 / 8);
127
+ const bitShift = (i * 2) % 8;
128
+ const val = (randomBytes[byteIdx] >> bitShift) & 0x03; // 0..3
129
+ if (val === 0) poly[i] = -1n;
130
+ else if (val === 1) poly[i] = 0n;
131
+ else if (val === 2) poly[i] = 1n;
132
+ else {
133
+ poly[i] = 1n;
134
+ }
37
135
  }
38
136
  return poly;
39
137
  }
@@ -45,14 +143,35 @@ export class QuarkDashKeyExchange implements IKeyExchange {
45
143
  */
46
144
  private static uniformPoly(): bigint[] {
47
145
  const poly = new Array<bigint>(this.N);
48
- const bytes = QuarkDashUtils.randomBytes(this.N*2);
49
- for(let i=0;i<this.N;i++) {
50
- const val = (bytes[2*i] | (bytes[2*i+1]<<8)) % Number(this.Q);
146
+ const bytes = QuarkDashUtils.randomBytes(this.N * 2);
147
+ for (let i = 0; i < this.N; i++) {
148
+ const val = (bytes[2 * i] | (bytes[2 * i + 1] << 8)) % Number(this.Q);
51
149
  poly[i] = BigInt(val);
52
150
  }
53
151
  return poly;
54
152
  }
55
153
 
154
+ /**
155
+ * Error polygon
156
+ * @private
157
+ */
158
+ private static errorPoly(): bigint[] {
159
+ const poly = new Array<bigint>(this.N);
160
+ const SIGMA = 3.19;
161
+ for (let i = 0; i < this.N; i++) {
162
+ let sum = 0;
163
+ const randBytes = QuarkDashUtils.randomBytes(12);
164
+ for (let j = 0; j < 12; j++) {
165
+ sum += randBytes[j];
166
+ }
167
+ // Центрируем и масштабируем к [-6,6]
168
+ const centered = (sum / 255) - 6;
169
+ const error = Math.floor(centered * SIGMA);
170
+ poly[i] = BigInt(Math.max(-Number(this.Q), Math.min(Number(this.Q) - 1, error)));
171
+ }
172
+ return poly;
173
+ }
174
+
56
175
  /**
57
176
  * NTT Operation
58
177
  * @param poly {bigint[]} Polygon
@@ -61,19 +180,19 @@ export class QuarkDashKeyExchange implements IKeyExchange {
61
180
  private static ntt(poly: bigint[]): bigint[] {
62
181
  const res = [...poly];
63
182
  let len = 2;
64
- while(len <= this.N) {
65
- const wlen = this.powMod(this.ROOT, BigInt(this.N/len), this.Q);
66
- for(let i=0;i<this.N;i+=len){
67
- let w=1n;
68
- for(let j=0;j<len/2;j++){
69
- const u=res[i+j];
70
- const v=(res[i+j+len/2]*w)%this.Q;
71
- res[i+j]=(u+v)%this.Q;
72
- res[i+j+len/2]=(u-v+this.Q)%this.Q;
73
- w=(w*wlen)%this.Q;
183
+ while (len <= this.N) {
184
+ const wlen = this.powMod(this.ROOT, BigInt(this.N / len), this.Q);
185
+ for (let i = 0; i < this.N; i += len) {
186
+ let w = 1n;
187
+ for (let j = 0; j < len / 2; j++) {
188
+ const u = res[i + j];
189
+ const v = (res[i + j + len / 2] * w) % this.Q;
190
+ res[i + j] = (u + v) % this.Q;
191
+ res[i + j + len / 2] = (u - v + this.Q) % this.Q;
192
+ w = (w * wlen) % this.Q;
74
193
  }
75
194
  }
76
- len<<=1;
195
+ len <<= 1;
77
196
  }
78
197
  return res;
79
198
  }
@@ -86,21 +205,23 @@ export class QuarkDashKeyExchange implements IKeyExchange {
86
205
  private static invNTT(poly: bigint[]): bigint[] {
87
206
  const res = [...poly];
88
207
  let len = this.N;
89
- while(len >= 2){
90
- const wlen = this.powMod(this.ROOT, BigInt(this.N/len), this.Q);
91
- for(let i=0;i<this.N;i+=len){
92
- let w=1n;
93
- for(let j=0;j<len/2;j++){
94
- const u=res[i+j];
95
- const v=res[i+j+len/2];
96
- res[i+j]=(u+v)%this.Q;
97
- res[i+j+len/2]=((u-v+this.Q)*w)%this.Q;
98
- w=(w*wlen)%this.Q;
208
+ while (len >= 2) {
209
+ const wlen = this.powMod(this.ROOT, BigInt(this.N / len), this.Q);
210
+ for (let i = 0; i < this.N; i += len) {
211
+ let w = 1n;
212
+ for (let j = 0; j < len / 2; j++) {
213
+ const u = res[i + j];
214
+ const v = res[i + j + len / 2];
215
+ res[i + j] = (u + v) % this.Q;
216
+ res[i + j + len / 2] = ((u - v + this.Q) * w) % this.Q;
217
+ w = (w * wlen) % this.Q;
99
218
  }
100
219
  }
101
- len>>=1;
220
+ len >>= 1;
221
+ }
222
+ for (let i = 0; i < this.N; i++) {
223
+ res[i] = (res[i] * this.INV_N) % this.Q;
102
224
  }
103
- for(let i=0;i<this.N;i++) res[i]=(res[i]*this.INV_N)%this.Q;
104
225
  return res;
105
226
  }
106
227
 
@@ -114,7 +235,9 @@ export class QuarkDashKeyExchange implements IKeyExchange {
114
235
  const aNTT = this.ntt(a);
115
236
  const bNTT = this.ntt(b);
116
237
  const prod = new Array<bigint>(this.N);
117
- for(let i=0;i<this.N;i++) prod[i]=(aNTT[i]*bNTT[i])%this.Q;
238
+ for (let i = 0; i < this.N; i++) {
239
+ prod[i] = (aNTT[i] * bNTT[i]) % this.Q;
240
+ }
118
241
  return this.invNTT(prod);
119
242
  }
120
243
 
@@ -125,11 +248,11 @@ export class QuarkDashKeyExchange implements IKeyExchange {
125
248
  * @private
126
249
  */
127
250
  private static serializePoly(poly: bigint[]): Uint8Array {
128
- const bytes = new Uint8Array(this.N*2);
129
- for(let i=0;i<this.N;i++) {
251
+ const bytes = new Uint8Array(this.N * 2);
252
+ for (let i = 0; i < this.N; i++) {
130
253
  const val = Number(poly[i]);
131
- bytes[2*i]=val&0xFF;
132
- bytes[2*i+1]=(val>>8)&0xFF;
254
+ bytes[2 * i] = val & 0xFF;
255
+ bytes[2 * i + 1] = (val >> 8) & 0xFF;
133
256
  }
134
257
  return bytes;
135
258
  }
@@ -142,9 +265,9 @@ export class QuarkDashKeyExchange implements IKeyExchange {
142
265
  */
143
266
  private static deserializePoly(bytes: Uint8Array): bigint[] {
144
267
  const poly = new Array<bigint>(this.N);
145
- for(let i=0;i<this.N;i++) {
146
- const val = bytes[2*i] | (bytes[2*i+1]<<8);
147
- poly[i]=BigInt(val);
268
+ for (let i = 0; i < this.N; i++) {
269
+ const val = bytes[2 * i] | (bytes[2 * i + 1] << 8);
270
+ poly[i] = BigInt(val);
148
271
  }
149
272
  return poly;
150
273
  }
@@ -157,9 +280,9 @@ export class QuarkDashKeyExchange implements IKeyExchange {
157
280
  */
158
281
  private static roundToBits(poly: bigint[]): Uint8Array {
159
282
  const result = new Uint8Array(32);
160
- for(let i=0;i<this.N;i++) {
161
- const bit = (Number(poly[i]) > Number(this.Q)/2) ? 1 : 0;
162
- if(bit) result[i>>3] |= (1<<(i&7));
283
+ for (let i = 0; i < this.N; i++) {
284
+ const bit = (Number(poly[i]) > Number(this.Q) / 2) ? 1 : 0;
285
+ if (bit) result[i >> 3] |= (1 << (i & 7));
163
286
  }
164
287
  return result;
165
288
  }
@@ -173,8 +296,14 @@ export class QuarkDashKeyExchange implements IKeyExchange {
173
296
  * @private
174
297
  */
175
298
  private static powMod(base: bigint, exp: bigint, mod: bigint): bigint {
176
- let result=1n, b=base%mod, e=exp;
177
- while(e>0n){ if(e&1n) result=(result*b)%mod; b=(b*b)%mod; e>>=1n; }
299
+ let result = 1n;
300
+ let b = base % mod;
301
+ let e = exp;
302
+ while (e > 0n) {
303
+ if (e & 1n) result = (result * b) % mod;
304
+ b = (b * b) % mod;
305
+ e >>= 1n;
306
+ }
178
307
  return result;
179
308
  }
180
309
 
@@ -186,92 +315,14 @@ export class QuarkDashKeyExchange implements IKeyExchange {
186
315
  * @private
187
316
  */
188
317
  private static modInverse(a: bigint, m: bigint): bigint {
189
- let [old_r,r]=[a,m], [old_s,s]=[1n,0n];
190
- while(r!==0n){ const q=old_r/r; [old_r,r]=[r,old_r-q*r]; [old_s,s]=[s,old_s-q*s]; }
191
- return (old_s%m+m)%m;
192
- }
193
-
194
- /**
195
- * Generate crypto key pair async
196
- * @returns {ICryptoKeyPair} Crypto key pair
197
- * TODO: GPU Calculations
198
- */
199
- public async generateKeyPair(): Promise<ICryptoKeyPair> {
200
- return this.generateKeyPairSync();
201
- }
202
-
203
- /**
204
- * Generate crypto key pair sync
205
- * @returns {ICryptoKeyPair} Crypto key pair
206
- */
207
- public generateKeyPairSync(): ICryptoKeyPair {
208
- const a = QuarkDashKeyExchange.uniformPoly();
209
- const s = QuarkDashKeyExchange.smallPoly();
210
- const e = QuarkDashKeyExchange.smallPoly();
211
- const as = QuarkDashKeyExchange.multiply(a,s);
212
- const b = new Array<bigint>(QuarkDashKeyExchange.N);
213
- for(let i=0; i<QuarkDashKeyExchange.N; i++) b[i] = (as[i]+e[i]) % QuarkDashKeyExchange.Q;
214
- const pub = QuarkDashUtils.concatBytes(QuarkDashKeyExchange.serializePoly(a), QuarkDashKeyExchange.serializePoly(b));
215
- const priv = QuarkDashKeyExchange.serializePoly(s);
216
- return { publicKey: pub, privateKey: priv };
217
- }
218
-
219
- /**
220
- * Encapsulate async
221
- * @param publicKey {Uint8Array} Public key buffer
222
- * @returns {Promise<ICryptoEncapsulated>} Encapsulated data
223
- * TODO: GPU Calculations
224
- */
225
- public async encapsulate(publicKey: Uint8Array): Promise<ICryptoEncapsulated> {
226
- return this.encapsulateSync(publicKey);
227
- }
228
-
229
- /**
230
- * Encapsulate sync
231
- * @param publicKey {Uint8Array} Public key buffer
232
- * @returns {ICryptoEncapsulated} Encapsulated data
233
- */
234
- public encapsulateSync(publicKey: Uint8Array): ICryptoEncapsulated {
235
- const aBytes = publicKey.slice(0, QuarkDashKeyExchange.N * 2);
236
- const bBytes = publicKey.slice(QuarkDashKeyExchange.N * 2);
237
- const a = QuarkDashKeyExchange.deserializePoly(aBytes);
238
- const b = QuarkDashKeyExchange.deserializePoly(bBytes);
239
- const sp = QuarkDashKeyExchange.smallPoly();
240
- const ep = QuarkDashKeyExchange.smallPoly();
241
- const uArr = QuarkDashKeyExchange.multiply(a, sp);
242
- for (let i = 0; i < QuarkDashKeyExchange.N; i++) uArr[i] = (uArr[i] + ep[i]) % QuarkDashKeyExchange.Q;
243
- const w = QuarkDashKeyExchange.multiply(b, sp);
244
- const rawSecret = QuarkDashKeyExchange.roundToBits(w);
245
- const ciphertext = QuarkDashKeyExchange.serializePoly(uArr);
246
- const sharedSecret = this.hashSharedSecret(rawSecret, publicKey, ciphertext);
247
- return { ciphertext, sharedSecret };
248
- }
249
-
250
- /**
251
- * Decapsulate async
252
- * @param privateKey {Uint8Array} Private key buffer
253
- * @param peerPublicKey {Uint8Array} Peer public key
254
- * @param ciphertext {Uint8Array} Cipher text buffer
255
- * @returns {Promise<Uint8Array>} Buffer data
256
- * TODO: GPU Calculations
257
- */
258
- public async decapsulate(privateKey: Uint8Array, peerPublicKey: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array> {
259
- return this.decapsulateSync(privateKey, peerPublicKey, ciphertext);
260
- }
261
-
262
- /**
263
- * Decapsulate sync
264
- * @param privateKey {Uint8Array} Private key buffer
265
- * @param peerPublicKey{Uint8Array} Peer public key buffer
266
- * @param ciphertext {Uint8Array} Cipher text buffer
267
- * @returns {Uint8Array} Buffer data
268
- */
269
- public decapsulateSync(privateKey: Uint8Array, peerPublicKey: Uint8Array, ciphertext: Uint8Array): Uint8Array {
270
- const s = QuarkDashKeyExchange.deserializePoly(privateKey);
271
- const u = QuarkDashKeyExchange.deserializePoly(ciphertext);
272
- const w = QuarkDashKeyExchange.multiply(u, s);
273
- const rawSecret = QuarkDashKeyExchange.roundToBits(w);
274
- return this.hashSharedSecret(rawSecret, peerPublicKey, ciphertext);
318
+ let [old_r, r] = [a, m];
319
+ let [old_s, s] = [1n, 0n];
320
+ while (r !== 0n) {
321
+ const q = old_r / r;
322
+ [old_r, r] = [r, old_r - q * r];
323
+ [old_s, s] = [s, old_s - q * s];
324
+ }
325
+ return (old_s % m + m) % m;
275
326
  }
276
327
 
277
328
  /**
@@ -282,7 +333,7 @@ export class QuarkDashKeyExchange implements IKeyExchange {
282
333
  * @returns {Uint8Array} Shared secret hash
283
334
  * @private
284
335
  */
285
- private hashSharedSecret(ss: Uint8Array, publicKey: Uint8Array, ciphertext: Uint8Array): Uint8Array {
336
+ private static hashSharedSecret(ss: Uint8Array, publicKey: Uint8Array, ciphertext: Uint8Array): Uint8Array {
286
337
  const data = QuarkDashUtils.concatBytes(ss, publicKey, ciphertext);
287
338
  return SHA256.hash(data, true) as Uint8Array;
288
339
  }
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/quarkdash.iml" filepath="$PROJECT_DIR$/.idea/quarkdash.iml" />
6
- </modules>
7
- </component>
8
- </project>
@@ -1,12 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="WEB_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$">
5
- <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
- <excludeFolder url="file://$MODULE_DIR$/temp" />
7
- <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
- </content>
9
- <orderEntry type="inheritedJdk" />
10
- <orderEntry type="sourceFolder" forTests="false" />
11
- </component>
12
- </module>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="" vcs="Git" />
5
- </component>
6
- </project>