IMPORT_EXAMPLE.md (11689B)
1 # Importing Crypto Library in Other Apps 2 3 This document shows how to import and use the crypto library from other LuajitOS applications. 4 5 ## Quick Start 6 7 ### Step 1: Update Your Manifest 8 9 Add `import` and `run` permissions to your app's `manifest.lua`: 10 11 ```lua 12 return { 13 name = "myapp", 14 developer = "mydev", 15 version = "1.0.0", 16 entry = "src/init.lua", 17 mode = "cli", -- or "gui" 18 permissions = { 19 "stdio", 20 "import", -- Required to import from other apps 21 "run" -- Required to run the crypto app 22 } 23 } 24 ``` 25 26 ### Step 2: Import Crypto in Your Code 27 28 In your `src/init.lua`: 29 30 ```lua 31 -- Run the crypto app to initialize exports 32 run("crypto") 33 34 -- Import the crypto library 35 local cryptoApp = apps["com.luajitos.crypto"] 36 if not cryptoApp then 37 print("Error: crypto app not found") 38 return 39 end 40 41 local crypto = cryptoApp:call("crypto") 42 if not crypto then 43 print("Error: failed to import crypto library") 44 return 45 end 46 47 -- Now you can use all crypto functions! 48 local hash = crypto.SHA256("Hello World") 49 50 -- Convert binary hash to hex for display 51 local function toHex(data) 52 local hex = "" 53 for i = 1, #data do 54 hex = hex .. string.format("%02x", string.byte(data, i)) 55 end 56 return hex 57 end 58 59 print("SHA256 hash: " .. toHex(hash)) 60 ``` 61 62 ## Complete Examples 63 64 ### Example 1: Simple Hash Calculator 65 66 ```lua 67 -- com.mydev.hashcalc/manifest.lua 68 return { 69 name = "hashcalc", 70 developer = "mydev", 71 version = "1.0.0", 72 entry = "src/init.lua", 73 mode = "cli", 74 permissions = {"stdio", "import", "run"} 75 } 76 77 -- com.mydev.hashcalc/src/init.lua 78 run("crypto") 79 local crypto = apps["com.luajitos.crypto"]:call("crypto") 80 81 local function toHex(data) 82 local hex = "" 83 for i = 1, #data do 84 hex = hex .. string.format("%02x", string.byte(data, i)) 85 end 86 return hex 87 end 88 89 local data = args[1] or "test" 90 91 print("Input: " .. data) 92 print("MD5: " .. toHex(crypto.MD5(data))) 93 print("SHA1: " .. toHex(crypto.SHA1(data))) 94 print("SHA256: " .. toHex(crypto.SHA256(data))) 95 print("BLAKE2b: " .. toHex(crypto["BLAKE2b-256"](data))) 96 ``` 97 98 Usage: `hashcalc "hello world"` 99 100 ### Example 2: Password Manager 101 102 ```lua 103 -- com.mydev.pwdmgr/manifest.lua 104 return { 105 name = "pwdmgr", 106 developer = "mydev", 107 version = "1.0.0", 108 entry = "src/init.lua", 109 mode = "cli", 110 permissions = {"stdio", "import", "run", "filesystem"} 111 } 112 113 -- com.mydev.pwdmgr/src/init.lua 114 run("crypto") 115 local crypto = apps["com.luajitos.crypto"]:call("crypto") 116 117 local function toHex(data) 118 local hex = "" 119 for i = 1, #data do 120 hex = hex .. string.format("%02x", string.byte(data, i)) 121 end 122 return hex 123 end 124 125 local function fromHex(hex) 126 local binary = "" 127 for i = 1, #hex, 2 do 128 local byte = tonumber(hex:sub(i, i+1), 16) 129 binary = binary .. string.char(byte) 130 end 131 return binary 132 end 133 134 -- Hash a password with a random salt 135 local function hashPassword(password) 136 local salt = crypto.generateSalt() 137 local hash = crypto.PBKDF2(password, salt, 100000, 32) 138 139 return { 140 salt = toHex(salt), 141 hash = toHex(hash) 142 } 143 end 144 145 -- Verify a password against stored hash 146 local function verifyPassword(password, salt_hex, hash_hex) 147 local salt = fromHex(salt_hex) 148 local stored_hash = fromHex(hash_hex) 149 local computed_hash = crypto.PBKDF2(password, salt, 100000, 32) 150 151 return computed_hash == stored_hash 152 end 153 154 -- Example usage 155 print("Password Manager Example") 156 print("") 157 158 -- Hash a password 159 local password = "MySecurePassword123" 160 print("Hashing password: " .. password) 161 local result = hashPassword(password) 162 print("Salt: " .. result.salt) 163 print("Hash: " .. result.hash) 164 print("") 165 166 -- Verify correct password 167 print("Verifying correct password...") 168 if verifyPassword(password, result.salt, result.hash) then 169 print("✓ Password verified!") 170 else 171 print("✗ Password verification failed") 172 end 173 174 -- Verify wrong password 175 print("") 176 print("Verifying wrong password...") 177 if verifyPassword("WrongPassword", result.salt, result.hash) then 178 print("✓ Password verified!") 179 else 180 print("✗ Password verification failed (expected)") 181 end 182 ``` 183 184 Usage: `pwdmgr` 185 186 ### Example 3: Digital Signature Tool 187 188 ```lua 189 -- com.mydev.signer/manifest.lua 190 return { 191 name = "signer", 192 developer = "mydev", 193 version = "1.0.0", 194 entry = "src/init.lua", 195 mode = "cli", 196 permissions = {"stdio", "import", "run"} 197 } 198 199 -- com.mydev.signer/src/init.lua 200 run("crypto") 201 local crypto = apps["com.luajitos.crypto"]:call("crypto") 202 203 local function toHex(data) 204 local hex = "" 205 for i = 1, #data do 206 hex = hex .. string.format("%02x", string.byte(data, i)) 207 end 208 return hex 209 end 210 211 print("Ed25519 Digital Signature Tool") 212 print("") 213 214 -- Generate keypair 215 print("Generating Ed25519 keypair...") 216 local pubkey, privkey = crypto.sign.Ed25519.keypair() 217 print("Public Key: " .. toHex(pubkey)) 218 print("Private Key: " .. toHex(privkey)) 219 print("") 220 221 -- Sign a message 222 local message = "This is a signed message" 223 print("Signing message: " .. message) 224 local signature = crypto.sign.Ed25519.sign(message, privkey) 225 print("Signature: " .. toHex(signature)) 226 print("") 227 228 -- Verify signature 229 print("Verifying signature...") 230 local valid = crypto.sign.Ed25519.verify(message, signature, pubkey) 231 if valid then 232 print("✓ Signature is VALID") 233 else 234 print("✗ Signature is INVALID") 235 end 236 print("") 237 238 -- Try to verify tampered message 239 local tampered = "This is a tampered message" 240 print("Verifying tampered message: " .. tampered) 241 local valid2 = crypto.sign.Ed25519.verify(tampered, signature, pubkey) 242 if valid2 then 243 print("✓ Signature is VALID") 244 else 245 print("✗ Signature is INVALID (expected)") 246 end 247 ``` 248 249 Usage: `signer` 250 251 ### Example 4: Key Exchange Demo 252 253 ```lua 254 -- com.mydev.keyexchange/manifest.lua 255 return { 256 name = "keyexchange", 257 developer = "mydev", 258 version = "1.0.0", 259 entry = "src/init.lua", 260 mode = "cli", 261 permissions = {"stdio", "import", "run"} 262 } 263 264 -- com.mydev.keyexchange/src/init.lua 265 run("crypto") 266 local crypto = apps["com.luajitos.crypto"]:call("crypto") 267 268 local function toHex(data) 269 local hex = "" 270 for i = 1, #data do 271 hex = hex .. string.format("%02x", string.byte(data, i)) 272 end 273 return hex 274 end 275 276 print("X25519 Diffie-Hellman Key Exchange Demo") 277 print("") 278 279 -- Alice generates her keypair 280 print("Alice generates keypair...") 281 local alice_pub, alice_priv = crypto.keyExchange.X25519.keypair() 282 print("Alice's public key: " .. toHex(alice_pub)) 283 print("Alice's private key: " .. toHex(alice_priv):sub(1, 32) .. "...") 284 print("") 285 286 -- Bob generates his keypair 287 print("Bob generates keypair...") 288 local bob_pub, bob_priv = crypto.keyExchange.X25519.keypair() 289 print("Bob's public key: " .. toHex(bob_pub)) 290 print("Bob's private key: " .. toHex(bob_priv):sub(1, 32) .. "...") 291 print("") 292 293 -- Alice computes shared secret using her private key and Bob's public key 294 print("Alice computes shared secret...") 295 local alice_shared = crypto.keyExchange.X25519.sharedSecret(alice_priv, bob_pub) 296 print("Alice's shared secret: " .. toHex(alice_shared)) 297 print("") 298 299 -- Bob computes shared secret using his private key and Alice's public key 300 print("Bob computes shared secret...") 301 local bob_shared = crypto.keyExchange.X25519.sharedSecret(bob_priv, alice_pub) 302 print("Bob's shared secret: " .. toHex(bob_shared)) 303 print("") 304 305 -- Verify they match 306 if alice_shared == bob_shared then 307 print("✓ Shared secrets match! Secure channel established.") 308 else 309 print("✗ Shared secrets don't match! Something went wrong.") 310 end 311 ``` 312 313 Usage: `keyexchange` 314 315 ## Available Crypto Functions 316 317 Once you import the crypto library, you have access to: 318 319 ### Hashing 320 - `crypto.MD5(data)` → 16 bytes 321 - `crypto.SHA1(data)` → 20 bytes 322 - `crypto.SHA256(data)` → 32 bytes 323 - `crypto.SHA512(data)` → 64 bytes 324 - `crypto["SHA3-256"](data)` → 32 bytes 325 - `crypto["SHA3-512"](data)` → 64 bytes 326 - `crypto["BLAKE2b-256"](data)` → 32 bytes 327 - `crypto["BLAKE2b-512"](data)` → 64 bytes 328 - `crypto.CRC32(data)` → 4 bytes 329 330 ### Key Derivation 331 - `crypto.PBKDF2(password, salt, iterations, keylen)` → keylen bytes 332 - `crypto.Argon2id(password, salt)` → 32 bytes 333 - `crypto.generateSalt()` → 32 bytes 334 335 ### Digital Signatures (Ed25519) 336 - `crypto.sign.Ed25519.keypair()` → (pubkey, privkey) 337 - `crypto.sign.Ed25519.sign(data, privkey)` → signature (64 bytes) 338 - `crypto.sign.Ed25519.verify(data, signature, pubkey)` → boolean 339 340 ### Key Exchange (X25519) 341 - `crypto.keyExchange.X25519.keypair()` → (pubkey, privkey) 342 - `crypto.keyExchange.X25519.publicKey(privkey)` → pubkey 343 - `crypto.keyExchange.X25519.sharedSecret(privkey, pubkey)` → shared_secret (32 bytes) 344 345 ### Random Generation 346 - `crypto.random(bytes)` → random data 347 - `crypto.newKey(bytes)` → random key 348 349 ## Helper Functions 350 351 You'll often need these helper functions to convert between binary and hex: 352 353 ```lua 354 -- Convert binary data to hex string 355 local function toHex(data) 356 if not data then return "nil" end 357 local hex = "" 358 for i = 1, #data do 359 hex = hex .. string.format("%02x", string.byte(data, i)) 360 end 361 return hex 362 end 363 364 -- Convert hex string to binary data 365 local function fromHex(hex) 366 if not hex then return nil end 367 hex = hex:gsub("%s+", "") -- Remove whitespace 368 if #hex % 2 ~= 0 then 369 return nil, "Hex string must have even length" 370 end 371 local binary = "" 372 for i = 1, #hex, 2 do 373 local byte = tonumber(hex:sub(i, i+1), 16) 374 if not byte then 375 return nil, "Invalid hex character at position " .. i 376 end 377 binary = binary .. string.char(byte) 378 end 379 return binary 380 end 381 ``` 382 383 ## Best Practices 384 385 1. **Always check if import succeeded** 386 ```lua 387 local crypto = apps["com.luajitos.crypto"]:call("crypto") 388 if not crypto then 389 print("Error: Failed to import crypto") 390 return 391 end 392 ``` 393 394 2. **Store keys securely** 395 - Use the filesystem permission to save keys to `$/data/` 396 - Never hardcode keys in your source code 397 - Use proper key derivation (PBKDF2/Argon2id) for passwords 398 399 3. **Use appropriate hash functions** 400 - **Passwords**: Use PBKDF2 or Argon2id (with salt and high iterations) 401 - **File integrity**: Use SHA256 or BLAKE2b 402 - **Quick checksums**: Use CRC32 (not cryptographically secure) 403 404 4. **Handle binary data correctly** 405 - All crypto functions return binary data 406 - Use `toHex()` or base64 encoding for storage/display 407 - Use `fromHex()` or base64 decoding when loading keys 408 409 5. **Understand key sizes** 410 - Ed25519: 32-byte public key, 64-byte private key 411 - X25519: 32-byte keys 412 - PBKDF2/Argon2id: Configurable output length 413 - Random/keys: Specify desired byte count 414 415 ## Troubleshooting 416 417 ### "Error: crypto app not found" 418 - Make sure you have the `run` permission in your manifest 419 - The crypto app must be installed at `/apps/com.luajitos.crypto/` 420 421 ### "Error: failed to import crypto library" 422 - Make sure you have the `import` permission in your manifest 423 - Ensure you ran `run("crypto")` before trying to import 424 425 ### "Attempt to access undefined global: crypto" 426 - The crypto library must be imported, it's not automatically available 427 - Follow the import steps above 428 429 ### Binary data looks garbled 430 - Crypto functions return binary data, not strings 431 - Always use `toHex()` or base64 encoding to display binary data 432 433 ## Notes 434 435 - The crypto library is already available globally in the sandbox, but importing via the crypto app provides a consistent interface 436 - All cryptographic operations are performed in C for performance 437 - The import mechanism ensures the crypto app is loaded before use 438 - Multiple apps can import crypto simultaneously without conflicts