Rivest–Shamir–Adleman (RSA) cryptosystem in Luau

Rivest–Shamir–Adleman

An implementation of RSA, a safe public-key cryptosystem for data transmission using a public key to encrypt and a private one to decrypt. Its security relies on the difficulty of factoring large primes, known as the RSA problem which has not be solved yet.


Includes

Implementation

In order to implement this asset, download the model or use require. Check if the asset is the original one and insert it to your place. A simple example is provided here:

local RSA = require(11287199148) -- Or reference a ModuleScript
n, e, d = RSA.newKeys()
encrypted = RSA.crypt(n, 242351, e)
decrypted = RSA.crypt(n, encrypted, d)
print(decrypted[1]) -- Expected output: 242351

A correct use of this algorithm is to keep the primes and private key secret, as well as all the processes must be done in the server. Do not use this for bulk encryption/decryption, as the algorithm is relatively slow; you might be looking for a symmetric-key one.

Information

This module includes 4 utilities:

  1. Key generator generates the key pairs with a given bit length (default 256), or given p, q and e (optional). Returns 8 bigInts:
Value
Default
Description
n Product of p and q. Can be released
e 3 or 65537 Public key. Used to encrypt data
d Secret private key. Used to decrypt data

The next ones are used only with CRT optimization, which allows computing modular exponentiation more efficiently and sent as part of the private key.

Value
Default
Description
p p input Source prime number
q q input Source prime number
d_p
d_q
q_inv
  1. Encryption and Decryption uses modular exponentiation properties to get the message. Text must be in the range [0;n>. If e is short or pair is suitable then encryption is fast. For optimized decryption, CRT mode should be used.
  2. Signature verification verifies the signature with the hash of the decrypted message. Notice that to sign a message you should use encryption function and this does not include a hash one.
  3. Data type conversion between bigInt and bytes. Since RSA usually works with large primes, Luau native numbers cannot handle correctly them. This function brings an easier form to convert files to bigInts and vice versa so files (such as numbers and strings) can be encrypted. Notice that padding is not included.

bigInts can be automatically converted from strings and numbers. For strings, they are notated as decimal (default), binary (base-2, beginning with 0b) or hexadecimal (base-16, beginning with 0x), in big-endian and underscores can be used. Usually using binary or hexadecimal notations are faster to convert.

Performance

The algorithm has been benchmarked with an Intel® Core™ i7-1065G7 @ 1.30GHz processor with a 16 GB RAM. e = 65537 for encryption was used.

Key size
Generation av. time Encryption av. time CRT decryption av. time
32 bits 0.0085 0.0002 0.0005
64 bits 0.0446 0.0007 0.0014
128 bits (16 bytes) 0.2325 0.0018 0.0161
256 bits (32 bytes) 2.6018 0.0145 0.0864
384 bits (48 bytes) 4.6809 0.0148 0.2283
512 bits (1/4 def. gen.) ~40 0.0619 1.5326

As seen above, bigInt calculus takes more time to compute, especially pow function. However, compared to other libraries, this is relatively faster since this was built for Luau, both key generation and decryption using optimization. Rest times can be used to prevent crashes, at the cost of time.


How do you rate this asset?
  • Great and useful
  • Great
  • Good
  • Needs improvements

0 voters

Should I make more crypto libraries?
  • Yes (which one?)
  • No

0 voters

Thanks for the feedback and your support!

23 Likes

What are the use cases of cryptography in roblox

1 Like

I’m guessing this is used for encrypting? For example “mypassword” > 37294 etc.

This is insanely cool (I tried making this once it did not go well)

Could you create in-depth docs for how to use this?

1 Like

Very cool resource, good work!

1 Like

I cannot specify the context where you have to use encryption. But could be used to give extra-protection to secret information or files users have in your games.

The documentation stated above mention how to use this library correctly!

By nature
if you have to encrypt a file
your doing it wrong

1 Like

I can think of one use-case;

Say you have an admin system and when you press like \ to do the hidden commands you could encrypt those to make those SUPER secret. (preventing remove event spy thingy hacky)

1 Like

Security through obsurity is like putting a key under your doormat
not a good idea

2 Likes

Horrible use case. the only valid use case i know so far is to learn/educate

1 Like

This is a use case:

It will also be added to a new model I’m making. More info on that coming soon!

Teleport data seems like the only use case for this, but this is quite nice to include.

Use case is using RSA256 to sign JSON Web Tokens in server → server context (you cannot imagine how grateful I am to find this at midnight after thinking I had to ditch a project because managing Roblox → OAuth2 → endpoint is a huge pain) [at least provided, I’m doing this correctly]

7 Likes

I have one that I’m working on right now. It’s to encrypt data between the client and the server to prevent Remote Spy from getting any information that an exploiter can use. This is, of course, above and beyond the standard practice of securing remotes on the server.

1 Like

How would one use this with raw binary data?

I managed to make this work with strings by converting them into numbers, possibly you could do the same.

Will you add padding to this eventually?

Is there a module that allows the reverse of this to be true, allowing the data to be encrypted with the private key and decrypted with the public key?

very cool module, thank you for sharing

1 Like

Will there be higher key sizes support? Can you use this to make an E2EE (End to end encrypted) chat for AES key exchange?