Posted 10 April 2019 - 12:59 AM
Hey it's me again. I'm back with another approach to public key cryptography, elliptic curve cryptography. ECC has smaller keys and is faster than RSA and regular Diffie-Hellman. This API implements the ECDH key exchange, EdDSA-like digital signatures, a pseudorandom byte generator as well as authenticated symmetric cryptography.
You can convert between strings and arrays:
Generates a key pair from a seed. You mustn't use the seed for anything else (nor its hash), since the information can be used to reconstruct your private key.
seed can be either a string or a byte array.
privateKey is a byte array.
publicKey is a byte array.
Examples:
Deterministic key pair from passphrase:
sharedSecret = ecc.exchange(privateKey, publicKey)
Exchanges two keys to derive a shared secret from a private and a public key. See Diffie-Hellman key exchange.
privateKey can be either a string or a byte array.
publicKey can be either a string or a byte array.
sharedSecret is a byte array.
Example:
signature = ecc.sign(privateKey, message)
Signs a message.
privateKey can be either a string or a byte array.
message can be either a string or a byte array.
signature is a byte array.
valid = ecc.verify(publicKey, message, signature)
Verifies if a signed message is valid.
publicKey can be either a string or a byte array.
message can be either a string or a byte array.
signature can be either a string or a byte array.
valid is a boolean.
Example:
Encrypts a message with a symmetric key.
message can be either a string or a byte array.
key can be either a string or a byte array.
ciphertext is a byte array.
message = ecc.decrypt(ciphertext, key)
Decrypts a message with a symmetric key.
ciphertext can be either a string or a byte array.
key can be either a string or a byte array.
message is a byte array.
Returns 32 random bytes.
rand is a byte array.
ecc.random.seed()
Adds custom data to the entropy pool.
ecc.random.save()
Saves the state into /.random (which is added to the entropy pool every time the API is loaded).
Authenticated Encryption - Proper Usage of Encryption
Authenticated Encryption means only messages that have been encrypted with the key will be decrypted without an error in the decryption function, this means messages cannot be modified when intercepted (regular symmetric encryption does not grant this).
Replay Attacks
Authenticated encryption preventing modifying ciphertexts doesn't mean an attacker can't send a valid ciphertext twice or delay a sent ciphertext for some time. This can lead to undesirable consequences such as a second bank transfer or a delay in a message to a door lock program. Protection against replay attacks require more intricate APIs that deal with sending messages directly and other things such as nonces, timestamps or counters. Replay attack protection is outside of the scope of this API.
Other Functions
Finally, the API also includes (and makes use of) Anavrins' ChaCha20 and SHA-256.
Download
Note: you must either use dofile or require when loading the API.
Pastebin: ZGJGBJdg
Byte Array Format
Tables in the byte array format ("byte arrays") are tables containing numbers from 0 to 255.You can convert between strings and arrays:
t1 = {72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33}
s1 = string.char(unpack(t1))
print(s1) -- Hello World!
And back:
s1 = "Hello World!"
t1 = {s1:byte(1, -1)}
Elliptic Curve Functions Usage
privateKey, publicKey = ecc.keypair(seed)Generates a key pair from a seed. You mustn't use the seed for anything else (nor its hash), since the information can be used to reconstruct your private key.
seed can be either a string or a byte array.
privateKey is a byte array.
publicKey is a byte array.
Examples:
Deterministic key pair from passphrase:
passphrase = read("*")
privateKey, publicKey = ecc.keypair(passphrase)
Random key pair from random.random:
privateKey, publicKey = ecc.keypair(ecc.random.random())
sharedSecret = ecc.exchange(privateKey, publicKey)
Exchanges two keys to derive a shared secret from a private and a public key. See Diffie-Hellman key exchange.
privateKey can be either a string or a byte array.
publicKey can be either a string or a byte array.
sharedSecret is a byte array.
Example:
sk1, pk1 = keypair(ecc.random.random())
sk2, pk2 = keypair(ecc.random.random())
ss1 = ecc.exchange(sk1, pk2)
ss2 = ecc.exchange(sk2, pk1)
ss1 and ss2 will be the same.signature = ecc.sign(privateKey, message)
Signs a message.
privateKey can be either a string or a byte array.
message can be either a string or a byte array.
signature is a byte array.
valid = ecc.verify(publicKey, message, signature)
Verifies if a signed message is valid.
publicKey can be either a string or a byte array.
message can be either a string or a byte array.
signature can be either a string or a byte array.
valid is a boolean.
Example:
sk, pk = ecc.keypair(ecc.random.random())
sig = ecc.sign(sk, "Hello world!")
valid1 = ecc.verify(pk, "Hello world!", sig)
valid2 = ecc.verify(pk, "Hello wrld!", sig)
valid1 should be true and valid2 should be false.Authenticated Encryption Usage
ciphertext = ecc.encrypt(message, key)Encrypts a message with a symmetric key.
message can be either a string or a byte array.
key can be either a string or a byte array.
ciphertext is a byte array.
message = ecc.decrypt(ciphertext, key)
Decrypts a message with a symmetric key.
ciphertext can be either a string or a byte array.
key can be either a string or a byte array.
message is a byte array.
Random Usage
rand = ecc.random.random()Returns 32 random bytes.
rand is a byte array.
ecc.random.seed()
Adds custom data to the entropy pool.
ecc.random.save()
Saves the state into /.random (which is added to the entropy pool every time the API is loaded).
Authenticated Encryption - Proper Usage of Encryption
Authenticated Encryption means only messages that have been encrypted with the key will be decrypted without an error in the decryption function, this means messages cannot be modified when intercepted (regular symmetric encryption does not grant this).
Replay Attacks
Authenticated encryption preventing modifying ciphertexts doesn't mean an attacker can't send a valid ciphertext twice or delay a sent ciphertext for some time. This can lead to undesirable consequences such as a second bank transfer or a delay in a message to a door lock program. Protection against replay attacks require more intricate APIs that deal with sending messages directly and other things such as nonces, timestamps or counters. Replay attack protection is outside of the scope of this API.
Other Functions
Finally, the API also includes (and makes use of) Anavrins' ChaCha20 and SHA-256.
Download
Note: you must either use dofile or require when loading the API.
Pastebin: ZGJGBJdg
Edited on 24 April 2019 - 11:04 PM