This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
skizzerz's profile picture

[1.33-1.41] crypt API v0.2 - Encryption, Hashing, and Random Number Generation

Started by skizzerz, 05 October 2012 - 04:13 AM
skizzerz #1
Posted 05 October 2012 - 06:13 AM
Encryption library for ComputerCraft. Please note that many of these library functions are very slow, and should only be used when you actually have a need for cryptographically secure data to be stored in your Minecraft world.

Notes
This API is not yet complete, implemented functions/types are denoted with "+" and unimplemented functions/types are denoted with "-". No guarantees are made that unimplemented functions will be implemented in a future version, and the functions and algorithms available may change over time.

This API is currently only functional in 1.33-1.41 (and possibly earlier versions if they include the bit library), the version 0.3 update will bring compatibility with 1.42+ where the bit.tobits and bit.tonumb functions are removed.

Function parameters wrapped in [] indicate that the parameter is optional. All of the function prototypes below assume that the library is installed as "crypt".

Downloads
It is highly recommended that you download this file if possible as opposed to copying it by-hand into the ComputerCraft terminal, as the file is quite large and will only get larger.

Current Version (0.2)
http://pastebin.com/8T1Vh18R

Older Versions
No older versions available.

Installation
To install this as a default API, download the file and place it into ComputerCraft's /lua/rom/apis directory (name it "crypt" without an extension). To install this on a single computer, download the file to that computer, name it "crypt" without an extension, and load it via os.loadAPI() in your program. The crypt API does not have any additional dependencies beyond what is included in a default ComputerCraft installation.

Cryptographic functions
  • -crypt.encrypt(cipher, key, data[, mode[, iv]]) - Encrypt's data with the given cipher and key. Please see below for which ciphers are available. In the event that you choose a block cipher (such as AES), you will need to specify mode as well. Finally, if you choose a cipher that requires some sort of Initialization Vector (IV), you will need to pass this in the iv parameter. If you are not making use of either mode or iv, you may omit these parameters from the function call.
  • -crypt.decrypt(cipher, key, data[, mode], iv]]) - Decrypt's data with the given cipher and key. Please ensure that if you are using a symmetric encryption algorithm that you use the same key used to encrypt the data in order to decrypt it. If you are using an asymmetric encryption algorithm, it should be the opposite key than what was used to encrypt (e.g. if the public key was used to encrypt, decrypt with the private key, and if the private key was used to encrypt, decrypt with the public key).
  • +crypt.hash(hashtype, data) - Computes the hash of data using the given hashtype. Hashing is a one-way process, and as such cannot be reversed.
  • -crypt.hmac(hashtype, key, data) - Compute the Hash-based message authentication code (HMAC) for the provided data using the given hashtype and key. Like hash, HMAC is a one-way process.

Utility functions
  • +crypt.getVersionInt() - Returns the version number of the installed library
  • +crypt.getVersionStr() - Returns the version string of the installed library
  • +crypt.rand([raw][, userdata]) - Returns a random number using the algorithm 1 described in FIPS 186-2 Change Notice 1, and as modified by the "General Purpose Random Number Generation" section in the same change notice. This algorithm is a Cryptographic Pseudorandom Number Generator, and as such is only as secure as the initial seed. The default seed if none is provided is computed as sha1((os.computerID() + os.time() + os.clock()) * 10000) for a 160-bit seed. If you can figure out a way to collect additional entropy for the default seed or can suggest something that is harder to brute force the entire set of seeds on, please let me know so that I can improve this generation. Two optional parameters for this function are raw and userdata; both are optional and may be passed independently of each other (e.g. you can call rand and pass just userdata and not raw). raw is a boolean that defaults to false. If false, the returned random number is a 32-bit integer. If true, the returned random number is a bit array containing 320 bits (the bit array is in the same order that the function bit.tobits() would produce). The 32-bit integer is the least significant 32 bits of this 320 bit array. The other parameter userdata can be passed to add additional entropy to the algorithm for a particular random number (it is the XSEEDj parameter as defined in step 3.1 of the algorithm pseudocode in the linked paper).
  • +crypt.srand(int) - Seed the random number generator with the given integer. Internally, the SHA-1 hash of the passed integer is taken in order to ensure that the seed is 160 bits.

Ciphers
Symmetric encryption ("secret key")
  • -crypt.symmetric.aes128 - 128-bit AES (Advanced Encryption Standard/RIJNDAEL)
  • -crypt.symmetric.aes192 - 192-bit AES
  • -crypt.symmetric.aes256 - 256-bit AES
  • -crypt.symmetric.tripledes - Triple DES (Data Encryption Standard)

Asymmetric encryption ("public/private key")
  • -crypt.asymmetric.rsa - RSA
  • -crypt.asymmetric.dsa - DSA

Modes (applies only to block ciphers, such as AES)
  • -crypt.mode.ecb - ECB (Electronic Codebook)
  • -crypt.mode.cbc - CBC (Cipher Block-chaining)

Hashtypes
  • -crypt.hashtype.md5 - MD5 hash
  • +crypt.hashtype.sha1 - SHA-1 hash
  • -crypt.hashtype.sha256 - SHA-2 hash with 256-bit output
  • -crypt.hashtype.sha512 - SHA-2 hash with 512-bit output

Changelog
  • 0.2: First version released to public. Implemented rand and srand according to FIPS 186-2, algorithm 1 of the change notice as modified by "General Purpose Random Number Generation".
  • 0.1: Implemented SHA-1 hash function.

License
Copyright © 2012, Ryan Schmidt
All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Cloudy #2
Posted 05 October 2012 - 11:08 AM
It is worth pointing out that bit.tonumb and bit.tobits are removed in the next version, since you can now do bit operations directly on numbers - and the bit API is now implemented in Java (and as such will be a lot quicker).
skizzerz #3
Posted 05 October 2012 - 04:11 PM
Cool, that should make things a tiny bit easier, although I'll still need to figure out a way to handle storage of large integers since the max integer size in lua is 52 bits (internally all numbers are represented as doubles, and the mantissa is 52 bits wide), and I need to be doing operations on bit sizes much larger than that for many of these calculations, but I am looking forward to faster bit operations as it would mean the ability to do more per cycle; perhaps if something is really really slow I could see about spawning it in a background thread and having the current thread block until the op is done but I'd rather not go there unless absolutely necessary.

I'll have to grab 1.42 (curently using technic pack/tekkit hence older version) and play around with that to get a port, but I'll update the title for the time being indicating it is currently 1.33 only.
gmt2001 #4
Posted 12 October 2012 - 01:00 PM
Cool, that should make things a tiny bit easier, although I'll still need to figure out a way to handle storage of large integers since the max integer size in lua is 52 bits (internally all numbers are represented as doubles, and the mantissa is 52 bits wide), and I need to be doing operations on bit sizes much larger than that for many of these calculations
Here is a link to a lua script that should allow you to have a number of arbitrary size
http://oss.digirati.com.br/luabignum/
CoolisTheName007 #5
Posted 25 November 2012 - 01:29 PM
What would you do to ensure that B, via broadcasting, informs A of it's existence and certifies itself as belonging to the same permission group as A, without enabling malevolent computer C to do the same? (C knows both the ID's and general programs that A and B are running, but A and B can share a private key previously set)
Take in account that an efficient algorithm is preferred.
This should be enough to allow for extremely safe transmissions in dynamic networks (see LyqydNet) , if you trust the routers in between.