@aleph-ai/tinyaleph 1.5.7 → 1.6.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.
- package/core/alexander-module.js +1469 -0
- package/core/arithmetic-link-kernel.js +1338 -0
- package/core/emotion.js +565 -0
- package/core/gravity.js +714 -0
- package/core/hilbert.js +506 -3
- package/core/index.js +132 -4
- package/core/nonlocal.js +744 -0
- package/core/oracle.js +662 -0
- package/examples/01-hello-world.js +69 -0
- package/examples/02-basic-hash.js +90 -0
- package/examples/02-observer-stack.js +385 -0
- package/examples/03-quantum-coin.js +136 -0
- package/examples/05-symbolic-resonance.js +146 -0
- package/examples/06-symbol-database.js +150 -0
- package/examples/07-semantic-inference.js +223 -0
- package/examples/08-compound-symbols.js +219 -0
- package/examples/README.md +170 -0
- package/examples/ai/01-embeddings.js +155 -0
- package/examples/ai/02-semantic-memory.js +243 -0
- package/examples/ai/03-reasoning.js +243 -0
- package/examples/ai/04-knowledge-graph.js +279 -0
- package/examples/ai/05-llm-integration.js +333 -0
- package/examples/ai/06-agent.js +294 -0
- package/examples/ai/07-hybrid-ai.js +223 -0
- package/examples/ai/08-entropy-reasoning.js +259 -0
- package/examples/ai/09-concept-learning.js +271 -0
- package/examples/ai/10-prompt-primes.js +312 -0
- package/examples/ai/11-rag.js +332 -0
- package/examples/ai/12-neuro-symbolic.js +321 -0
- package/examples/ai/README.md +80 -0
- package/examples/arithmetic-topology/01-legendre-symbol.js +78 -0
- package/examples/arithmetic-topology/02-redei-symbol.js +126 -0
- package/examples/arithmetic-topology/03-alk-kuramoto.js +138 -0
- package/examples/arithmetic-topology/04-alexander-module.js +117 -0
- package/examples/arithmetic-topology/05-signature-memory.js +118 -0
- package/examples/arithmetic-topology/README.md +291 -0
- package/examples/bioinformatics/01-dna-encoding.js +108 -0
- package/examples/bioinformatics/02-central-dogma.js +162 -0
- package/examples/bioinformatics/03-protein-folding.js +206 -0
- package/examples/bioinformatics/04-dna-computing.js +192 -0
- package/examples/bioinformatics/05-molecular-binding.js +209 -0
- package/examples/book-operators-demo.js +155 -0
- package/examples/chat.js +105 -0
- package/examples/crt-homology/01-residue-encoding.js +87 -0
- package/examples/crt-homology/02-birkhoff-attention.js +100 -0
- package/examples/crt-homology/03-homology-loss.js +132 -0
- package/examples/crt-homology/04-crt-resoformer.js +132 -0
- package/examples/crt-homology/README.md +67 -0
- package/examples/crypto/01-password-hash.js +210 -0
- package/examples/crypto/02-key-derivation.js +210 -0
- package/examples/crypto/03-hmac.js +229 -0
- package/examples/crypto/04-file-integrity.js +263 -0
- package/examples/crypto/05-content-hash.js +263 -0
- package/examples/crypto/README.md +99 -0
- package/examples/demo-modular.js +223 -0
- package/examples/demo-two-layer.js +196 -0
- package/examples/discrete/01-integer-sine-table.js +120 -0
- package/examples/discrete/02-codebook-tunneling.js +118 -0
- package/examples/discrete/03-canonical-fusion.js +135 -0
- package/examples/discrete/04-tick-gate.js +139 -0
- package/examples/discrete/README.md +142 -0
- package/examples/emotion-demo.js +200 -0
- package/examples/formal-semantics/01-typed-terms.js +156 -0
- package/examples/formal-semantics/02-reduction.js +202 -0
- package/examples/formal-semantics/03-lambda-translation.js +206 -0
- package/examples/formal-semantics/04-enochian-language.js +257 -0
- package/examples/formal-semantics/README.md +98 -0
- package/examples/gravity-demo.js +190 -0
- package/examples/math/01-quaternions.js +237 -0
- package/examples/math/02-octonions.js +192 -0
- package/examples/math/03-prime-factorization.js +215 -0
- package/examples/math/04-vector-spaces.js +210 -0
- package/examples/math/05-gaussian-primes.js +234 -0
- package/examples/math/README.md +93 -0
- package/examples/nonlocal-demo.js +237 -0
- package/examples/oracle-demo.js +204 -0
- package/examples/physics/01-oscillator.js +177 -0
- package/examples/physics/02-lyapunov.js +201 -0
- package/examples/physics/03-collapse.js +183 -0
- package/examples/physics/04-kuramoto.js +212 -0
- package/examples/physics/05-entropy.js +226 -0
- package/examples/physics/05-sync-models.js +298 -0
- package/examples/physics/06-primeon-ladder.js +233 -0
- package/examples/physics/07-kuramoto-coupled-ladder.js +298 -0
- package/examples/physics/README.md +126 -0
- package/examples/quantum/01-prime-hunter.js +79 -0
- package/examples/quantum/02-entanglement-demo.js +79 -0
- package/examples/quantum/03-wave-analysis.js +63 -0
- package/examples/resonance/01-prime-hilbert-space.js +140 -0
- package/examples/resonance/02-prime-resonance-network.js +221 -0
- package/examples/resonance/03-resoformer.js +349 -0
- package/examples/resonance/04-resoformer-training.js +329 -0
- package/examples/resonance/05-language-model.js +484 -0
- package/examples/resonance/README.md +238 -0
- package/examples/run-examples.js +427 -0
- package/examples/scientific/01-single-qubit.js +185 -0
- package/examples/scientific/02-two-qubit.js +209 -0
- package/examples/scientific/03-quantum-circuits.js +270 -0
- package/examples/scientific/04-measurement.js +229 -0
- package/examples/scientific/05-algorithms.js +245 -0
- package/examples/scientific/06-random.js +225 -0
- package/examples/scientific/07-wavefunction.js +192 -0
- package/examples/scientific/README.md +118 -0
- package/examples/semantic/01-vocabulary.js +186 -0
- package/examples/semantic/02-similarity.js +263 -0
- package/examples/semantic/03-word-algebra.js +295 -0
- package/examples/semantic/04-clustering.js +348 -0
- package/examples/semantic/05-classification.js +386 -0
- package/examples/semantic/06-dna-encoding.js +228 -0
- package/examples/semantic/07-search.js +304 -0
- package/examples/semantic/08-qa-system.js +278 -0
- package/examples/semantic/README.md +116 -0
- package/examples/topology/01-108-invariant.js +81 -0
- package/examples/topology/02-trefoil-constants.js +112 -0
- package/examples/topology/03-gauge-symmetry.js +112 -0
- package/examples/topology/04-free-energy-dynamics.js +124 -0
- package/examples/topology/README.md +129 -0
- package/index.js +32 -0
- package/modular.js +63 -2
- package/package.json +8 -3
- package/physics/alk-kuramoto.js +817 -0
- package/physics/index.js +23 -2
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @example Key Derivation
|
|
3
|
+
* @description Derive cryptographic keys from passwords using TinyAleph
|
|
4
|
+
*
|
|
5
|
+
* Key derivation functions (KDFs) create strong cryptographic keys from
|
|
6
|
+
* potentially weak passwords. TinyAleph's deriveKey function:
|
|
7
|
+
* - Uses salt to prevent rainbow table attacks
|
|
8
|
+
* - Supports configurable iterations for work factor
|
|
9
|
+
* - Produces keys of specified length
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const { CryptographicBackend } = require('../../modular');
|
|
13
|
+
|
|
14
|
+
// ===========================================
|
|
15
|
+
// SETUP
|
|
16
|
+
// ===========================================
|
|
17
|
+
|
|
18
|
+
const backend = new CryptographicBackend({ dimension: 32 });
|
|
19
|
+
|
|
20
|
+
console.log('TinyAleph Key Derivation Example');
|
|
21
|
+
console.log('=================================\n');
|
|
22
|
+
|
|
23
|
+
// ===========================================
|
|
24
|
+
// BASIC KEY DERIVATION
|
|
25
|
+
// ===========================================
|
|
26
|
+
|
|
27
|
+
console.log('Basic Key Derivation:');
|
|
28
|
+
console.log('-'.repeat(50) + '\n');
|
|
29
|
+
|
|
30
|
+
var password = 'MySecretPassword123';
|
|
31
|
+
var salt = 'randomsalt12345678';
|
|
32
|
+
var keyLength = 32;
|
|
33
|
+
var iterations = 1000;
|
|
34
|
+
|
|
35
|
+
console.log('Input:');
|
|
36
|
+
console.log(' Password: ' + password);
|
|
37
|
+
console.log(' Salt: ' + salt);
|
|
38
|
+
console.log(' Key Length: ' + keyLength + ' bytes');
|
|
39
|
+
console.log(' Iterations: ' + iterations);
|
|
40
|
+
|
|
41
|
+
var derivedKey = backend.deriveKey(password, salt, keyLength, iterations);
|
|
42
|
+
console.log('\nDerived Key (hex): ' + derivedKey.toString('hex'));
|
|
43
|
+
|
|
44
|
+
// ===========================================
|
|
45
|
+
// SALT IMPORTANCE
|
|
46
|
+
// ===========================================
|
|
47
|
+
|
|
48
|
+
console.log('\n' + '='.repeat(50));
|
|
49
|
+
console.log('Salt Importance:');
|
|
50
|
+
console.log('='.repeat(50) + '\n');
|
|
51
|
+
|
|
52
|
+
console.log('Same password with different salts produces different keys:\n');
|
|
53
|
+
|
|
54
|
+
var salts = ['salt_user_1', 'salt_user_2', 'salt_user_3'];
|
|
55
|
+
|
|
56
|
+
for (var i = 0; i < salts.length; i++) {
|
|
57
|
+
var s = salts[i];
|
|
58
|
+
var key = backend.deriveKey(password, s, 32, 1000);
|
|
59
|
+
console.log(' Salt: "' + s + '"');
|
|
60
|
+
console.log(' Key: ' + key.toString('hex').substring(0, 40) + '...\n');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ===========================================
|
|
64
|
+
// ITERATION COUNT
|
|
65
|
+
// ===========================================
|
|
66
|
+
|
|
67
|
+
console.log('='.repeat(50));
|
|
68
|
+
console.log('Iteration Count (Work Factor):');
|
|
69
|
+
console.log('='.repeat(50) + '\n');
|
|
70
|
+
|
|
71
|
+
console.log('Higher iterations = more secure but slower:\n');
|
|
72
|
+
|
|
73
|
+
var iterCounts = [100, 1000, 10000];
|
|
74
|
+
|
|
75
|
+
for (var i = 0; i < iterCounts.length; i++) {
|
|
76
|
+
var count = iterCounts[i];
|
|
77
|
+
var start = Date.now();
|
|
78
|
+
var key = backend.deriveKey(password, salt, 32, count);
|
|
79
|
+
var elapsed = Date.now() - start;
|
|
80
|
+
|
|
81
|
+
console.log(' Iterations: ' + count);
|
|
82
|
+
console.log(' Time: ' + elapsed + 'ms');
|
|
83
|
+
console.log(' Key: ' + key.toString('hex').substring(0, 32) + '...\n');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ===========================================
|
|
87
|
+
// KEY LENGTH VARIATIONS
|
|
88
|
+
// ===========================================
|
|
89
|
+
|
|
90
|
+
console.log('='.repeat(50));
|
|
91
|
+
console.log('Variable Key Lengths:');
|
|
92
|
+
console.log('='.repeat(50) + '\n');
|
|
93
|
+
|
|
94
|
+
console.log('Derive keys of different lengths for different purposes:\n');
|
|
95
|
+
|
|
96
|
+
var keyPurposes = [
|
|
97
|
+
{ name: 'AES-128', length: 16 },
|
|
98
|
+
{ name: 'AES-256', length: 32 },
|
|
99
|
+
{ name: 'HMAC-SHA256', length: 32 },
|
|
100
|
+
{ name: 'ChaCha20', length: 32 }
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
for (var i = 0; i < keyPurposes.length; i++) {
|
|
104
|
+
var purpose = keyPurposes[i];
|
|
105
|
+
var key = backend.deriveKey(password, salt, purpose.length, 1000);
|
|
106
|
+
console.log(' ' + purpose.name + ' (' + purpose.length + ' bytes):');
|
|
107
|
+
console.log(' ' + key.toString('hex'));
|
|
108
|
+
console.log('');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ===========================================
|
|
112
|
+
// MULTIPLE KEYS FROM ONE PASSWORD
|
|
113
|
+
// ===========================================
|
|
114
|
+
|
|
115
|
+
console.log('='.repeat(50));
|
|
116
|
+
console.log('Deriving Multiple Keys:');
|
|
117
|
+
console.log('='.repeat(50) + '\n');
|
|
118
|
+
|
|
119
|
+
console.log('Use different salts or purposes to derive multiple keys:\n');
|
|
120
|
+
|
|
121
|
+
function deriveMultipleKeys(password, masterSalt, keySpecs) {
|
|
122
|
+
var keys = {};
|
|
123
|
+
for (var i = 0; i < keySpecs.length; i++) {
|
|
124
|
+
var spec = keySpecs[i];
|
|
125
|
+
var specificSalt = masterSalt + ':' + spec.purpose;
|
|
126
|
+
keys[spec.purpose] = backend.deriveKey(password, specificSalt, spec.length, 1000);
|
|
127
|
+
}
|
|
128
|
+
return keys;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
var keySpecs = [
|
|
132
|
+
{ purpose: 'encryption', length: 32 },
|
|
133
|
+
{ purpose: 'authentication', length: 32 },
|
|
134
|
+
{ purpose: 'signing', length: 64 }
|
|
135
|
+
];
|
|
136
|
+
|
|
137
|
+
var keys = deriveMultipleKeys(password, 'master_salt', keySpecs);
|
|
138
|
+
|
|
139
|
+
for (var purpose in keys) {
|
|
140
|
+
if (keys.hasOwnProperty(purpose)) {
|
|
141
|
+
console.log(' ' + purpose + ': ' + keys[purpose].toString('hex').substring(0, 40) + '...');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ===========================================
|
|
146
|
+
// PASSWORD STRENGTH
|
|
147
|
+
// ===========================================
|
|
148
|
+
|
|
149
|
+
console.log('\n' + '='.repeat(50));
|
|
150
|
+
console.log('Password Strength Consideration:');
|
|
151
|
+
console.log('='.repeat(50) + '\n');
|
|
152
|
+
|
|
153
|
+
console.log('Even with KDF, use strong passwords:\n');
|
|
154
|
+
|
|
155
|
+
var testPasswords = [
|
|
156
|
+
{ pwd: '123456', strength: 'Very Weak' },
|
|
157
|
+
{ pwd: 'password', strength: 'Weak' },
|
|
158
|
+
{ pwd: 'MyP@ss!', strength: 'Medium' },
|
|
159
|
+
{ pwd: 'Tr0ub4dor&3', strength: 'Strong' },
|
|
160
|
+
{ pwd: 'correct-horse-battery-staple', strength: 'Very Strong' }
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
for (var i = 0; i < testPasswords.length; i++) {
|
|
164
|
+
var test = testPasswords[i];
|
|
165
|
+
var key = backend.deriveKey(test.pwd, salt, 32, 1000);
|
|
166
|
+
console.log(' "' + test.pwd + '" (' + test.strength + ')');
|
|
167
|
+
console.log(' Key: ' + key.toString('hex').substring(0, 32) + '...\n');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// ===========================================
|
|
171
|
+
// KEY VERIFICATION
|
|
172
|
+
// ===========================================
|
|
173
|
+
|
|
174
|
+
console.log('='.repeat(50));
|
|
175
|
+
console.log('Key Verification:');
|
|
176
|
+
console.log('='.repeat(50) + '\n');
|
|
177
|
+
|
|
178
|
+
console.log('Store salt and verify derived key matches:\n');
|
|
179
|
+
|
|
180
|
+
// "Store" the salt and a verification hash
|
|
181
|
+
var storedSalt = 'user_specific_salt_123';
|
|
182
|
+
var masterPassword = 'UserMasterPassword';
|
|
183
|
+
var storedVerifier = backend.deriveKey(masterPassword, storedSalt + ':verify', 16, 1000);
|
|
184
|
+
|
|
185
|
+
console.log('Stored Salt: ' + storedSalt);
|
|
186
|
+
console.log('Stored Verifier: ' + storedVerifier.toString('hex') + '\n');
|
|
187
|
+
|
|
188
|
+
// Attempt verification
|
|
189
|
+
var attempts = ['UserMasterPassword', 'WrongPassword', 'usermasterpassword'];
|
|
190
|
+
|
|
191
|
+
for (var i = 0; i < attempts.length; i++) {
|
|
192
|
+
var attempt = attempts[i];
|
|
193
|
+
var computedVerifier = backend.deriveKey(attempt, storedSalt + ':verify', 16, 1000);
|
|
194
|
+
var isValid = computedVerifier.toString('hex') === storedVerifier.toString('hex');
|
|
195
|
+
|
|
196
|
+
console.log(' "' + attempt + '" -> ' + (isValid ? 'VALID' : 'INVALID'));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ===========================================
|
|
200
|
+
// KEY TAKEAWAYS
|
|
201
|
+
// ===========================================
|
|
202
|
+
|
|
203
|
+
console.log('\n' + '='.repeat(50));
|
|
204
|
+
console.log('KEY TAKEAWAYS:');
|
|
205
|
+
console.log('1. Always use a unique salt per user/purpose');
|
|
206
|
+
console.log('2. Increase iterations for stronger security');
|
|
207
|
+
console.log('3. Derive multiple keys using different salts');
|
|
208
|
+
console.log('4. Higher iterations = more time = harder to brute force');
|
|
209
|
+
console.log('5. Key derivation cannot fix weak passwords');
|
|
210
|
+
console.log('6. Store salt with derived key (salt is not secret)');
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @example HMAC (Hash-based Message Authentication Code)
|
|
3
|
+
* @description Create message authentication codes with TinyAleph
|
|
4
|
+
*
|
|
5
|
+
* HMAC combines a secret key with a message to create an authentication code:
|
|
6
|
+
* - Verifies message integrity (not tampered)
|
|
7
|
+
* - Verifies message authenticity (from expected sender)
|
|
8
|
+
* - Uses a shared secret key
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const { CryptographicBackend } = require('../../modular');
|
|
12
|
+
|
|
13
|
+
// ===========================================
|
|
14
|
+
// SETUP
|
|
15
|
+
// ===========================================
|
|
16
|
+
|
|
17
|
+
const backend = new CryptographicBackend({ dimension: 32 });
|
|
18
|
+
|
|
19
|
+
console.log('TinyAleph HMAC Example');
|
|
20
|
+
console.log('======================\n');
|
|
21
|
+
|
|
22
|
+
// ===========================================
|
|
23
|
+
// HMAC IMPLEMENTATION
|
|
24
|
+
// ===========================================
|
|
25
|
+
|
|
26
|
+
function hmac(key, message, outputLength) {
|
|
27
|
+
outputLength = outputLength || 32;
|
|
28
|
+
|
|
29
|
+
// HMAC uses two passes with padded keys
|
|
30
|
+
var blockSize = 64;
|
|
31
|
+
|
|
32
|
+
// If key is too long, hash it first
|
|
33
|
+
if (key.length > blockSize) {
|
|
34
|
+
key = backend.hash(key, blockSize).toString('hex');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Pad key to block size
|
|
38
|
+
while (key.length < blockSize) {
|
|
39
|
+
key += '\x00';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Create inner and outer padded keys
|
|
43
|
+
var ipad = '';
|
|
44
|
+
var opad = '';
|
|
45
|
+
for (var i = 0; i < blockSize; i++) {
|
|
46
|
+
var keyChar = key.charCodeAt(i);
|
|
47
|
+
ipad += String.fromCharCode(keyChar ^ 0x36);
|
|
48
|
+
opad += String.fromCharCode(keyChar ^ 0x5c);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Inner hash: hash(ipad || message)
|
|
52
|
+
var innerData = ipad + message;
|
|
53
|
+
var innerHash = backend.hash(innerData, outputLength);
|
|
54
|
+
|
|
55
|
+
// Outer hash: hash(opad || inner_hash)
|
|
56
|
+
var outerData = opad + innerHash.toString('hex');
|
|
57
|
+
var hmacResult = backend.hash(outerData, outputLength);
|
|
58
|
+
|
|
59
|
+
return hmacResult;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ===========================================
|
|
63
|
+
// BASIC HMAC
|
|
64
|
+
// ===========================================
|
|
65
|
+
|
|
66
|
+
console.log('Basic HMAC:');
|
|
67
|
+
console.log('-'.repeat(50) + '\n');
|
|
68
|
+
|
|
69
|
+
var secretKey = 'my_secret_key_123';
|
|
70
|
+
var message = 'Hello, this is a secret message.';
|
|
71
|
+
|
|
72
|
+
var mac = hmac(secretKey, message);
|
|
73
|
+
|
|
74
|
+
console.log('Key: ' + secretKey);
|
|
75
|
+
console.log('Message: ' + message);
|
|
76
|
+
console.log('HMAC: ' + mac.toString('hex'));
|
|
77
|
+
|
|
78
|
+
// ===========================================
|
|
79
|
+
// MESSAGE VERIFICATION
|
|
80
|
+
// ===========================================
|
|
81
|
+
|
|
82
|
+
console.log('\n' + '='.repeat(50));
|
|
83
|
+
console.log('Message Verification:');
|
|
84
|
+
console.log('='.repeat(50) + '\n');
|
|
85
|
+
|
|
86
|
+
function verifyMessage(key, message, expectedMac) {
|
|
87
|
+
var computedMac = hmac(key, message);
|
|
88
|
+
return computedMac.toString('hex') === expectedMac;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
var originalMac = hmac(secretKey, message).toString('hex');
|
|
92
|
+
|
|
93
|
+
var testCases = [
|
|
94
|
+
{ msg: message, desc: 'Original message' },
|
|
95
|
+
{ msg: message + ' ', desc: 'Message with extra space' },
|
|
96
|
+
{ msg: 'Hello, this is a SECRET message.', desc: 'Modified message' },
|
|
97
|
+
{ msg: 'Completely different message', desc: 'Different message' }
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
console.log('Testing message integrity:\n');
|
|
101
|
+
|
|
102
|
+
for (var i = 0; i < testCases.length; i++) {
|
|
103
|
+
var test = testCases[i];
|
|
104
|
+
var isValid = verifyMessage(secretKey, test.msg, originalMac);
|
|
105
|
+
console.log(' ' + test.desc + ': ' + (isValid ? 'VALID' : 'INVALID'));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ===========================================
|
|
109
|
+
// KEY VERIFICATION
|
|
110
|
+
// ===========================================
|
|
111
|
+
|
|
112
|
+
console.log('\n' + '='.repeat(50));
|
|
113
|
+
console.log('Key Authentication:');
|
|
114
|
+
console.log('='.repeat(50) + '\n');
|
|
115
|
+
|
|
116
|
+
console.log('Only the correct key produces matching HMAC:\n');
|
|
117
|
+
|
|
118
|
+
var keys = [
|
|
119
|
+
'my_secret_key_123', // Correct
|
|
120
|
+
'my_secret_key_124', // One char different
|
|
121
|
+
'wrong_key', // Wrong
|
|
122
|
+
'' // Empty
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
for (var i = 0; i < keys.length; i++) {
|
|
126
|
+
var testKey = keys[i];
|
|
127
|
+
var testMac = hmac(testKey, message);
|
|
128
|
+
var matches = testMac.toString('hex') === originalMac;
|
|
129
|
+
console.log(' Key "' + (testKey || '(empty)') + '": ' + (matches ? 'MATCHES' : 'No match'));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ===========================================
|
|
133
|
+
// API REQUEST SIGNING
|
|
134
|
+
// ===========================================
|
|
135
|
+
|
|
136
|
+
console.log('\n' + '='.repeat(50));
|
|
137
|
+
console.log('API Request Signing:');
|
|
138
|
+
console.log('='.repeat(50) + '\n');
|
|
139
|
+
|
|
140
|
+
function signRequest(apiKey, method, path, body, timestamp) {
|
|
141
|
+
var payload = method + '\n' + path + '\n' + timestamp + '\n' + (body || '');
|
|
142
|
+
var signature = hmac(apiKey, payload);
|
|
143
|
+
return signature.toString('hex');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function verifyRequest(apiKey, method, path, body, timestamp, signature) {
|
|
147
|
+
var expectedSig = signRequest(apiKey, method, path, body, timestamp);
|
|
148
|
+
return expectedSig === signature;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
var apiKey = 'api_secret_abc123';
|
|
152
|
+
var method = 'POST';
|
|
153
|
+
var path = '/api/users';
|
|
154
|
+
var body = '{"name":"John","email":"john@example.com"}';
|
|
155
|
+
var timestamp = '2024-01-15T12:00:00Z';
|
|
156
|
+
|
|
157
|
+
var signature = signRequest(apiKey, method, path, body, timestamp);
|
|
158
|
+
|
|
159
|
+
console.log('Request Details:');
|
|
160
|
+
console.log(' Method: ' + method);
|
|
161
|
+
console.log(' Path: ' + path);
|
|
162
|
+
console.log(' Body: ' + body);
|
|
163
|
+
console.log(' Timestamp: ' + timestamp);
|
|
164
|
+
console.log(' Signature: ' + signature.substring(0, 32) + '...\n');
|
|
165
|
+
|
|
166
|
+
console.log('Verification:');
|
|
167
|
+
console.log(' Valid request: ' + verifyRequest(apiKey, method, path, body, timestamp, signature));
|
|
168
|
+
console.log(' Tampered body: ' + verifyRequest(apiKey, method, path, body + 'x', timestamp, signature));
|
|
169
|
+
console.log(' Wrong timestamp: ' + verifyRequest(apiKey, method, path, body, '2024-01-15T12:00:01Z', signature));
|
|
170
|
+
|
|
171
|
+
// ===========================================
|
|
172
|
+
// WEBHOOK VERIFICATION
|
|
173
|
+
// ===========================================
|
|
174
|
+
|
|
175
|
+
console.log('\n' + '='.repeat(50));
|
|
176
|
+
console.log('Webhook Signature Verification:');
|
|
177
|
+
console.log('='.repeat(50) + '\n');
|
|
178
|
+
|
|
179
|
+
// Simulate webhook delivery and verification
|
|
180
|
+
function createWebhook(secret, event, payload) {
|
|
181
|
+
var payloadStr = JSON.stringify(payload);
|
|
182
|
+
var signature = hmac(secret, payloadStr);
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
headers: {
|
|
186
|
+
'X-Webhook-Signature': signature.toString('hex'),
|
|
187
|
+
'X-Webhook-Event': event
|
|
188
|
+
},
|
|
189
|
+
body: payloadStr
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function verifyWebhook(secret, webhook) {
|
|
194
|
+
var expectedSig = hmac(secret, webhook.body).toString('hex');
|
|
195
|
+
return expectedSig === webhook.headers['X-Webhook-Signature'];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
var webhookSecret = 'whsec_mysecretkey';
|
|
199
|
+
var event = 'payment.completed';
|
|
200
|
+
var payload = { orderId: '12345', amount: 99.99, currency: 'USD' };
|
|
201
|
+
|
|
202
|
+
var webhook = createWebhook(webhookSecret, event, payload);
|
|
203
|
+
|
|
204
|
+
console.log('Webhook Received:');
|
|
205
|
+
console.log(' Event: ' + webhook.headers['X-Webhook-Event']);
|
|
206
|
+
console.log(' Signature: ' + webhook.headers['X-Webhook-Signature'].substring(0, 32) + '...');
|
|
207
|
+
console.log(' Body: ' + webhook.body);
|
|
208
|
+
console.log(' Valid: ' + verifyWebhook(webhookSecret, webhook));
|
|
209
|
+
|
|
210
|
+
// Tampered webhook
|
|
211
|
+
var tamperedWebhook = {
|
|
212
|
+
headers: webhook.headers,
|
|
213
|
+
body: '{"orderId":"12345","amount":0.01,"currency":"USD"}'
|
|
214
|
+
};
|
|
215
|
+
console.log('\n Tampered Body: ' + tamperedWebhook.body);
|
|
216
|
+
console.log(' Tampered Valid: ' + verifyWebhook(webhookSecret, tamperedWebhook));
|
|
217
|
+
|
|
218
|
+
// ===========================================
|
|
219
|
+
// KEY TAKEAWAYS
|
|
220
|
+
// ===========================================
|
|
221
|
+
|
|
222
|
+
console.log('\n' + '='.repeat(50));
|
|
223
|
+
console.log('KEY TAKEAWAYS:');
|
|
224
|
+
console.log('1. HMAC verifies both integrity and authenticity');
|
|
225
|
+
console.log('2. Only holders of the secret key can create valid MACs');
|
|
226
|
+
console.log('3. Any message change invalidates the MAC');
|
|
227
|
+
console.log('4. Use for API signing, webhooks, and data verification');
|
|
228
|
+
console.log('5. Keep the secret key secure and never expose it');
|
|
229
|
+
console.log('6. Use constant-time comparison for verification');
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @example File Integrity Verification
|
|
3
|
+
* @description Verify file integrity using cryptographic hashes
|
|
4
|
+
*
|
|
5
|
+
* File integrity verification ensures files haven't been modified:
|
|
6
|
+
* - Compute hash of original file
|
|
7
|
+
* - Store hash securely
|
|
8
|
+
* - Recompute and compare to detect changes
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const { CryptographicBackend } = require('../../modular');
|
|
12
|
+
|
|
13
|
+
// ===========================================
|
|
14
|
+
// SETUP
|
|
15
|
+
// ===========================================
|
|
16
|
+
|
|
17
|
+
const backend = new CryptographicBackend({ dimension: 32 });
|
|
18
|
+
|
|
19
|
+
console.log('TinyAleph File Integrity Example');
|
|
20
|
+
console.log('=================================\n');
|
|
21
|
+
|
|
22
|
+
// ===========================================
|
|
23
|
+
// SIMULATED FILE SYSTEM
|
|
24
|
+
// ===========================================
|
|
25
|
+
|
|
26
|
+
// Simulate files (in real use, you'd read actual files)
|
|
27
|
+
var files = {
|
|
28
|
+
'config.json': '{"version":"1.0","debug":false,"timeout":30}',
|
|
29
|
+
'script.js': 'function main() { console.log("Hello"); }\nmain();',
|
|
30
|
+
'data.txt': 'Important data that must not be modified.\nLine 2.',
|
|
31
|
+
'readme.md': '# Project\n\nThis is the readme file.'
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// ===========================================
|
|
35
|
+
// COMPUTE FILE HASHES
|
|
36
|
+
// ===========================================
|
|
37
|
+
|
|
38
|
+
console.log('Computing File Hashes:');
|
|
39
|
+
console.log('-'.repeat(50) + '\n');
|
|
40
|
+
|
|
41
|
+
function hashFile(content) {
|
|
42
|
+
return backend.hash(content, 32).toString('hex');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
var manifest = {};
|
|
46
|
+
|
|
47
|
+
for (var filename in files) {
|
|
48
|
+
if (files.hasOwnProperty(filename)) {
|
|
49
|
+
var hash = hashFile(files[filename]);
|
|
50
|
+
manifest[filename] = {
|
|
51
|
+
hash: hash,
|
|
52
|
+
size: files[filename].length,
|
|
53
|
+
timestamp: new Date().toISOString()
|
|
54
|
+
};
|
|
55
|
+
console.log(' ' + filename.padEnd(15) + ' ' + hash.substring(0, 40) + '...');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ===========================================
|
|
60
|
+
// VERIFY FILE INTEGRITY
|
|
61
|
+
// ===========================================
|
|
62
|
+
|
|
63
|
+
console.log('\n' + '='.repeat(50));
|
|
64
|
+
console.log('Verifying File Integrity:');
|
|
65
|
+
console.log('='.repeat(50) + '\n');
|
|
66
|
+
|
|
67
|
+
function verifyFile(filename, content, manifest) {
|
|
68
|
+
if (!manifest[filename]) {
|
|
69
|
+
return { valid: false, reason: 'File not in manifest' };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
var currentHash = hashFile(content);
|
|
73
|
+
var expectedHash = manifest[filename].hash;
|
|
74
|
+
|
|
75
|
+
if (currentHash === expectedHash) {
|
|
76
|
+
return { valid: true, reason: 'Hash matches' };
|
|
77
|
+
} else {
|
|
78
|
+
return { valid: false, reason: 'Hash mismatch', expected: expectedHash, actual: currentHash };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
console.log('Verification of unchanged files:\n');
|
|
83
|
+
|
|
84
|
+
for (var filename in files) {
|
|
85
|
+
if (files.hasOwnProperty(filename)) {
|
|
86
|
+
var result = verifyFile(filename, files[filename], manifest);
|
|
87
|
+
console.log(' ' + filename + ': ' + (result.valid ? 'OK' : 'FAILED'));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ===========================================
|
|
92
|
+
// DETECT MODIFICATIONS
|
|
93
|
+
// ===========================================
|
|
94
|
+
|
|
95
|
+
console.log('\n' + '='.repeat(50));
|
|
96
|
+
console.log('Detecting Modifications:');
|
|
97
|
+
console.log('='.repeat(50) + '\n');
|
|
98
|
+
|
|
99
|
+
// Simulate file modifications
|
|
100
|
+
var modifiedFiles = {
|
|
101
|
+
'config.json': '{"version":"1.0","debug":true,"timeout":30}', // Changed debug to true
|
|
102
|
+
'script.js': 'function main() { console.log("Hello"); }\nmain();', // Unchanged
|
|
103
|
+
'data.txt': 'Important data that WAS modified.\nLine 2.', // Modified
|
|
104
|
+
'readme.md': '# Project\n\nThis is the readme file.' // Unchanged
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
console.log('After modifications:\n');
|
|
108
|
+
|
|
109
|
+
for (var filename in modifiedFiles) {
|
|
110
|
+
if (modifiedFiles.hasOwnProperty(filename)) {
|
|
111
|
+
var result = verifyFile(filename, modifiedFiles[filename], manifest);
|
|
112
|
+
var status = result.valid ? 'UNCHANGED' : 'MODIFIED';
|
|
113
|
+
console.log(' ' + filename + ': ' + status);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ===========================================
|
|
118
|
+
// DETAILED CHANGE DETECTION
|
|
119
|
+
// ===========================================
|
|
120
|
+
|
|
121
|
+
console.log('\n' + '='.repeat(50));
|
|
122
|
+
console.log('Detailed Change Analysis:');
|
|
123
|
+
console.log('='.repeat(50) + '\n');
|
|
124
|
+
|
|
125
|
+
function analyzeChanges(originalFiles, currentFiles, manifest) {
|
|
126
|
+
var report = {
|
|
127
|
+
unchanged: [],
|
|
128
|
+
modified: [],
|
|
129
|
+
added: [],
|
|
130
|
+
deleted: []
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Check existing files
|
|
134
|
+
for (var filename in manifest) {
|
|
135
|
+
if (manifest.hasOwnProperty(filename)) {
|
|
136
|
+
if (!currentFiles[filename]) {
|
|
137
|
+
report.deleted.push(filename);
|
|
138
|
+
} else {
|
|
139
|
+
var result = verifyFile(filename, currentFiles[filename], manifest);
|
|
140
|
+
if (result.valid) {
|
|
141
|
+
report.unchanged.push(filename);
|
|
142
|
+
} else {
|
|
143
|
+
report.modified.push({
|
|
144
|
+
filename: filename,
|
|
145
|
+
originalHash: manifest[filename].hash.substring(0, 16) + '...',
|
|
146
|
+
currentHash: hashFile(currentFiles[filename]).substring(0, 16) + '...'
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check for new files
|
|
154
|
+
for (var filename in currentFiles) {
|
|
155
|
+
if (currentFiles.hasOwnProperty(filename)) {
|
|
156
|
+
if (!manifest[filename]) {
|
|
157
|
+
report.added.push(filename);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return report;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Add a new file and delete one
|
|
166
|
+
var scenario = Object.assign({}, modifiedFiles);
|
|
167
|
+
scenario['new-file.txt'] = 'This is a new file';
|
|
168
|
+
delete scenario['readme.md'];
|
|
169
|
+
|
|
170
|
+
var report = analyzeChanges(files, scenario, manifest);
|
|
171
|
+
|
|
172
|
+
console.log('Change Report:');
|
|
173
|
+
console.log(' Unchanged: ' + (report.unchanged.length > 0 ? report.unchanged.join(', ') : 'none'));
|
|
174
|
+
console.log(' Modified: ' + (report.modified.length > 0 ? report.modified.map(function(m) { return m.filename; }).join(', ') : 'none'));
|
|
175
|
+
console.log(' Added: ' + (report.added.length > 0 ? report.added.join(', ') : 'none'));
|
|
176
|
+
console.log(' Deleted: ' + (report.deleted.length > 0 ? report.deleted.join(', ') : 'none'));
|
|
177
|
+
|
|
178
|
+
if (report.modified.length > 0) {
|
|
179
|
+
console.log('\nModified file details:');
|
|
180
|
+
for (var i = 0; i < report.modified.length; i++) {
|
|
181
|
+
var mod = report.modified[i];
|
|
182
|
+
console.log(' ' + mod.filename + ':');
|
|
183
|
+
console.log(' Original: ' + mod.originalHash);
|
|
184
|
+
console.log(' Current: ' + mod.currentHash);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ===========================================
|
|
189
|
+
// MANIFEST FILE FORMAT
|
|
190
|
+
// ===========================================
|
|
191
|
+
|
|
192
|
+
console.log('\n' + '='.repeat(50));
|
|
193
|
+
console.log('Manifest File Format:');
|
|
194
|
+
console.log('='.repeat(50) + '\n');
|
|
195
|
+
|
|
196
|
+
function createManifest(files) {
|
|
197
|
+
var manifest = {
|
|
198
|
+
version: '1.0',
|
|
199
|
+
created: new Date().toISOString(),
|
|
200
|
+
algorithm: 'tinyaleph-hash-32',
|
|
201
|
+
files: {}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
for (var filename in files) {
|
|
205
|
+
if (files.hasOwnProperty(filename)) {
|
|
206
|
+
manifest.files[filename] = {
|
|
207
|
+
hash: hashFile(files[filename]),
|
|
208
|
+
size: files[filename].length
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Sign the manifest itself
|
|
214
|
+
var manifestContent = JSON.stringify(manifest.files);
|
|
215
|
+
manifest.signature = hashFile(manifestContent);
|
|
216
|
+
|
|
217
|
+
return manifest;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
var fullManifest = createManifest(files);
|
|
221
|
+
console.log(JSON.stringify(fullManifest, null, 2));
|
|
222
|
+
|
|
223
|
+
// ===========================================
|
|
224
|
+
// INCREMENTAL UPDATES
|
|
225
|
+
// ===========================================
|
|
226
|
+
|
|
227
|
+
console.log('\n' + '='.repeat(50));
|
|
228
|
+
console.log('Incremental Manifest Updates:');
|
|
229
|
+
console.log('='.repeat(50) + '\n');
|
|
230
|
+
|
|
231
|
+
function updateManifest(manifest, filename, content) {
|
|
232
|
+
var newManifest = JSON.parse(JSON.stringify(manifest));
|
|
233
|
+
newManifest.files[filename] = {
|
|
234
|
+
hash: hashFile(content),
|
|
235
|
+
size: content.length
|
|
236
|
+
};
|
|
237
|
+
newManifest.updated = new Date().toISOString();
|
|
238
|
+
|
|
239
|
+
// Re-sign
|
|
240
|
+
var manifestContent = JSON.stringify(newManifest.files);
|
|
241
|
+
newManifest.signature = hashFile(manifestContent);
|
|
242
|
+
|
|
243
|
+
return newManifest;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
console.log('Updating manifest after file change:\n');
|
|
247
|
+
var updatedManifest = updateManifest(fullManifest, 'config.json', '{"version":"2.0"}');
|
|
248
|
+
console.log(' Old config.json hash: ' + fullManifest.files['config.json'].hash.substring(0, 32) + '...');
|
|
249
|
+
console.log(' New config.json hash: ' + updatedManifest.files['config.json'].hash.substring(0, 32) + '...');
|
|
250
|
+
console.log(' New signature: ' + updatedManifest.signature.substring(0, 32) + '...');
|
|
251
|
+
|
|
252
|
+
// ===========================================
|
|
253
|
+
// KEY TAKEAWAYS
|
|
254
|
+
// ===========================================
|
|
255
|
+
|
|
256
|
+
console.log('\n' + '='.repeat(50));
|
|
257
|
+
console.log('KEY TAKEAWAYS:');
|
|
258
|
+
console.log('1. Hash files to create integrity fingerprints');
|
|
259
|
+
console.log('2. Store hashes in a manifest file');
|
|
260
|
+
console.log('3. Recompute and compare to detect changes');
|
|
261
|
+
console.log('4. Sign manifests to protect against tampering');
|
|
262
|
+
console.log('5. Track added, modified, and deleted files');
|
|
263
|
+
console.log('6. Use incremental updates for efficiency');
|