Skip to content

Pure Crystal implementations of various Cryptography algorithms

License

Notifications You must be signed in to change notification settings

protoncr/crypto

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Nov 16, 2023
d468d9e · Nov 16, 2023

History

25 Commits
Feb 24, 2020
Nov 16, 2023
Nov 16, 2023
Feb 22, 2020
Feb 23, 2020
Feb 22, 2020
Feb 22, 2020
Mar 1, 2021
Jan 19, 2021

Repository files navigation

Crypto Crystal

Specs

Pure Crystal port of pyrogram/tgcrpto. Implements various Cryptograpgy algorithms that are especially usefull for Telegram's MTPtoto protocol.

Installation

  1. Add the dependency to your shard.yml:

    dependencies:
      crypto:
        github: watzon/crypto
  2. Run shards install

API

module Crypto
  module AES
    def self.create_encryption_key(key : Bytes) : Slice(UInt32)
    def self.create_decryption_key(key : Bytes) : Slice(UInt32)
    def self.encrypt(data : Bytes, key : Indexable(UInt32)) : Bytes
    def self.decrypt(data : Bytes, key : Indexable(UInt32)) : Bytes
  end

  module CBC
    def self.encrypt(data : Bytes, key : Bytes, iv : Bytes) : Bytes
    def self.decrypt(data : Bytes, key : Bytes, iv : Bytes) : Bytes
  end

  module CTR
    def self.xcrypt(data : Bytes, key : Bytes, iv : Bytes, state : Bytes = [0_u8]) : Bytes
  end

  module IGE
    def self.encrypt(data : Bytes, key : Bytes, iv : Bytes) : Bytes
    def self.decrypt(data : Bytes, key : Bytes, iv : Bytes) : Bytes
  end

  module Padding
    def self.pkcs7(buffer : Bytes, block_size : Int)
  end
end

Usage

IGE Mode

Note: Data must be padded to match a multiple of the block size AES::BLOCK_SIZE.

require "crypto"

random = Random.new

# 10 MB of random data + 7 bytes to show padding
data = random.random_bytes(10 * 1024 * 1024 + 7)

key = random.random_bytes(32) # Random key
iv = random.random_bytes(32) # Random iv

# Pad the data using PKCS7
data = Crypto::Padding.pkcs7(data, Crypto::AES::BLOCK_SIZE)

encrypted = Crypto::IGE.encrypt(data, key, iv)
decrypted = Crypto::IGE.decrypt(encrypted, key, iv)

puts data == decrypted
# => true

CTR Mode

require "crypto"

random = Random.new

# 10 MB of random data + 7 bytes to show padding
data = random.random_bytes(10 * 1024 * 1024 + 7)

key = random.random_bytes(32) # Random key
iv = random.random_bytes(16) # Random iv

# Pad the data using PKCS7
data = Crypto::Padding.pkcs7(data, Crypto::AES::BLOCK_SIZE)

encrypted = Crypto::CTR.xcrypt(data, key, iv)
decrypted = Crypto::CTR.xcrypt(encrypted, key, iv)

puts data == decrypted

CBC Mode

Note: Data must be padded to match a multiple of the block size AES::BLOCK_SIZE.

require "crypto"

random = Random.new

# 10 MB of random data + 7 bytes to show padding
data = random.random_bytes(10 * 1024 * 1024 + 7)

key = random.random_bytes(32) # Random key
iv = random.random_bytes(16) # Random iv

# Pad the data using PKCS7
data = Crypto::Padding.pkcs7(data, Crypto::AES::BLOCK_SIZE)

encrypted = Crypto::CBC.encrypt(data, key, iv)
decrypted = Crypto::CBC.decrypt(encrypted, key, iv)

puts data == decrypted

Roadmap

  • Cipher Based
    • AES
      • 128
      • 192
      • 256
    • CBC
      • 128
      • 192
      • 256
    • CTR
      • 128
      • 192
      • 256
    • IGE
      • 128
      • 192
      • 256
  • Public Key Cryptography
    • RSA
  • Hashing
    • Blake
      • Blake2b
      • Blake2s
      • Blake3
      • Argon2
  • Key Derivation Functions
    • KDF
      • PBKDF2
  • More?

Contributing

  1. Fork it (https://github.com/watzon/crypto/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors