@aleph-ai/tinyaleph 1.5.7 → 1.6.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/core/alexander-module.js +1469 -0
- package/core/arithmetic-link-kernel.js +1338 -0
- package/core/index.js +95 -2
- 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/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/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/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/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/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 +417 -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,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Example 04: CRT-Enhanced ResoFormer
|
|
4
|
+
*
|
|
5
|
+
* Demonstrates the full CRT-enhanced ResoFormer architecture:
|
|
6
|
+
* - Per-modulus attention heads with Birkhoff projection
|
|
7
|
+
* - CRT fusion of head outputs
|
|
8
|
+
* - Homology detection for semantic consistency
|
|
9
|
+
*
|
|
10
|
+
* This integrates with tinyaleph's SparsePrimeState representation.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
CRTResonantAttention,
|
|
17
|
+
HomologyRegularizedBlock,
|
|
18
|
+
CRTResoFormer,
|
|
19
|
+
createCRTResoFormer
|
|
20
|
+
} = require('../../core/rformer-crt');
|
|
21
|
+
|
|
22
|
+
const { SparsePrimeState } = require('../../core/rformer');
|
|
23
|
+
|
|
24
|
+
console.log('=== CRT-Enhanced ResoFormer Example ===\n');
|
|
25
|
+
|
|
26
|
+
// Example 1: CRT Resonant Attention
|
|
27
|
+
console.log('1. CRT Resonant Attention:');
|
|
28
|
+
const attention = new CRTResonantAttention({
|
|
29
|
+
numHeads: 4,
|
|
30
|
+
numPrimes: 4096,
|
|
31
|
+
activeK: 32
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
console.log(` Number of heads: ${attention.numHeads}`);
|
|
35
|
+
console.log(` Moduli: [${attention.moduli.join(', ')}]`);
|
|
36
|
+
console.log(` Product P = ${attention.moduli.reduce((a, b) => a * b, 1)}`);
|
|
37
|
+
|
|
38
|
+
// Create sample states
|
|
39
|
+
const query = SparsePrimeState.fromHash('query concept');
|
|
40
|
+
const keys = [
|
|
41
|
+
SparsePrimeState.fromHash('key 1 - related'),
|
|
42
|
+
SparsePrimeState.fromHash('key 2 - similar'),
|
|
43
|
+
SparsePrimeState.fromHash('key 3 - different')
|
|
44
|
+
];
|
|
45
|
+
const values = keys.map((_, i) => SparsePrimeState.fromHash(`value ${i}`));
|
|
46
|
+
|
|
47
|
+
console.log(` Query: ${query.getActivePrimes().slice(0, 5).join(', ')}...`);
|
|
48
|
+
console.log(` Keys: ${keys.length} states\n`);
|
|
49
|
+
|
|
50
|
+
const attnResult = attention.forward(query, keys, values);
|
|
51
|
+
console.log(` Output primes: ${attnResult.result.getActivePrimes().length} active`);
|
|
52
|
+
console.log(` Heads computed: ${attnResult.headOutputs.length}`);
|
|
53
|
+
console.log(` CRT residues: [${attnResult.crtResidues.map(r => r.toFixed(2)).join(', ')}]`);
|
|
54
|
+
console.log(` Homology detected: ${attnResult.homologyInfo.hasHoles}`);
|
|
55
|
+
console.log(` Betti numbers: β₀=${attnResult.homologyInfo.bettiNumbers[0]}, ` +
|
|
56
|
+
`β₁=${attnResult.homologyInfo.bettiNumbers[1]}`);
|
|
57
|
+
|
|
58
|
+
// Example 2: Homology Regularized Block
|
|
59
|
+
console.log('\n2. Homology Regularized Block:');
|
|
60
|
+
const block = new HomologyRegularizedBlock({
|
|
61
|
+
numHeads: 4,
|
|
62
|
+
hiddenDim: 256,
|
|
63
|
+
numPrimes: 4096,
|
|
64
|
+
activeK: 32,
|
|
65
|
+
homologyWeight: 0.1
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const input = SparsePrimeState.fromHash('input state');
|
|
69
|
+
const context = [
|
|
70
|
+
SparsePrimeState.fromHash('context 1'),
|
|
71
|
+
SparsePrimeState.fromHash('context 2'),
|
|
72
|
+
SparsePrimeState.fromHash('context 3')
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
const blockResult = block.forward(input, context);
|
|
76
|
+
console.log(` Input primes: ${input.getActivePrimes().length}`);
|
|
77
|
+
console.log(` Output primes: ${blockResult.output.getActivePrimes().length}`);
|
|
78
|
+
console.log(` Homology loss: ${blockResult.loss.toFixed(6)}`);
|
|
79
|
+
console.log(` Has holes: ${blockResult.homologyInfo.hasHoles}`);
|
|
80
|
+
|
|
81
|
+
// Example 3: Full CRT ResoFormer
|
|
82
|
+
console.log('\n3. Full CRT ResoFormer:');
|
|
83
|
+
const model = createCRTResoFormer({
|
|
84
|
+
numLayers: 3,
|
|
85
|
+
numHeads: 4,
|
|
86
|
+
hiddenDim: 256,
|
|
87
|
+
numPrimes: 4096,
|
|
88
|
+
activeK: 32,
|
|
89
|
+
homologyWeight: 0.1,
|
|
90
|
+
usePositionalEncoding: true
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
console.log(` Layers: ${model.numLayers}`);
|
|
94
|
+
console.log(` Position encoding: ${model.usePositionalEncoding}`);
|
|
95
|
+
console.log(` Parameter count (est): ${model.getParameterCount()}`);
|
|
96
|
+
|
|
97
|
+
// Process a sequence
|
|
98
|
+
const sequence = [
|
|
99
|
+
SparsePrimeState.fromHash('the'),
|
|
100
|
+
SparsePrimeState.fromHash('quick'),
|
|
101
|
+
SparsePrimeState.fromHash('brown'),
|
|
102
|
+
SparsePrimeState.fromHash('fox')
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
console.log(`\n Processing sequence of ${sequence.length} tokens...`);
|
|
106
|
+
const result = model.forward(sequence);
|
|
107
|
+
|
|
108
|
+
console.log(` Output sequence length: ${result.output.length}`);
|
|
109
|
+
console.log(` Total homology loss: ${result.totalLoss.toFixed(6)}`);
|
|
110
|
+
console.log(` Homology report:`);
|
|
111
|
+
console.log(` Holes detected: ${result.homologyReport.hasHoles}`);
|
|
112
|
+
console.log(` Total holes: ${result.homologyReport.totalHolesDetected}`);
|
|
113
|
+
console.log(` Max Betti number: ${result.homologyReport.maxBettiNumber}`);
|
|
114
|
+
console.log(` Layer reports: ${result.homologyReport.layerReports.length}`);
|
|
115
|
+
|
|
116
|
+
// Example 4: Training mode
|
|
117
|
+
console.log('\n4. Training vs Evaluation Mode:');
|
|
118
|
+
model.train(true);
|
|
119
|
+
console.log(` Training mode: ${model.blocks[0].training}`);
|
|
120
|
+
|
|
121
|
+
model.eval();
|
|
122
|
+
console.log(` After eval(): ${model.blocks[0].training}`);
|
|
123
|
+
|
|
124
|
+
// Example 5: CRT Configuration
|
|
125
|
+
console.log('\n5. CRT Configuration:');
|
|
126
|
+
const crtConfig = model.getCRTConfig();
|
|
127
|
+
console.log(` Moduli: [${crtConfig.moduli.join(', ')}]`);
|
|
128
|
+
console.log(` Heads: ${crtConfig.numHeads}`);
|
|
129
|
+
console.log(` Temperature: ${crtConfig.temperature}`);
|
|
130
|
+
console.log(` Head weights (first head): [${crtConfig.headWeights[0].map(w => w.toFixed(3)).join(', ')}]`);
|
|
131
|
+
|
|
132
|
+
console.log('\n✓ Example complete\n');
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# CRT-Homology Examples
|
|
2
|
+
|
|
3
|
+
This directory contains examples demonstrating the CRT-Homology framework integrated into tinyaleph.
|
|
4
|
+
|
|
5
|
+
## Examples
|
|
6
|
+
|
|
7
|
+
### 01-residue-encoding.js
|
|
8
|
+
Demonstrates encoding hidden vectors into K residue distributions over coprime moduli, then reconstructing via Chinese Remainder Theorem.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
node examples/crt-homology/01-residue-encoding.js
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### 02-birkhoff-attention.js
|
|
15
|
+
Shows projecting attention matrices onto the Birkhoff polytope (doubly-stochastic matrices) using Sinkhorn-Knopp algorithm.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
node examples/crt-homology/02-birkhoff-attention.js
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 03-homology-loss.js
|
|
22
|
+
Illustrates detecting "holes" in residue space - consistency failures that persist under perturbation. Computes Betti numbers and homology loss.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
node examples/crt-homology/03-homology-loss.js
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 04-crt-resoformer.js
|
|
29
|
+
Full CRT-enhanced ResoFormer architecture with per-modulus attention heads, CRT fusion, and homology detection.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
node examples/crt-homology/04-crt-resoformer.js
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Key Concepts
|
|
36
|
+
|
|
37
|
+
### Chinese Remainder Theorem (CRT)
|
|
38
|
+
Given coprime moduli p₁, p₂, ..., pₖ with product P = ∏pₖ, any value L ∈ [0, P) can be uniquely reconstructed from its residues mod each pₖ:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
L̂ = Σₖ E[rₖ] · (P/pₖ) · (P/pₖ)⁻¹ mod P
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Birkhoff Polytope
|
|
45
|
+
The set of doubly-stochastic matrices (all row and column sums = 1). Projecting attention onto this space enforces "conservation of attention mass".
|
|
46
|
+
|
|
47
|
+
### Homology Loss
|
|
48
|
+
Detects semantic inconsistencies as topological holes:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
ℒ_homology = Σ_{cycles ∈ Ker(ℛ)} f(cycle)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Where Ker(ℛ) = { r | ε(r) > τ } is the kernel of high-error residue tuples.
|
|
55
|
+
|
|
56
|
+
### Betti Numbers
|
|
57
|
+
- β₀: Number of connected components in the kernel
|
|
58
|
+
- β₁: Number of 1-dimensional holes (cycles that don't bound)
|
|
59
|
+
|
|
60
|
+
## Mathematical Foundation
|
|
61
|
+
|
|
62
|
+
See [docs/reference/09-crt-homology.md](../../docs/reference/09-crt-homology.md) for complete mathematical details.
|
|
63
|
+
|
|
64
|
+
## Run All Examples
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
for f in examples/crt-homology/*.js; do node "$f"; done
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @example Password Hashing
|
|
3
|
+
* @description Securely hash passwords using TinyAleph's cryptographic backend
|
|
4
|
+
*
|
|
5
|
+
* TinyAleph provides cryptographic hashing that:
|
|
6
|
+
* - Creates deterministic hashes from input
|
|
7
|
+
* - Is one-way (cannot reverse to get original)
|
|
8
|
+
* - Has configurable output length
|
|
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 Password Hashing Example');
|
|
20
|
+
console.log('===================================\n');
|
|
21
|
+
|
|
22
|
+
// ===========================================
|
|
23
|
+
// BASIC PASSWORD HASHING
|
|
24
|
+
// ===========================================
|
|
25
|
+
|
|
26
|
+
console.log('Basic Password Hashing:');
|
|
27
|
+
console.log('-'.repeat(50) + '\n');
|
|
28
|
+
|
|
29
|
+
var passwords = [
|
|
30
|
+
'password123',
|
|
31
|
+
'SecureP@ss!',
|
|
32
|
+
'MySecret2024',
|
|
33
|
+
'hunter2'
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
console.log('Password Hash (first 32 chars)');
|
|
37
|
+
console.log('-'.repeat(60));
|
|
38
|
+
|
|
39
|
+
for (var i = 0; i < passwords.length; i++) {
|
|
40
|
+
var password = passwords[i];
|
|
41
|
+
var hash = backend.hash(password);
|
|
42
|
+
var hashHex = hash.toString('hex');
|
|
43
|
+
console.log(password.padEnd(25) + hashHex.substring(0, 32) + '...');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ===========================================
|
|
47
|
+
// HASH VERIFICATION
|
|
48
|
+
// ===========================================
|
|
49
|
+
|
|
50
|
+
console.log('\n' + '='.repeat(50));
|
|
51
|
+
console.log('Password Verification:');
|
|
52
|
+
console.log('='.repeat(50) + '\n');
|
|
53
|
+
|
|
54
|
+
function verifyPassword(password, storedHash) {
|
|
55
|
+
var computedHash = backend.hash(password);
|
|
56
|
+
return computedHash.toString('hex') === storedHash;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Store a password hash
|
|
60
|
+
var originalPassword = 'MySecretPassword';
|
|
61
|
+
var storedHash = backend.hash(originalPassword).toString('hex');
|
|
62
|
+
|
|
63
|
+
console.log('Stored hash: ' + storedHash.substring(0, 40) + '...\n');
|
|
64
|
+
|
|
65
|
+
// Test verification
|
|
66
|
+
var testPasswords = [
|
|
67
|
+
'MySecretPassword', // Correct
|
|
68
|
+
'mysecretpassword', // Wrong case
|
|
69
|
+
'MySecretPassword ', // Trailing space
|
|
70
|
+
'WrongPassword' // Completely wrong
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
console.log('Verification results:');
|
|
74
|
+
for (var i = 0; i < testPasswords.length; i++) {
|
|
75
|
+
var testPwd = testPasswords[i];
|
|
76
|
+
var isValid = verifyPassword(testPwd, storedHash);
|
|
77
|
+
var status = isValid ? 'VALID' : 'INVALID';
|
|
78
|
+
console.log(' "' + testPwd + '" -> ' + status);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ===========================================
|
|
82
|
+
// HASH PROPERTIES
|
|
83
|
+
// ===========================================
|
|
84
|
+
|
|
85
|
+
console.log('\n' + '='.repeat(50));
|
|
86
|
+
console.log('Hash Properties:');
|
|
87
|
+
console.log('='.repeat(50) + '\n');
|
|
88
|
+
|
|
89
|
+
// Determinism
|
|
90
|
+
console.log('1. Determinism (same input = same output):');
|
|
91
|
+
var hash1 = backend.hash('test').toString('hex');
|
|
92
|
+
var hash2 = backend.hash('test').toString('hex');
|
|
93
|
+
console.log(' Hash 1: ' + hash1.substring(0, 32));
|
|
94
|
+
console.log(' Hash 2: ' + hash2.substring(0, 32));
|
|
95
|
+
console.log(' Equal: ' + (hash1 === hash2));
|
|
96
|
+
|
|
97
|
+
// Avalanche effect
|
|
98
|
+
console.log('\n2. Avalanche Effect (small change = big difference):');
|
|
99
|
+
var similar1 = backend.hash('password').toString('hex');
|
|
100
|
+
var similar2 = backend.hash('Password').toString('hex');
|
|
101
|
+
var similar3 = backend.hash('password1').toString('hex');
|
|
102
|
+
|
|
103
|
+
console.log(' "password" -> ' + similar1.substring(0, 24));
|
|
104
|
+
console.log(' "Password" -> ' + similar2.substring(0, 24));
|
|
105
|
+
console.log(' "password1" -> ' + similar3.substring(0, 24));
|
|
106
|
+
|
|
107
|
+
// Count differing characters
|
|
108
|
+
function countDiff(a, b) {
|
|
109
|
+
var diff = 0;
|
|
110
|
+
for (var i = 0; i < Math.min(a.length, b.length); i++) {
|
|
111
|
+
if (a[i] !== b[i]) diff++;
|
|
112
|
+
}
|
|
113
|
+
return diff;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
console.log(' Difference (p vs P): ' + countDiff(similar1, similar2) + ' chars');
|
|
117
|
+
console.log(' Difference (p vs p1): ' + countDiff(similar1, similar3) + ' chars');
|
|
118
|
+
|
|
119
|
+
// ===========================================
|
|
120
|
+
// CONFIGURABLE OUTPUT LENGTH
|
|
121
|
+
// ===========================================
|
|
122
|
+
|
|
123
|
+
console.log('\n' + '='.repeat(50));
|
|
124
|
+
console.log('Configurable Hash Length:');
|
|
125
|
+
console.log('='.repeat(50) + '\n');
|
|
126
|
+
|
|
127
|
+
var input = 'SampleInput';
|
|
128
|
+
var lengths = [16, 32, 64, 128];
|
|
129
|
+
|
|
130
|
+
for (var l = 0; l < lengths.length; l++) {
|
|
131
|
+
var len = lengths[l];
|
|
132
|
+
var hash = backend.hash(input, len);
|
|
133
|
+
console.log(len + ' bytes: ' + hash.toString('hex').substring(0, 40) + (len > 20 ? '...' : ''));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ===========================================
|
|
137
|
+
// TIMING ATTACK RESISTANCE
|
|
138
|
+
// ===========================================
|
|
139
|
+
|
|
140
|
+
console.log('\n' + '='.repeat(50));
|
|
141
|
+
console.log('Constant-Time Comparison:');
|
|
142
|
+
console.log('='.repeat(50) + '\n');
|
|
143
|
+
|
|
144
|
+
// Use constant-time comparison to prevent timing attacks
|
|
145
|
+
function constantTimeCompare(a, b) {
|
|
146
|
+
if (a.length !== b.length) return false;
|
|
147
|
+
|
|
148
|
+
var result = 0;
|
|
149
|
+
for (var i = 0; i < a.length; i++) {
|
|
150
|
+
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
151
|
+
}
|
|
152
|
+
return result === 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
var storedHashStr = backend.hash('secret').toString('hex');
|
|
156
|
+
var correctAttempt = backend.hash('secret').toString('hex');
|
|
157
|
+
var wrongAttempt = backend.hash('wrong').toString('hex');
|
|
158
|
+
|
|
159
|
+
console.log('Constant-time comparison prevents timing attacks:');
|
|
160
|
+
console.log(' Correct password: ' + constantTimeCompare(storedHashStr, correctAttempt));
|
|
161
|
+
console.log(' Wrong password: ' + constantTimeCompare(storedHashStr, wrongAttempt));
|
|
162
|
+
|
|
163
|
+
// ===========================================
|
|
164
|
+
// SALT USAGE
|
|
165
|
+
// ===========================================
|
|
166
|
+
|
|
167
|
+
console.log('\n' + '='.repeat(50));
|
|
168
|
+
console.log('Using Salts:');
|
|
169
|
+
console.log('='.repeat(50) + '\n');
|
|
170
|
+
|
|
171
|
+
function hashWithSalt(password, salt) {
|
|
172
|
+
return backend.hash(salt + password);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function generateSalt() {
|
|
176
|
+
// In production, use crypto.randomBytes
|
|
177
|
+
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
178
|
+
var salt = '';
|
|
179
|
+
for (var i = 0; i < 16; i++) {
|
|
180
|
+
salt += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
181
|
+
}
|
|
182
|
+
return salt;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
var password = 'CommonPassword';
|
|
186
|
+
var salt1 = generateSalt();
|
|
187
|
+
var salt2 = generateSalt();
|
|
188
|
+
|
|
189
|
+
var salted1 = hashWithSalt(password, salt1).toString('hex');
|
|
190
|
+
var salted2 = hashWithSalt(password, salt2).toString('hex');
|
|
191
|
+
|
|
192
|
+
console.log('Same password with different salts:');
|
|
193
|
+
console.log(' Salt 1: ' + salt1);
|
|
194
|
+
console.log(' Hash 1: ' + salted1.substring(0, 32) + '...');
|
|
195
|
+
console.log(' Salt 2: ' + salt2);
|
|
196
|
+
console.log(' Hash 2: ' + salted2.substring(0, 32) + '...');
|
|
197
|
+
console.log(' Different: ' + (salted1 !== salted2));
|
|
198
|
+
|
|
199
|
+
// ===========================================
|
|
200
|
+
// KEY TAKEAWAYS
|
|
201
|
+
// ===========================================
|
|
202
|
+
|
|
203
|
+
console.log('\n' + '='.repeat(50));
|
|
204
|
+
console.log('KEY TAKEAWAYS:');
|
|
205
|
+
console.log('1. Hash passwords before storing them');
|
|
206
|
+
console.log('2. Use salts to prevent rainbow table attacks');
|
|
207
|
+
console.log('3. Use constant-time comparison for security');
|
|
208
|
+
console.log('4. Hashes are deterministic but one-way');
|
|
209
|
+
console.log('5. Small input changes cause large hash changes');
|
|
210
|
+
console.log('6. Configure output length based on security needs');
|
|
@@ -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)');
|