0
# Elliptic Curve Cryptography
1
2
SJCL provides comprehensive elliptic curve cryptography (ECC) implementation including ECDSA digital signatures, ECDH key agreement, and ElGamal encryption over multiple standard curves with complete key generation and cryptographic operations.
3
4
## Capabilities
5
6
### Available Curves
7
8
SJCL supports multiple standardized elliptic curves for different security and performance requirements.
9
10
```javascript { .api }
11
/**\n * NIST P-192 curve (192-bit security)\n */\nsjcl.ecc.curves.c192;\n\n/**\n * NIST P-224 curve (224-bit security)\n */\nsjcl.ecc.curves.c224;\n\n/**\n * NIST P-256 curve (256-bit security) - Most commonly used\n */\nsjcl.ecc.curves.c256;\n\n/**\n * NIST P-384 curve (384-bit security)\n */\nsjcl.ecc.curves.c384;\n\n/**\n * NIST P-521 curve (521-bit security) - Highest security\n */\nsjcl.ecc.curves.c521;\n\n/**\n * secp256k1 curve (Bitcoin/Ethereum curve)\n */\nsjcl.ecc.curves.k256;\n```\n\n**Usage Examples:**\n\n```javascript\nconst sjcl = require('sjcl');\n\n// Access different curves\nconst p256 = sjcl.ecc.curves.c256; // Most common\nconst p384 = sjcl.ecc.curves.c384; // Higher security\nconst secp256k1 = sjcl.ecc.curves.k256; // Bitcoin curve\n\n// Curve properties\nconsole.log('P-256 field size:', p256.field.modulus.toString());\nconsole.log('P-384 order:', p384.r.toString());\n```\n\n### ECDSA Digital Signatures\n\nElliptic Curve Digital Signature Algorithm for creating and verifying digital signatures.\n\n```javascript { .api }\n/**\n * Generate ECDSA key pair\n * @param {Curve} curve - Elliptic curve to use\n * @param {number} [paranoia] - Paranoia level for key generation\n * @returns {Object} Object with sec (private key) and pub (public key)\n */\nsjcl.ecc.ecdsa.generateKeys(curve, paranoia);\n\n/**\n * ECDSA private key constructor\n * @param {Curve} curve - Elliptic curve\n * @param {BitArray} exponent - Private key exponent\n */\nnew sjcl.ecc.ecdsa.secretKey(curve, exponent);\n\n/**\n * ECDSA public key constructor\n * @param {Curve} curve - Elliptic curve\n * @param {Point} point - Public key point\n */\nnew sjcl.ecc.ecdsa.publicKey(curve, point);\n```\n\n**ECDSA Private Key Methods:**\n\n```javascript { .api }\n/**\n * Sign data with ECDSA private key\n * @param {BitArray} hash - Hash of data to sign\n * @param {number} [paranoia] - Paranoia level for signature generation\n * @returns {BitArray} ECDSA signature\n */\nsjcl.ecc.ecdsa.secretKey.prototype.sign(hash, paranoia);\n```\n\n**ECDSA Public Key Methods:**\n\n```javascript { .api }\n/**\n * Verify ECDSA signature\n * @param {BitArray} hash - Hash of original data\n * @param {BitArray} signature - ECDSA signature to verify\n * @returns {boolean} True if signature is valid\n */\nsjcl.ecc.ecdsa.publicKey.prototype.verify(hash, signature);\n```\n\n**Usage Examples:**\n\n```javascript\nconst sjcl = require('sjcl');\n\n// Generate ECDSA key pair\nconst ecdsaKeys = sjcl.ecc.ecdsa.generateKeys(sjcl.ecc.curves.c256, 6);\nconst privateKey = ecdsaKeys.sec;\nconst publicKey = ecdsaKeys.pub;\n\n// Sign data\nconst message = \"Hello, ECDSA!\";\nconst messageHash = sjcl.hash.sha256.hash(message);\nconst signature = privateKey.sign(messageHash, 6);\n\nconsole.log('Signature:', sjcl.codec.hex.fromBits(signature));\n\n// Verify signature\nconst isValid = publicKey.verify(messageHash, signature);\nconsole.log('Signature valid:', isValid);\n\n// Try with different message (should fail)\nconst wrongHash = sjcl.hash.sha256.hash(\"Wrong message\");\nconst isWrongValid = publicKey.verify(wrongHash, signature);\nconsole.log('Wrong signature valid:', isWrongValid); // false\n```\n\n### ECDH Key Agreement\n\nElliptic Curve Diffie-Hellman for secure key agreement between parties.\n\n```javascript { .api }\n/**\n * Generate ECDH key pair\n * @param {Curve} curve - Elliptic curve to use\n * @param {number} [paranoia] - Paranoia level for key generation\n * @returns {Object} Object with sec (private key) and pub (public key)\n */\nsjcl.ecc.ecdh.generateKeys(curve, paranoia);\n\n/**\n * ECDH private key constructor\n * @param {Curve} curve - Elliptic curve\n * @param {BitArray} exponent - Private key exponent\n */\nnew sjcl.ecc.ecdh.secretKey(curve, exponent);\n\n/**\n * ECDH public key constructor\n * @param {Curve} curve - Elliptic curve\n * @param {Point} point - Public key point\n */\nnew sjcl.ecc.ecdh.publicKey(curve, point);\n```\n\n**ECDH Private Key Methods:**\n\n```javascript { .api }\n/**\n * Perform ECDH key agreement\n * @param {sjcl.ecc.ecdh.publicKey} publicKey - Other party's public key\n * @returns {BitArray} Shared secret\n */\nsjcl.ecc.ecdh.secretKey.prototype.dh(publicKey);\n```\n\n**Usage Examples:**\n\n```javascript\nconst sjcl = require('sjcl');\n\n// Alice generates key pair\nconst aliceKeys = sjcl.ecc.ecdh.generateKeys(sjcl.ecc.curves.c256, 6);\nconst alicePrivate = aliceKeys.sec;\nconst alicePublic = aliceKeys.pub;\n\n// Bob generates key pair\nconst bobKeys = sjcl.ecc.ecdh.generateKeys(sjcl.ecc.curves.c256, 6);\nconst bobPrivate = bobKeys.sec;\nconst bobPublic = bobKeys.pub;\n\n// Both parties compute shared secret\nconst aliceShared = alicePrivate.dh(bobPublic);\nconst bobShared = bobPrivate.dh(alicePublic);\n\n// Shared secrets should be identical\nconst secretsMatch = sjcl.bitArray.equal(aliceShared, bobShared);\nconsole.log('Shared secrets match:', secretsMatch);\n\n// Derive encryption key from shared secret\nconst sharedKey = sjcl.misc.hkdf(\n aliceShared, \n 256, \n null, \n sjcl.codec.utf8String.toBits(\"encryption-key\")\n);\n\nconsole.log('Derived key:', sjcl.codec.hex.fromBits(sharedKey));\n```\n\n### ElGamal Encryption\n\nElliptic curve ElGamal encryption for public key encryption.\n\n```javascript { .api }\n/**\n * Generate ElGamal key pair\n * @param {Curve} curve - Elliptic curve to use\n * @param {number} [paranoia] - Paranoia level for key generation\n * @returns {Object} Object with sec (private key) and pub (public key)\n */\nsjcl.ecc.elGamal.generateKeys(curve, paranoia);\n\n/**\n * ElGamal private key constructor\n * @param {Curve} curve - Elliptic curve\n * @param {BitArray} exponent - Private key exponent\n */\nnew sjcl.ecc.elGamal.secretKey(curve, exponent);\n\n/**\n * ElGamal public key constructor\n * @param {Curve} curve - Elliptic curve\n * @param {Point} point - Public key point\n */\nnew sjcl.ecc.elGamal.publicKey(curve, point);\n```\n\n**ElGamal Public Key Methods:**\n\n```javascript { .api }\n/**\n * Encrypt data with ElGamal public key\n * @param {BitArray} data - Data to encrypt (must fit in curve field)\n * @param {number} [paranoia] - Paranoia level for encryption\n * @returns {Object} Encryption result with c1 and c2 components\n */\nsjcl.ecc.elGamal.publicKey.prototype.encrypt(data, paranoia);\n```\n\n**ElGamal Private Key Methods:**\n\n```javascript { .api }\n/**\n * Decrypt ElGamal ciphertext\n * @param {Object} ciphertext - Encryption result from encrypt method\n * @returns {BitArray} Decrypted data\n */\nsjcl.ecc.elGamal.secretKey.prototype.decrypt(ciphertext);\n```\n\n**Usage Examples:**\n\n```javascript\nconst sjcl = require('sjcl');\n\n// Generate ElGamal key pair\nconst elGamalKeys = sjcl.ecc.elGamal.generateKeys(sjcl.ecc.curves.c256, 6);\nconst privateKey = elGamalKeys.sec;\nconst publicKey = elGamalKeys.pub;\n\n// Encrypt small data (must fit in curve field)\nconst plaintext = sjcl.codec.utf8String.toBits(\"Secret!\");\nconst shortData = sjcl.bitArray.clamp(plaintext, 200); // Ensure it fits\n\nconst encrypted = publicKey.encrypt(shortData, 6);\nconsole.log('Encrypted c1:', sjcl.codec.hex.fromBits(encrypted.c1));\nconsole.log('Encrypted c2:', sjcl.codec.hex.fromBits(encrypted.c2));\n\n// Decrypt data\nconst decrypted = privateKey.decrypt(encrypted);\nconst decryptedText = sjcl.codec.utf8String.fromBits(decrypted);\nconsole.log('Decrypted:', decryptedText);\n```\n\n## Point Operations\n\nDirect elliptic curve point manipulation for advanced use cases.\n\n```javascript { .api }\n/**\n * Elliptic curve point in affine coordinates\n * @param {Curve} curve - Elliptic curve\n * @param {BitArray} [x] - X coordinate\n * @param {BitArray} [y] - Y coordinate\n */\nnew sjcl.ecc.point(curve, x, y);\n\n/**\n * Elliptic curve point in Jacobian coordinates (more efficient)\n * @param {Curve} curve - Elliptic curve\n * @param {BitArray} [x] - X coordinate\n * @param {BitArray} [y] - Y coordinate\n * @param {BitArray} [z] - Z coordinate\n */\nnew sjcl.ecc.pointJac(curve, x, y, z);\n```\n\n**Point Methods:**\n\n```javascript { .api }\n/**\n * Add two points\n * @param {Point} point - Point to add\n * @returns {Point} Sum of points\n */\nsjcl.ecc.point.prototype.add(point);\n\n/**\n * Multiply point by scalar\n * @param {BitArray} scalar - Scalar multiplier\n * @returns {Point} Scaled point\n */\nsjcl.ecc.point.prototype.mult(scalar);\n\n/**\n * Double the point\n * @returns {Point} Doubled point\n */\nsjcl.ecc.point.prototype.doubl();\n\n/**\n * Check if point is valid on curve\n * @returns {boolean} True if point is on curve\n */\nsjcl.ecc.point.prototype.isValid();\n```\n\n**Usage Examples:**\n\n```javascript\nconst sjcl = require('sjcl');\n\n// Work with curve points\nconst curve = sjcl.ecc.curves.c256;\nconst generator = curve.G; // Generator point\n\n// Scalar multiplication\nconst scalar = sjcl.random.randomWords(8);\nconst point = generator.mult(scalar);\n\nconsole.log('Point valid:', point.isValid());\n\n// Point addition\nconst point2 = generator.mult(sjcl.random.randomWords(8));\nconst sum = point.add(point2);\n\nconsole.log('Sum valid:', sum.isValid());\n\n// Convert to affine coordinates\nconst affinePoint = point.toAffine();\nconsole.log('X coord:', affinePoint.x.toString());\nconsole.log('Y coord:', affinePoint.y.toString());\n```\n\n## Advanced ECC Operations\n\n### Key Serialization\n\nSerialize and deserialize ECC keys for storage and transmission:\n\n```javascript\nconst sjcl = require('sjcl');\n\n// Generate key pair\nconst keys = sjcl.ecc.ecdsa.generateKeys(sjcl.ecc.curves.c256, 6);\n\n// Serialize public key\nfunction serializePublicKey(publicKey) {\n const point = publicKey._point;\n const affine = point.toAffine();\n \n return {\n curve: 'c256', // You'd need to map curve to identifier\n x: sjcl.codec.hex.fromBits(affine.x.toBits()),\n y: sjcl.codec.hex.fromBits(affine.y.toBits())\n };\n}\n\n// Serialize private key (NEVER log or store unencrypted)\nfunction serializePrivateKey(privateKey) {\n return {\n curve: 'c256',\n d: sjcl.codec.hex.fromBits(privateKey._exponent.toBits())\n };\n}\n\n// Deserialize keys\nfunction deserializePublicKey(serialized) {\n const curve = sjcl.ecc.curves[serialized.curve];\n const x = curve.field.fromBits(sjcl.codec.hex.toBits(serialized.x));\n const y = curve.field.fromBits(sjcl.codec.hex.toBits(serialized.y));\n const point = new sjcl.ecc.point(curve, x, y);\n \n return new sjcl.ecc.ecdsa.publicKey(curve, point.toJac());\n}\n\n// Usage\nconst serializedPub = serializePublicKey(keys.pub);\nconst deserializedPub = deserializePublicKey(serializedPub);\n\n// Test serialization\nconst testHash = sjcl.hash.sha256.hash(\"test\");\nconst signature = keys.sec.sign(testHash);\nconst isValid = deserializedPub.verify(testHash, signature);\nconsole.log('Serialization test:', isValid);\n```\n\n### Multi-Signature Schemes\n\nImplement basic multi-signature functionality:\n\n```javascript\nconst sjcl = require('sjcl');\n\nclass MultiSig {\n constructor(curve, threshold, totalKeys) {\n this.curve = curve;\n this.threshold = threshold;\n this.totalKeys = totalKeys;\n this.keys = [];\n }\n \n generateKeys() {\n for (let i = 0; i < this.totalKeys; i++) {\n const keyPair = sjcl.ecc.ecdsa.generateKeys(this.curve, 6);\n this.keys.push(keyPair);\n }\n return this.keys.map(k => k.pub); // Return public keys\n }\n \n signMessage(message, keyIndices) {\n if (keyIndices.length < this.threshold) {\n throw new Error('Insufficient signatures');\n }\n \n const hash = sjcl.hash.sha256.hash(message);\n const signatures = [];\n \n keyIndices.forEach(index => {\n if (index < this.keys.length) {\n const signature = this.keys[index].sec.sign(hash, 6);\n signatures.push({ index, signature });\n }\n });\n \n return { hash, signatures };\n }\n \n verifyMultiSig(message, multiSig) {\n const hash = sjcl.hash.sha256.hash(message);\n \n if (!sjcl.bitArray.equal(hash, multiSig.hash)) {\n return false;\n }\n \n if (multiSig.signatures.length < this.threshold) {\n return false;\n }\n \n return multiSig.signatures.every(sig => {\n const publicKey = this.keys[sig.index].pub;\n return publicKey.verify(hash, sig.signature);\n });\n }\n}\n\n// Usage\nconst multiSig = new MultiSig(sjcl.ecc.curves.c256, 2, 3); // 2-of-3\nconst publicKeys = multiSig.generateKeys();\n\nconst message = \"Transfer 100 BTC to Alice\";\nconst signed = multiSig.signMessage(message, [0, 1]); // Sign with first 2 keys\nconst isValid = multiSig.verifyMultiSig(message, signed);\n\nconsole.log('Multi-signature valid:', isValid);\n```\n\n### Curve Comparison\n\n| Curve | Security Level | Key Size | Performance | Use Case |\n|-------|---------------|----------|-------------|----------|\n| P-192 | 96-bit | 192-bit | Fastest | Legacy systems |\n| P-224 | 112-bit | 224-bit | Fast | Embedded systems |\n| P-256 | 128-bit | 256-bit | Good | General purpose |\n| P-384 | 192-bit | 384-bit | Moderate | High security |\n| P-521 | 256-bit | 521-bit | Slowest | Maximum security |\n| secp256k1 | 128-bit | 256-bit | Good | Blockchain/Bitcoin |\n\n## Security Recommendations\n\n1. **Curve Selection**: Use P-256 for general purpose, P-384+ for high security\n2. **Key Generation**: Use high paranoia levels (6-8) for key generation\n3. **Hash Functions**: Use SHA-256 or SHA-512 for signatures\n4. **Private Key Protection**: Never expose or log private keys\n5. **Signature Verification**: Always verify signatures before trusting data\n6. **Random Numbers**: Ensure good entropy for all random operations\n7. **Key Reuse**: Generate fresh keys for each use case when possible\n\n## Common Use Cases\n\n1. **Digital Signatures**: Document signing, software verification\n2. **Key Agreement**: Secure communication channel establishment\n3. **Authentication**: Prove identity without passwords\n4. **Blockchain**: Cryptocurrency transactions and smart contracts\n5. **TLS/SSL**: Web security and certificate validation\n6. **IoT Security**: Lightweight cryptography for devices