CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sjcl

Stanford JavaScript Crypto Library providing comprehensive cryptographic operations including AES encryption, hash functions, key derivation, and elliptic curve cryptography.

Pending
Overview
Eval results
Files

elliptic-curve-cryptography.mddocs/

Elliptic Curve Cryptography

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.

Capabilities

Available Curves

SJCL supports multiple standardized elliptic curves for different security and performance requirements.

/**\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

Install with Tessl CLI

npx tessl i tessl/npm-sjcl

docs

big-number-arithmetic.md

bit-array-utilities.md

cipher-modes.md

data-encoding.md

elliptic-curve-cryptography.md

hash-functions.md

high-level-encryption.md

index.md

key-derivation.md

key-exchange.md

message-authentication.md

random-number-generation.md

symmetric-encryption.md

tile.json