neozipkit 0.1.1

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.
Files changed (135) hide show
  1. package/README.md +400 -0
  2. package/contracts/Lock.sol +34 -0
  3. package/contracts/bytecode.txt +1 -0
  4. package/contracts/compile-contract.js +168 -0
  5. package/contracts/deploy/deploy-both-contracts.js +286 -0
  6. package/contracts/deploy/deploy-enhanced-contract.js +197 -0
  7. package/contracts/deploy/deploy-private-contract.js +190 -0
  8. package/contracts/deploy/deploy-public-clean.js +1063 -0
  9. package/contracts/deploy/deploy-public-contract.js +1107 -0
  10. package/contracts/deployment.config.example.js +25 -0
  11. package/contracts/remix-compile.js +222 -0
  12. package/contracts/setup-deployment.js +51 -0
  13. package/contracts/src/NZIP-NFT-Private.sol +350 -0
  14. package/contracts/src/NZIP-NFT.sol +265 -0
  15. package/contracts/src/ZipFileNFT-DEPRECATED-6field.sol +260 -0
  16. package/contracts/src/ZipFileNFT-DEPRECATED-Enhanced.sol +289 -0
  17. package/dist/browser/CertificateGeneratorBrowser.d.ts +75 -0
  18. package/dist/browser/CertificateGeneratorBrowser.js +433 -0
  19. package/dist/browser/TokenVerifierBrowser.d.ts +76 -0
  20. package/dist/browser/TokenVerifierBrowser.js +299 -0
  21. package/dist/browser/ZipKitBrowser.d.ts +18 -0
  22. package/dist/browser/ZipKitBrowser.js +250 -0
  23. package/dist/browser/ZipKitStampBrowser.d.ts +2 -0
  24. package/dist/browser/ZipKitStampBrowser.js +12 -0
  25. package/dist/browser-index.d.ts +21 -0
  26. package/dist/browser-index.js +58 -0
  27. package/dist/browser.d.ts +21 -0
  28. package/dist/browser.js +58 -0
  29. package/dist/index.d.ts +29 -0
  30. package/dist/index.js +76 -0
  31. package/dist/server/blockchain/CertificateToken.d.ts +48 -0
  32. package/dist/server/blockchain/CertificateToken.js +386 -0
  33. package/dist/server/blockchain/NFTMinter.d.ts +41 -0
  34. package/dist/server/blockchain/NFTMinter.js +323 -0
  35. package/dist/server/blockchain/TokenQuerier.d.ts +31 -0
  36. package/dist/server/blockchain/TokenQuerier.js +259 -0
  37. package/dist/server/blockchain/TokenVerifier.d.ts +20 -0
  38. package/dist/server/blockchain/TokenVerifier.js +395 -0
  39. package/dist/server/blockchain/WalletAnalyzer.d.ts +81 -0
  40. package/dist/server/blockchain/WalletAnalyzer.js +356 -0
  41. package/dist/server/blockchain/WalletFormatter.d.ts +39 -0
  42. package/dist/server/blockchain/WalletFormatter.js +196 -0
  43. package/dist/server/blockchain/WalletManager.d.ts +46 -0
  44. package/dist/server/blockchain/WalletManager.js +294 -0
  45. package/dist/server/blockchain/ZipMetadata.d.ts +27 -0
  46. package/dist/server/blockchain/ZipMetadata.js +131 -0
  47. package/dist/server/blockchain/ZipTokenProcessor.d.ts +44 -0
  48. package/dist/server/blockchain/ZipTokenProcessor.js +204 -0
  49. package/dist/server/blockchain/constants.d.ts +102 -0
  50. package/dist/server/blockchain/constants.js +968 -0
  51. package/dist/server/blockchain/index.d.ts +9 -0
  52. package/dist/server/blockchain/index.js +44 -0
  53. package/dist/server/blockchain/test-certificate.d.ts +8 -0
  54. package/dist/server/blockchain/test-certificate.js +100 -0
  55. package/dist/server/blockchain/types.d.ts +69 -0
  56. package/dist/server/blockchain/types.js +51 -0
  57. package/dist/server/platform/server/ZipKitServer.d.ts +105 -0
  58. package/dist/server/platform/server/ZipKitServer.js +437 -0
  59. package/dist/server/platform/servercomponents/ZipKitOTS.d.ts +91 -0
  60. package/dist/server/platform/servercomponents/ZipKitOTS.js +271 -0
  61. package/dist/shared/ZipEntry.d.ts +131 -0
  62. package/dist/shared/ZipEntry.js +686 -0
  63. package/dist/shared/ZipKit.d.ts +249 -0
  64. package/dist/shared/ZipKit.js +789 -0
  65. package/dist/shared/components/CertificateOTS.d.ts +15 -0
  66. package/dist/shared/components/CertificateOTS.js +116 -0
  67. package/dist/shared/components/FileSys.d.ts +2 -0
  68. package/dist/shared/components/FileSys.js +113 -0
  69. package/dist/shared/components/HashAccumulator.d.ts +55 -0
  70. package/dist/shared/components/HashAccumulator.js +100 -0
  71. package/dist/shared/components/Support.d.ts +63 -0
  72. package/dist/shared/components/Support.js +70 -0
  73. package/dist/shared/components/Util.d.ts +21 -0
  74. package/dist/shared/components/Util.js +115 -0
  75. package/dist/shared/components/ZipCrypto.d.ts +3 -0
  76. package/dist/shared/components/ZipCrypto.js +78 -0
  77. package/dist/shared/components/merkleTree.d.ts +66 -0
  78. package/dist/shared/components/merkleTree.js +136 -0
  79. package/dist/shared/constants/Errors.d.ts +53 -0
  80. package/dist/shared/constants/Errors.js +69 -0
  81. package/dist/shared/constants/Headers.d.ts +167 -0
  82. package/dist/shared/constants/Headers.js +191 -0
  83. package/dist/shared/types/index.d.ts +21 -0
  84. package/dist/shared/types/index.js +3 -0
  85. package/dist/shared/types.d.ts +33 -0
  86. package/dist/shared/types.js +8 -0
  87. package/dist/shared/version.d.ts +4 -0
  88. package/dist/shared/version.js +7 -0
  89. package/dist/types/index.d.ts +21 -0
  90. package/dist/types/index.js +3 -0
  91. package/examples/unzip-token.ts +488 -0
  92. package/examples/zip-token.ts +604 -0
  93. package/package.json +117 -0
  94. package/src/browser/CertificateGeneratorBrowser.ts +498 -0
  95. package/src/browser/TokenVerifierBrowser.ts +344 -0
  96. package/src/browser/ZipKitBrowser.ts +242 -0
  97. package/src/browser/ZipKitStampBrowser.ts +9 -0
  98. package/src/browser-index.ts +36 -0
  99. package/src/index.ts +48 -0
  100. package/src/server/blockchain/CertificateToken.ts +444 -0
  101. package/src/server/blockchain/NFTMinter.ts +357 -0
  102. package/src/server/blockchain/TokenQuerier.ts +287 -0
  103. package/src/server/blockchain/TokenVerifier.ts +453 -0
  104. package/src/server/blockchain/WalletAnalyzer.ts +397 -0
  105. package/src/server/blockchain/WalletFormatter.ts +206 -0
  106. package/src/server/blockchain/WalletManager.ts +294 -0
  107. package/src/server/blockchain/ZipMetadata.ts +117 -0
  108. package/src/server/blockchain/ZipTokenProcessor.ts +234 -0
  109. package/src/server/blockchain/constants.ts +969 -0
  110. package/src/server/blockchain/index.ts +42 -0
  111. package/src/server/blockchain/test-certificate.ts +137 -0
  112. package/src/server/blockchain/types.ts +134 -0
  113. package/src/server/platform/server/ZipKitServer.ts +459 -0
  114. package/src/server/platform/servercomponents/ZipKitOTS.ts +313 -0
  115. package/src/server/platform/servercomponents/opentimestamps.d.ts +23 -0
  116. package/src/shared/ZipEntry.ts +767 -0
  117. package/src/shared/ZipKit.ts +899 -0
  118. package/src/shared/components/CertificateOTS.ts +132 -0
  119. package/src/shared/components/FileSys.ts +87 -0
  120. package/src/shared/components/HashAccumulator.ts +113 -0
  121. package/src/shared/components/Support.ts +77 -0
  122. package/src/shared/components/Util.ts +113 -0
  123. package/src/shared/components/ZipCrypto.ts +91 -0
  124. package/src/shared/components/merkleTree.ts +162 -0
  125. package/src/shared/constants/Errors.ts +82 -0
  126. package/src/shared/constants/Headers.ts +203 -0
  127. package/src/shared/types/index.ts +25 -0
  128. package/src/shared/types/modules.d.ts +22 -0
  129. package/src/shared/types/opentimestamps.d.ts +23 -0
  130. package/src/shared/types.d.ts +8 -0
  131. package/src/shared/types.ts +43 -0
  132. package/src/shared/version.ts +4 -0
  133. package/src/types/index.ts +25 -0
  134. package/src/types/modules.d.ts +22 -0
  135. package/src/types/opentimestamps.d.ts +23 -0
@@ -0,0 +1,132 @@
1
+ // ======================================
2
+ // CertificateOTS.ts
3
+ // Copyright (c) 2025 NeoWare, Inc. All rights reserved.
4
+ // ======================================
5
+
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ import ZipEntry from '../ZipEntry';
9
+
10
+ import {
11
+ TIMESTAMP_SUBMITTED,
12
+ TIMESTAMP_METADATA,
13
+ } from '../constants/Headers';
14
+
15
+ // Add this at the top of the file
16
+ import type { AttestationValue } from '../types';
17
+
18
+ /**
19
+ * Generates a certificate HTML document based on timestamp information
20
+ *
21
+ * @param attestStr - Attestation message
22
+ * @param zipFile - Name of the zip file
23
+ * @param hashDigest - Hash digest of the zip file
24
+ * @param needsUpdateMsg - Message indicating if update is needed
25
+ * @param attestationValues - Array of attestation values
26
+ * @param zipEntries - Array of ZipEntry objects
27
+ * @param narrow - Whether to use narrow layout
28
+ * @returns Generated HTML certificate as string
29
+ */
30
+ export default function CertificateTemplate(
31
+ attestStr: string | null,
32
+ zipFile: string,
33
+ hashDigest: string,
34
+ needsUpdateMsg: string,
35
+ attestationValues: AttestationValue[],
36
+ zipEntries: ZipEntry[],
37
+ narrow?: boolean
38
+ ): string {
39
+ // Load the HTML template
40
+ let templatePath;
41
+ try {
42
+ // Try to find the template from the package root
43
+ templatePath = path.resolve(process.cwd(), 'assets/templates/certificate.html');
44
+ if (!fs.existsSync(templatePath)) {
45
+ // If not found in current working directory, try relative to this file
46
+ templatePath = path.resolve(__dirname, '../../assets/templates/certificate.html');
47
+ }
48
+
49
+ if (!fs.existsSync(templatePath)) {
50
+ throw new Error('Certificate template not found');
51
+ }
52
+ } catch (error) {
53
+ console.error('Error resolving template path:', error);
54
+ return '';
55
+ }
56
+
57
+ // Read the template file
58
+ let htmlTemplate;
59
+ try {
60
+ htmlTemplate = fs.readFileSync(templatePath, 'utf8');
61
+ } catch (error) {
62
+ console.error('Error reading template file:', error);
63
+ return '';
64
+ }
65
+
66
+ const updateWarning = needsUpdateMsg || '';
67
+
68
+ // Generate attestation HTML
69
+ let attestHTML = '';
70
+ if (attestationValues && attestationValues.length > 0) {
71
+ attestationValues.forEach((attest) => {
72
+ attestHTML += `
73
+ <div class="key-value-pair">
74
+ <div class="key">Block Height:</div>
75
+ <div class="value">${attest['blockHeight']}</div>
76
+ </div>
77
+ <div class="key-value-pair">
78
+ <div class="key">Transaction:</div>
79
+ <div class="value">${attest['transactionId']}</div>
80
+ </div>
81
+ <div class="key-value-pair">
82
+ <div class="key">Merkle Root:</div>
83
+ <div class="value">${attest['merkleRoot']}</div>
84
+ </div>
85
+ <br/>
86
+ `;
87
+ });
88
+ }
89
+
90
+ // Generate files table HTML
91
+ let stampEntry = null;
92
+ let files = [];
93
+ for (const entry of zipEntries) {
94
+ if (entry.filename === TIMESTAMP_METADATA) {
95
+ stampEntry = entry;
96
+ } else if (entry.filename === TIMESTAMP_SUBMITTED) {
97
+ if (stampEntry == null)
98
+ stampEntry = entry;
99
+ } else if (entry.sha256) {
100
+ let file = {
101
+ name: entry.filename,
102
+ size: entry.uncompressedSize.toString(),
103
+ date: entry.toFormattedUTCDateString(),
104
+ hash: entry.sha256,
105
+ }
106
+ files.push(file);
107
+ }
108
+ }
109
+
110
+ let filesTableHTML = '';
111
+ files.forEach((file) => {
112
+ filesTableHTML += `
113
+ <tr>
114
+ <td class="table-data1">${file.name}</td>
115
+ <td class="table-data">${file.size}</td>
116
+ <td class="table-data">${file.date}</td>
117
+ <td class="table-data">${file.hash}</td>
118
+ </tr>
119
+ `;
120
+ });
121
+
122
+ // Replace placeholders in the template
123
+ let html = htmlTemplate
124
+ .replace(/{{ATTEST_STR}}/g, attestStr || '')
125
+ .replace(/{{UPDATE_WARNING}}/g, needsUpdateMsg ? `<div class="warning">${needsUpdateMsg}</div>` : '')
126
+ .replace(/{{ZIP_FILE}}/g, zipFile)
127
+ .replace(/{{HASH_DIGEST}}/g, hashDigest)
128
+ .replace(/{{ATTESTATION_HTML}}/g, attestHTML)
129
+ .replace(/{{FILES_TABLE_HTML}}/g, filesTableHTML);
130
+
131
+ return html;
132
+ }
@@ -0,0 +1,87 @@
1
+ // ======================================
2
+ // FileSys.ts
3
+ // Copyright (c) 2024 NeoWare, Inc. All rights reserved.
4
+ // ======================================
5
+
6
+ import * as fs from 'fs';
7
+ import * as pth from 'path';
8
+
9
+ import Errors from '../constants/Errors';
10
+
11
+ // Output a buffer to a file
12
+ export function outputToFile(
13
+ fileName: string,
14
+ buffer: Buffer,
15
+ dirPath: string,
16
+ overwrite: boolean,
17
+ never: boolean,
18
+ fileAttr: number)
19
+ {
20
+ // get Unix file permissions
21
+ const _fattr = fileAttr ? (((fileAttr >>> 0) | 0) >> 16) & 0xfff : 0;
22
+
23
+ const _path = dirPath ? dirPath + pth.sep + fileName : fileName;
24
+
25
+ if (fs.existsSync(_path)) {
26
+ console.log('File exists: ', _path);
27
+ if (never)
28
+ return false;
29
+ if (!overwrite) {
30
+ console.log('Overwrite file: ', _path);
31
+ return false; // cannot overwrite
32
+ }
33
+
34
+ const stat = fs.statSync(_path);
35
+ if (stat.isDirectory())
36
+ return false;
37
+ }
38
+
39
+ // Check if we need to create a new folder
40
+ const _folder = pth.dirname(_path);
41
+ if (!fs.existsSync(_folder)) {
42
+ makeDir(_folder);
43
+ }
44
+
45
+ var fd;
46
+ try {
47
+ fd = fs.openSync(_path, "w", 438); // 0666
48
+ } catch (e) {
49
+ fs.chmodSync(_path, 438);
50
+ fd = fs.openSync(_path, "w", 438);
51
+ }
52
+ if (fd) {
53
+ try {
54
+ fs.writeSync(fd, buffer, 0, buffer.length, 0);
55
+ } finally {
56
+ fs.closeSync(fd);
57
+ }
58
+ }
59
+
60
+ if (_fattr)
61
+ fs.chmodSync(_path, _fattr);
62
+
63
+ return true;
64
+ }
65
+
66
+ // Make directories tree for a given path
67
+ export function makeDir(folder: string) {
68
+ console.log('mkDir: ', folder);
69
+
70
+ // Sync - make directories tree
71
+ function mkdirSync(fpath: string) {
72
+ let resolvedPath = fpath.split(pth.sep)[0];
73
+ fpath.split(pth.sep).forEach(function (name) {
74
+ if (!name || name.endsWith(":")) return;
75
+ resolvedPath += pth.sep + name;
76
+ var stat;
77
+ try {
78
+ stat = fs.statSync(resolvedPath);
79
+ } catch (e) {
80
+ fs.mkdirSync(resolvedPath);
81
+ }
82
+ if (stat && stat.isFile()) throw Errors.FILE_IN_THE_WAY.replace("%s", resolvedPath);
83
+ });
84
+ }
85
+
86
+ mkdirSync(folder);
87
+ };
@@ -0,0 +1,113 @@
1
+ // ======================================
2
+ // HashAccumulator.ts
3
+ // ======================================
4
+
5
+ import { MerkleTree } from './merkleTree';
6
+
7
+ /**
8
+ * Class for accumulating and combining SHA-256 hashes using both XOR and Merkle tree methods
9
+ *
10
+ * Usage example:
11
+ * ```typescript
12
+ * const accumulator = new HashAccumulator();
13
+ * accumulator.addHash('a1b2c3d4');
14
+ * accumulator.addHash('12345678');
15
+ * console.log(accumulator.xorHash()); // Outputs the accumulated XOR result
16
+ * console.log(accumulator.merkleRoot()); // Outputs the accumulated Merkle root
17
+ * ```
18
+ */
19
+ export default class HashAccumulator {
20
+ private hashes: Buffer[]; // Array of hash buffers for Merkle tree
21
+ private xorResult: Buffer; // Running XOR of all hashes
22
+
23
+ /**
24
+ * Creates a new HashAccumulator instance
25
+ * Initializes empty hash array and zero-filled XOR buffer
26
+ */
27
+ constructor() {
28
+ this.hashes = [];
29
+ this.xorResult = Buffer.alloc(32, 0);
30
+ }
31
+
32
+ /**
33
+ * Adds a hash to both the XOR accumulation and hash array
34
+ * @param hash - Hash value as hex string or Buffer
35
+ * The hash must be 32 bytes (SHA-256)
36
+ */
37
+ addHash(hash: string | Buffer) {
38
+ // Convert hash to Buffer if it's a string
39
+ const hashBuffer = typeof hash === 'string'
40
+ ? Buffer.from(hash, 'hex')
41
+ : hash;
42
+
43
+ // Add to array for Merkle tree
44
+ this.hashes.push(hashBuffer);
45
+
46
+ // XOR accumulation
47
+ for (let i = 0; i < 32; i++) {
48
+ this.xorResult[i] ^= hashBuffer[i];
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Gets the accumulated XOR of all added hashes
54
+ * @returns Hex string of XOR result
55
+ */
56
+ xorHash(): string {
57
+ return this.xorResult.toString('hex');
58
+ }
59
+
60
+ /**
61
+ * Creates a Merkle tree from accumulated hashes and returns the root
62
+ * @returns Hex string of Merkle root, or null if no hashes added
63
+ */
64
+ merkleRoot(): string | null {
65
+ let merkleRoot = null;
66
+ if (this.hashes.length > 0) {
67
+ const tree = new MerkleTree(this.hashes, {
68
+ hashLeaves: false, // Leaves are already hashed
69
+ sortLeaves: true, // Sort leaves for consistent results
70
+ sortPairs: true, // Sort pairs for consistent results
71
+ duplicateOdd: true // Duplicate odd leaf for balanced tree
72
+ });
73
+ merkleRoot = tree.getRoot().toString('hex');
74
+ }
75
+
76
+ return merkleRoot;
77
+ }
78
+
79
+ /**
80
+ * Gets the number of hashes accumulated
81
+ * @returns Number of accumulated hashes
82
+ */
83
+ leafCount(): number {
84
+ return this.hashes.length;
85
+ }
86
+
87
+ /**
88
+ * Resets the accumulator to initial state
89
+ * Clears hash array and zeroes XOR buffer
90
+ */
91
+ clear() {
92
+ this.hashes = [];
93
+ this.xorResult = Buffer.alloc(32, 0);
94
+ }
95
+
96
+ /**
97
+ * Combines multiple hash results into a single Merkle root
98
+ * @param results - Array of objects containing merkleRoot properties
99
+ * @returns Combined Merkle root as hex string, or null if no valid roots
100
+ */
101
+ static combineResults(results: { merkleRoot?: string }[]) {
102
+ const accumulator = new HashAccumulator();
103
+
104
+ // Combine all hashes
105
+ for (const result of results) {
106
+ if (result.merkleRoot) {
107
+ accumulator.addHash(result.merkleRoot);
108
+ }
109
+ }
110
+
111
+ return accumulator.merkleRoot();
112
+ }
113
+ }
@@ -0,0 +1,77 @@
1
+ // ======================================
2
+ // Support.ts
3
+ // A utility module for detecting platform capabilities and features
4
+ // Copyright (c) 2024 NeoWare, Inc. All rights reserved.
5
+ // ======================================
6
+
7
+ /**
8
+ * Platform and environment feature detection utility
9
+ * Provides boolean flags indicating support for various features needed by NeoZip
10
+ *
11
+ * @namespace Support
12
+ * @property {boolean} base64 - Always true, indicates base64 encoding support
13
+ * @property {boolean} array - Always true, indicates Array support
14
+ * @property {boolean} string - Always true, indicates String support
15
+ * @property {boolean} isNode - True if running in Node.js environment
16
+ * @property {boolean} buffer - True if Node.js Buffer is available
17
+ * @property {boolean} uint8array - True if Uint8Array is supported
18
+ * @property {boolean} arrayBuffer - True if both ArrayBuffer and Uint8Array are supported
19
+ * @property {boolean} blob - True if Blob creation with ArrayBuffer is supported
20
+ * @property {boolean} streams - True if ReadableStream and WritableStream are supported
21
+ * @property {boolean} fileReader - True if FileReader is supported
22
+ */
23
+ const Support = {
24
+ /** Base64 encoding support (always true) */
25
+ base64: true,
26
+ /** Array support (always true) */
27
+ array: true,
28
+ /** String support (always true) */
29
+ string: true,
30
+
31
+ /**
32
+ * Detects if code is running in Node.js environment
33
+ * True if process.versions.node exists, undefined in browser
34
+ */
35
+ isNode: true,
36
+
37
+ /**
38
+ * Detects if Node.js Buffer is available
39
+ * True in Node.js, undefined in browser
40
+ */
41
+ buffer: true,
42
+
43
+ /**
44
+ * Detects support for Uint8Array typed array
45
+ * Used for binary data handling
46
+ */
47
+ uint8array: true,
48
+
49
+ /**
50
+ * Detects support for both ArrayBuffer and Uint8Array
51
+ * Required for binary data operations
52
+ */
53
+ arrayBuffer: typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined",
54
+
55
+ /**
56
+ * Detects support for Blob with ArrayBuffer
57
+ * Tests by attempting to create an empty ZIP Blob
58
+ * @returns {boolean} True if Blob creation succeeds
59
+ */
60
+ blob: true,
61
+
62
+ /**
63
+ * Detects support for Streams API
64
+ * Checks for ReadableStream/WritableStream in browser
65
+ * or 'stream' module in Node.js
66
+ * @returns {boolean} True if streams are supported in current environment
67
+ */
68
+ streams: true,
69
+
70
+ /**
71
+ * Detects support for FileReader
72
+ * @returns {boolean} True if FileReader is supported
73
+ */
74
+ fileReader: false
75
+ };
76
+
77
+ export default Support;
@@ -0,0 +1,113 @@
1
+ // ======================================
2
+ // Util.ts
3
+ // Copyright (c) 2024 NeoWare, Inc. All rights reserved.
4
+ // ======================================
5
+ // Utility functions
6
+
7
+ import Support from "./Support";
8
+ import Errors from "../constants/Errors";
9
+
10
+ export const DATATYPE = {
11
+ STRING: "string",
12
+ BUFFER: "buffer",
13
+ ARRAY: "array",
14
+ ARRAYBUFFER: "arraybuffer",
15
+ U8ARRAY: "uint8array",
16
+ BLOB: "blob",
17
+ STREAM: "stream",
18
+ };
19
+
20
+ // Generate the CRC32 table
21
+ const crcTable = new Uint32Array(256).map((t, crc) => {
22
+ for (let j = 0; j < 8; j++) {
23
+ if (0 !== (crc & 1)) {
24
+ crc = (crc >>> 1) ^ 0xedb88320;
25
+ } else {
26
+ crc >>>= 1;
27
+ }
28
+ }
29
+ return crc >>> 0;
30
+ });
31
+
32
+ // crc32 byte single update (actually same function is part of utils.crc32 function :) )
33
+ export const crc32update = (pCrc32: number, bval: number) => {
34
+ return crcTable[(pCrc32 ^ bval) & 0xff] ^ (pCrc32 >>> 8);
35
+ };
36
+
37
+ // Return the CRC32 of a buffer
38
+ export function crc32(buf: Buffer): number {
39
+ if (typeof buf === "string") {
40
+ buf = Buffer.from(buf, "utf8");
41
+ }
42
+ // Generate crcTable
43
+ // if (!crcTable.length) genCRCTable();
44
+
45
+ let len = buf.length;
46
+ let crc = ~0;
47
+ for (let off = 0; off < len; )
48
+ crc = crcTable[(crc ^ buf[off++]) & 0xff] ^ (crc >>> 8);
49
+
50
+ // xor and cast as uint32 number
51
+ return ~crc >>> 0;
52
+ };
53
+
54
+ // Parse a 64-bit unsigned integer from a buffer
55
+ export function readBigUInt64LE(buffer: Buffer, index: number): number {
56
+ var buf = Buffer.from(buffer.subarray(index, index + 8));
57
+ buf.swap64();
58
+
59
+ return parseInt(`0x${buf.toString("hex")}`);
60
+ };
61
+
62
+ // C-style uInt32 Multiply (discards higher bits, when JS multiply discards lower bits)
63
+ export const uMul = (a: number, b: number) => Math.imul(a, b) >>> 0;
64
+
65
+ interface StreamLike {
66
+ on: Function;
67
+ pause: Function;
68
+ resume: Function;
69
+ }
70
+
71
+ export function isStream(obj: unknown): obj is StreamLike {
72
+ if (!obj || typeof obj !== 'object') return false;
73
+ const streamLike = obj as StreamLike;
74
+ return typeof streamLike.on === "function" &&
75
+ typeof streamLike.pause === "function" &&
76
+ typeof streamLike.resume === "function";
77
+ }
78
+
79
+ // Return the type of the input.
80
+ // The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer.
81
+ // If the type is not supported, throw an exception.
82
+ export function getTypeOf(input: string|Buffer|Blob|Array<any>|ArrayBuffer|Uint8Array): string {
83
+ if (typeof input === "string") {
84
+ if (!Support.string)
85
+ throw new Error(Errors.DATATYPE_STRING_UNSUPPORTED);
86
+ return DATATYPE.STRING;
87
+ }
88
+ else if (Object.prototype.toString.call(input) === "[object Array]") {
89
+ if (!Support.array)
90
+ throw new Error(Errors.DATATYPE_ARRAY_UNSUPPORTED);
91
+ return DATATYPE.ARRAY;
92
+ }
93
+ else if (Buffer.isBuffer(input)) {
94
+ if (!Support.buffer)
95
+ throw new Error(Errors.DATATYPE_BUFFER_UNSUPPORTED);
96
+ return DATATYPE.BUFFER;
97
+ } else if (input instanceof Blob) {
98
+ if (!Support.blob)
99
+ throw new Error(Errors.DATATYPE_BLOB_UNSUPPORTED);
100
+ return DATATYPE.BLOB;
101
+ } else if (input instanceof Uint8Array) {
102
+ if (!Support.uint8array)
103
+ throw new Error(Errors.DATATYPE_U8ARRAY_UNSUPPORTED);
104
+ return DATATYPE.U8ARRAY;
105
+ }
106
+ else if (input instanceof ArrayBuffer) {
107
+ if (!Support.arrayBuffer)
108
+ throw new Error(Errors.DATATYPE_ARRAYBUFFER_UNSUPPORTED);
109
+ return DATATYPE.ARRAYBUFFER;
110
+ } else { // Add an else block to handle unsupported types
111
+ throw new Error(Errors.DATATYPE_UNSUPPORTED);
112
+ }
113
+ };
@@ -0,0 +1,91 @@
1
+ // ======================================
2
+ // ZipCrypto.ts
3
+ // Copyright (c) 2024 NeoWare, Inc. All rights reserved.
4
+ // ======================================
5
+ // Zip Cryptography Routines
6
+
7
+ "use strict";
8
+
9
+ import { createHash, randomFillSync } from 'crypto';
10
+
11
+ import { crc32update, uMul } from './Util';
12
+ import { ENCRYPT_HDR_SIZE } from '../constants/Headers';
13
+
14
+ // Return the SHA256 hash of a buffer
15
+ export function sha256(data: Buffer): string {
16
+ const hash = createHash('sha256');
17
+
18
+ return hash
19
+ .update(data)
20
+ .digest('hex');
21
+ }
22
+
23
+ class InitKeys {
24
+ private keys: Uint32Array;
25
+
26
+ constructor(pw: string | Buffer) {
27
+ this.keys = new Uint32Array([0x12345678, 0x23456789, 0x34567890]);
28
+ const pass = typeof pw === 'string' ? Buffer.from(pw) : pw;
29
+ for (let i = 0; i < pass.length; i++) {
30
+ this.updateKeys(pass[i]);
31
+ }
32
+ }
33
+
34
+ updateKeys(byteValue: number): number {
35
+ this.keys[0] = crc32update(this.keys[0], byteValue);
36
+ this.keys[1] = ((this.keys[1] + (this.keys[0] & 0xff)) * 0x08088405 + 1) >>> 0;
37
+ this.keys[2] = crc32update(this.keys[2], this.keys[1] >>> 24);
38
+ return byteValue;
39
+ }
40
+
41
+ next(): number {
42
+ const k = (this.keys[2] | 2) >>> 0; // key
43
+ return (uMul(k, k ^ 1) >> 8) & 0xff; // decode
44
+ }
45
+ }
46
+
47
+ // Return encrypting function, result and pos is here so we dont have to merge buffers later
48
+ function make_encrypter(pwd: string | Buffer): Function {
49
+ const keys = new InitKeys(pwd);
50
+
51
+ return function (data: Buffer, result: Buffer, pos: number = 0): Buffer {
52
+ // result - we create new Buffer for results
53
+ if (!result) result = Buffer.alloc(data.length);
54
+ // process input data
55
+ for (let c of data) {
56
+ const k = keys.next(); // save key byte
57
+ result[pos++] = c ^ k; // save val
58
+ keys.updateKeys(c); // update keys with decoded byte
59
+ }
60
+ return result;
61
+ };
62
+ }
63
+
64
+ // Encrypt data with password and include a checkByte verification byte at the end
65
+ export function encrypter(data: Buffer | null, checkByte: number, pwd: string): Buffer | null {
66
+ if (!data) return null;
67
+
68
+ const _encrypter = make_encrypter(pwd);
69
+
70
+ const salt = randomFillSync(Buffer.alloc(ENCRYPT_HDR_SIZE));
71
+ salt[ENCRYPT_HDR_SIZE - 1] = checkByte;
72
+
73
+ // create encryption header
74
+ const result = Buffer.alloc(data.length + ENCRYPT_HDR_SIZE);
75
+ _encrypter(salt, result);
76
+
77
+ // encode content
78
+ return _encrypter(data, result, ENCRYPT_HDR_SIZE);
79
+ }
80
+
81
+ // Return the decrypter function
82
+ export function decrypter(pwd: string | Buffer): Function {
83
+ const keys = new InitKeys(pwd);
84
+
85
+ return function (data: Buffer): Buffer {
86
+ for (let i=0; i<data.length; i++) {
87
+ data[i] = keys.updateKeys(data[i] ^ keys.next());
88
+ }
89
+ return data;
90
+ };
91
+ }