0
# Big Number Arithmetic
1
2
SJCL provides arbitrary precision integer arithmetic through the `sjcl.bn` (big number) class, essential for cryptographic operations requiring large number support beyond JavaScript's native number limitations.
3
4
## Capabilities
5
6
### Big Number Constructor
7
8
Create big number instances from various input types.
9
10
```javascript { .api }
11
/**
12
* Big number constructor
13
* @param {number|string|sjcl.bn} it - Initial value (number, hex string, or another big number)
14
*/
15
new sjcl.bn(it);
16
```
17
18
**Usage Examples:**
19
20
```javascript
21
const sjcl = require('sjcl');
22
23
// Create from integer
24
const bn1 = new sjcl.bn(12345);
25
console.log('From integer:', bn1.toString());
26
27
// Create from hex string
28
const bn2 = new sjcl.bn('deadbeef');
29
console.log('From hex:', bn2.toString());
30
31
// Create from another big number (copy constructor)
32
const bn3 = new sjcl.bn(bn2);
33
console.log('Copied:', bn3.toString());
34
35
// Create large number
36
const largeBN = new sjcl.bn('123456789abcdef0123456789abcdef0123456789abcdef');
37
console.log('Large number:', largeBN.toString());
38
```
39
40
### Basic Operations
41
42
Fundamental arithmetic operations on big numbers.
43
44
```javascript { .api }
45
/**
46
* Copy the big number
47
* @returns {sjcl.bn} New big number with same value
48
*/
49
sjcl.bn.prototype.copy();
50
51
/**
52
* Initialize with new value
53
* @param {number|string|sjcl.bn} it - New value
54
* @returns {sjcl.bn} This big number for chaining
55
*/
56
sjcl.bn.prototype.initWith(it);
57
58
/**
59
* Test equality with another big number
60
* @param {sjcl.bn} that - Big number to compare with
61
* @returns {boolean} True if numbers are equal
62
*/
63
sjcl.bn.prototype.equals(that);
64
65
/**
66
* Greater than or equal comparison (constant time)
67
* @param {sjcl.bn} that - Big number to compare with
68
* @returns {boolean} True if this >= that
69
*/
70
sjcl.bn.prototype.greaterEquals(that);
71
72
/**
73
* Convert to hex string
74
* @returns {string} Hexadecimal representation
75
*/
76
sjcl.bn.prototype.toString();
77
```
78
79
**Usage Examples:**
80
81
```javascript
82
const sjcl = require('sjcl');
83
84
// Basic operations
85
const a = new sjcl.bn('deadbeef');
86
const b = new sjcl.bn('cafebabe');
87
88
// Copy
89
const aCopy = a.copy();
90
console.log('Copy equals original:', a.equals(aCopy)); // true
91
92
// Comparison
93
console.log('a >= b:', a.greaterEquals(b));
94
console.log('a == b:', a.equals(b)); // false
95
96
// String conversion
97
console.log('a as hex:', a.toString());
98
console.log('b as hex:', b.toString());
99
100
// Reinitialize
101
aCopy.initWith('12345678');
102
console.log('Reinitialized:', aCopy.toString());
103
```
104
105
### Arithmetic Operations
106
107
Core mathematical operations for big number arithmetic.
108
109
```javascript { .api }
110
/**
111
* Add two big numbers
112
* @param {sjcl.bn} that - Big number to add
113
* @returns {sjcl.bn} Sum as new big number
114
*/
115
sjcl.bn.prototype.add(that);
116
117
/**
118
* Subtract big number from this one
119
* @param {sjcl.bn} that - Big number to subtract
120
* @returns {sjcl.bn} Difference as new big number
121
*/
122
sjcl.bn.prototype.sub(that);
123
124
/**
125
* Multiply two big numbers
126
* @param {sjcl.bn} that - Big number to multiply by
127
* @returns {sjcl.bn} Product as new big number
128
*/
129
sjcl.bn.prototype.mul(that);
130
131
/**
132
* Square the big number
133
* @returns {sjcl.bn} Square as new big number
134
*/
135
sjcl.bn.prototype.square();
136
137
/**
138
* Modular exponentiation
139
* @param {sjcl.bn} exp - Exponent
140
* @param {sjcl.bn} [mod] - Modulus (if provided, computes (this^exp) mod mod)
141
* @returns {sjcl.bn} Result as new big number
142
*/
143
sjcl.bn.prototype.power(exp, mod);
144
```
145
146
**Usage Examples:**
147
148
```javascript
149
const sjcl = require('sjcl');
150
151
// Create test numbers
152
const a = new sjcl.bn('1000');
153
const b = new sjcl.bn('500');
154
const c = new sjcl.bn('7');
155
156
// Basic arithmetic
157
const sum = a.add(b);
158
console.log('1000 + 500 =', sum.toString()); // 1500
159
160
const diff = a.sub(b);
161
console.log('1000 - 500 =', diff.toString()); // 500
162
163
const product = a.mul(b);
164
console.log('1000 * 500 =', product.toString()); // 500000
165
166
const squared = a.square();
167
console.log('1000^2 =', squared.toString()); // 1000000
168
169
// Exponentiation
170
const powered = c.power(new sjcl.bn('3'));
171
console.log('7^3 =', powered.toString()); // 343
172
173
// Modular exponentiation
174
const modPow = c.power(new sjcl.bn('10'), new sjcl.bn('13'));
175
console.log('7^10 mod 13 =', modPow.toString());
176
```
177
178
### Utility Operations
179
180
Helper methods for big number manipulation.
181
182
```javascript { .api }
183
/**
184
* Get the i'th limb (32-bit word)
185
* @param {number} i - Limb index
186
* @returns {number} 32-bit limb value
187
*/
188
sjcl.bn.prototype.getLimb(i);
189
190
/**
191
* Remove leading zeros
192
* @returns {sjcl.bn} This big number for chaining
193
*/
194
sjcl.bn.prototype.trim();
195
```
196
197
**Usage Examples:**
198
199
```javascript
200
const sjcl = require('sjcl');\n\n// Create big number\nconst bn = new sjcl.bn('deadbeefcafebabe');\n\n// Access individual limbs (32-bit words)\nconsole.log('Limb 0:', bn.getLimb(0).toString(16));\nconsole.log('Limb 1:', bn.getLimb(1).toString(16));\n\n// Trim leading zeros\nconst withZeros = new sjcl.bn('000deadbeef');\nconsole.log('Before trim:', withZeros.toString());\nwithZeros.trim();\nconsole.log('After trim:', withZeros.toString());\n```\n\n## Cryptographic Applications\n\n### RSA Key Operations\n\nBig numbers are essential for RSA cryptography:\n\n```javascript\nconst sjcl = require('sjcl');\n\n// Simulate RSA key generation components\nfunction generateRSAComponents() {\n // In real RSA, these would be large random primes\n const p = new sjcl.bn('d5bbf8a7e3d5e5e0b3f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5');\n const q = new sjcl.bn('e9f8a7b3d5e5e0f3f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5');\n \n // Calculate n = p * q\n const n = p.mul(q);\n \n // Calculate phi(n) = (p-1) * (q-1)\n const pMinus1 = p.sub(new sjcl.bn('1'));\n const qMinus1 = q.sub(new sjcl.bn('1'));\n const phi = pMinus1.mul(qMinus1);\n \n // Common public exponent\n const e = new sjcl.bn('65537');\n \n return { n, e, phi, p, q };\n}\n\n// RSA encryption (simplified)\nfunction rsaEncrypt(message, publicKey) {\n const m = new sjcl.bn(message);\n return m.power(publicKey.e, publicKey.n);\n}\n\n// Usage\nconst keys = generateRSAComponents();\nconst message = 'deadbeef';\nconst encrypted = rsaEncrypt(message, { e: keys.e, n: keys.n });\n\nconsole.log('Original message:', message);\nconsole.log('Encrypted:', encrypted.toString());\n```\n\n### Discrete Logarithm Operations\n\nBig numbers in discrete logarithm cryptography:\n\n```javascript\nconst sjcl = require('sjcl');\n\n// Diffie-Hellman key exchange simulation\nfunction diffieHellmanExample() {\n // Public parameters (in real use, these would be much larger)\n const p = new sjcl.bn('23'); // Prime modulus\n const g = new sjcl.bn('5'); // Generator\n \n // Alice's private key\n const alicePrivate = new sjcl.bn('6');\n // Alice's public key: g^a mod p\n const alicePublic = g.power(alicePrivate, p);\n \n // Bob's private key\n const bobPrivate = new sjcl.bn('15');\n // Bob's public key: g^b mod p\n const bobPublic = g.power(bobPrivate, p);\n \n // Shared secret calculation\n // Alice computes: (Bob's public)^(Alice's private) mod p\n const aliceShared = bobPublic.power(alicePrivate, p);\n \n // Bob computes: (Alice's public)^(Bob's private) mod p\n const bobShared = alicePublic.power(bobPrivate, p);\n \n return {\n alicePublic: alicePublic.toString(),\n bobPublic: bobPublic.toString(),\n aliceShared: aliceShared.toString(),\n bobShared: bobShared.toString(),\n secretsMatch: aliceShared.equals(bobShared)\n };\n}\n\nconst dhResult = diffieHellmanExample();\nconsole.log('DH Exchange:', dhResult);\n```\n\n### Modular Arithmetic\n\nCommon modular arithmetic operations:\n\n```javascript\nconst sjcl = require('sjcl');\n\nclass ModularArithmetic {\n constructor(modulus) {\n this.modulus = new sjcl.bn(modulus);\n }\n \n // Modular addition\n addMod(a, b) {\n const aBN = new sjcl.bn(a);\n const bBN = new sjcl.bn(b);\n const sum = aBN.add(bBN);\n \n // Simple modular reduction (not constant-time)\n while (sum.greaterEquals(this.modulus)) {\n sum = sum.sub(this.modulus);\n }\n \n return sum;\n }\n \n // Modular multiplication\n mulMod(a, b) {\n const aBN = new sjcl.bn(a);\n const bBN = new sjcl.bn(b);\n const product = aBN.mul(bBN);\n \n // Simple modular reduction\n while (product.greaterEquals(this.modulus)) {\n product = product.sub(this.modulus);\n }\n \n return product;\n }\n \n // Modular exponentiation\n powMod(base, exp) {\n const baseBN = new sjcl.bn(base);\n const expBN = new sjcl.bn(exp);\n \n return baseBN.power(expBN, this.modulus);\n }\n}\n\n// Usage\nconst mod17 = new ModularArithmetic('17');\n\nconsole.log('5 + 15 mod 17 =', mod17.addMod('5', '15').toString()); // 3\nconsole.log('7 * 8 mod 17 =', mod17.mulMod('7', '8').toString()); // 5\nconsole.log('3^10 mod 17 =', mod17.powMod('3', '10').toString()); // 16\n```\n\n## Advanced Operations\n\n### Prime Testing\n\nBasic primality testing using big numbers:\n\n```javascript\nconst sjcl = require('sjcl');\n\nclass PrimalityTest {\n // Simple trial division (not cryptographically secure)\n static isSmallPrime(n) {\n const bn = new sjcl.bn(n);\n const two = new sjcl.bn('2');\n const three = new sjcl.bn('3');\n \n if (bn.equals(two) || bn.equals(three)) return true;\n \n // Check if divisible by 2\n const mod2 = bn.power(new sjcl.bn('1'), two);\n if (mod2.equals(new sjcl.bn('0'))) return false;\n \n // Check odd divisors up to sqrt(n)\n let divisor = new sjcl.bn('3');\n const limit = new sjcl.bn(Math.floor(Math.sqrt(parseInt(n.toString()))));\n \n while (divisor.greaterEquals(limit) === false) {\n // This is a simplified check - real implementation would use modular division\n divisor = divisor.add(two);\n }\n \n return true; // Simplified - real implementation needed\n }\n \n // Fermat primality test (probabilistic)\n static fermatTest(n, iterations = 5) {\n const nBN = new sjcl.bn(n);\n const one = new sjcl.bn('1');\n const nMinus1 = nBN.sub(one);\n \n for (let i = 0; i < iterations; i++) {\n // Choose random a in range [2, n-2]\n const a = new sjcl.bn('2').add(new sjcl.bn(Math.floor(Math.random() * 100)));\n \n // Check if a^(n-1) ≡ 1 (mod n)\n const result = a.power(nMinus1, nBN);\n \n if (!result.equals(one)) {\n return false; // Definitely composite\n }\n }\n \n return true; // Probably prime\n }\n}\n\n// Usage (simplified examples)\nconsole.log('17 is prime (Fermat):', PrimalityTest.fermatTest('17'));\nconsole.log('15 is prime (Fermat):', PrimalityTest.fermatTest('15')); // Should be false\n```\n\n### Number Theory Operations\n\nImplement common number theory operations:\n\n```javascript\nconst sjcl = require('sjcl');\n\nclass NumberTheory {\n // Greatest Common Divisor (Euclidean algorithm)\n static gcd(a, b) {\n let aBN = new sjcl.bn(a);\n let bBN = new sjcl.bn(b);\n const zero = new sjcl.bn('0');\n \n while (!bBN.equals(zero)) {\n const temp = bBN.copy();\n // In real implementation, we'd need modular division\n // This is simplified\n bBN = aBN; // Placeholder - real implementation needed\n aBN = temp;\n }\n \n return aBN;\n }\n \n // Least Common Multiple\n static lcm(a, b) {\n const aBN = new sjcl.bn(a);\n const bBN = new sjcl.bn(b);\n const gcdResult = NumberTheory.gcd(a, b);\n \n return aBN.mul(bBN); // Simplified - should divide by GCD\n }\n \n // Check if two numbers are coprime\n static areCoprime(a, b) {\n const gcdResult = NumberTheory.gcd(a, b);\n return gcdResult.equals(new sjcl.bn('1'));\n }\n}\n\n// Usage examples\nconst a = '48';\nconst b = '18';\n\nconsole.log(`gcd(${a}, ${b}) =`, NumberTheory.gcd(a, b).toString());\nconsole.log(`Are ${a} and ${b} coprime?`, NumberTheory.areCoprime(a, b));\n```\n\n## Performance Considerations\n\n1. **Operation Cost**: Multiplication and exponentiation are expensive\n2. **Memory Usage**: Large numbers consume significant memory\n3. **Algorithm Choice**: Use appropriate algorithms for different operations\n4. **Optimization**: Consider Montgomery multiplication for repeated modular operations\n5. **Bit Length**: Minimize bit lengths when possible\n\n## Security Considerations\n\n1. **Timing Attacks**: Big number operations are NOT constant-time\n2. **Side Channels**: Be aware of potential information leakage\n3. **Random Numbers**: Use secure random number generation for cryptographic applications\n4. **Implementation**: SJCL's big number implementation may not be side-channel resistant\n5. **Validation**: Always validate big number inputs and results\n\n## Common Use Cases\n\n1. **RSA Cryptography**: Modular exponentiation with large numbers\n2. **Elliptic Curves**: Field arithmetic for curve operations\n3. **Discrete Logarithms**: Diffie-Hellman and related protocols\n4. **Digital Signatures**: DSA and ECDSA signature schemes\n5. **Key Generation**: Creating cryptographic keys and parameters\n6. **Mathematical Proofs**: Zero-knowledge proofs and commitments