Skip to main content

A Python encryption library implemented in Rust. It supports AEAD with various ciphers. It uses multiple providers to handle encryption.

Project description

rencrypt

PyPI version CI

[!WARNING] This crate hasn't been audited, but it's mostly a wrapper over several libs like ring (well known and audited library),RustCrypto (AES-GCM and ChaCha20Poly1305 ciphers are audited) but also others which are NOT audited, so in principle at least the primitives should offer a similar level of security.

A Python encryption library implemented in Rust. It supports AEAD with varius ciphers. It uses ring, RustCrypto (and derivates), sodiumoxide and orion to handle encryption. If offers slightly higher speed compared to other Python libs, especially for small chunks of data (especially the Ring provider with AES-GCM ciphers). The API also tries to be easy to use but it's more optimized for speed than usability.

So if you want to use a vast variaety of ciphers and/or achieve the highest possible encryption speed, consider giving it a try.

Benchmark

Some benchmarks comparing it to PyFLocker which from my benchmarks is the fastest among other Python libs like cryptography, NaCl (libsodium), PyCryptodome.

Buffer in memory

This is useful when you keep a buffer, set your plaintext/ciphertext in there, and then encrypt/decrypt in-place in that buffer. This is the most performant way to use it, because it does't copy any bytes nor allocate new memory. rencrypt is faster on small buffers, less than few MB, PyFLocker is comming closer for larger buffers.

Encrypt seconds Encrypt buffer

Decrypt seconds Decrypt buffer

Block size and duration in seconds

MB rencrypt
encrypt
PyFLocker
encrypt
rencrypt
decrypt
PyFLocker
decrypt
0.03125 0.00001 0.00091 0.00001 0.00004
0.0625 0.00001 0.00005 0.00001 0.00004
0.125 0.00002 0.00005 0.00003 0.00005
0.25 0.00004 0.00008 0.00005 0.00009
0.5 0.00010 0.00014 0.00011 0.00015
1 0.00021 0.00024 0.00021 0.00029
2 0.00043 0.00052 0.00044 0.00058
4 0.00089 0.00098 0.00089 0.00117
8 0.00184 0.00190 0.00192 0.00323
16 0.00353 0.00393 0.00367 0.00617
32 0.00678 0.00748 0.00749 0.01348
64 0.01361 0.01461 0.01460 0.02697
128 0.02923 0.03027 0.03134 0.05410
256 0.06348 0.06188 0.06136 0.10417
512 0.11782 0.13463 0.12090 0.21114
1024 0.25001 0.24953 0.25377 0.42581

File

Encrypt seconds Encrypt file

Decrypt seconds Decrypt buffer

File size and duration in seconds

MB rencrypt
encrypt
PyFLocker
encrypt
rencrypt
decrypt
PyFLocker
decrypt
0.031251 0.00010 0.00280 0.00004 0.00479
0.062501 0.00009 0.00218 0.00005 0.00143
0.125 0.00020 0.00212 0.00014 0.00129
0.25 0.00034 0.00232 0.00020 0.00165
0.5 0.00050 0.00232 0.00035 0.00181
1 0.00087 0.00356 0.00065 0.00248
2 0.00215 0.00484 0.00154 0.00363
4 0.00361 0.00765 0.00301 0.00736
8 0.00688 0.01190 0.00621 0.00876
16 0.01503 0.02097 0.01202 0.01583
32 0.02924 0.03642 0.02563 0.02959
64 0.05737 0.06473 0.04431 0.05287
128 0.11098 0.12646 0.08944 0.09926
256 0.22964 0.24716 0.17402 0.19420
512 0.43506 0.46444 0.38143 0.38242
1024 0.97147 0.95803 0.78137 0.87363
2048 2.07143 2.10766 1.69471 2.99210
4096 4.85395 4.69722 5.40580 8.73779
8192 10.76984 11.76741 10.29253 21.00636
16384 21.84490 26.27385 39.56230 43.55530

Hardware used in benchmarks

Laptop LG Gram 17Z90Q
SSD: 1 TB M.2 NVMe SSD (Samsung PM9A1) – 2x M.2 2280 slots
CPU: 12th Gen Intel(R) Core(TM) i7-1260P
CPU ID: GenuineIntel,6,154,3
CPU Architecture: x86_64
CPUs Online: 16
CPUs Available: 16
CPU Sibling Cores: [0-15]
CPU Sibling Threads: [0-1], [2-3], [4-5], [6-7], [8], [9], [10], [11], [12], [13], [14], [15]
Total Memory: 33.4 GB LPDDR5 5200 MHz
Linux Kernel Version: 6.9.5-1-MANJARO

Usage

There are two ways in which you can use the lib, the first one is a bit faster, the second offers a bit more flexible way to use it sacrificing a bit of performance.

  1. With a buffer in memory: using seal_in_place()/open_in_place(), is useful when you keep a buffer (or have it from somewhere), set your plaintext/ciphertext in there, and then encrypt/decrypt in-place in that buffer. This is the most performant way to use it, because it does't copy any bytes nor allocate new memory. The buffer has to be a numpy array, so that it's easier for you to collect data with slices that reference to underlying data. This is because the whole buffer needs to be the size of ciphertext (which is plaintext_len + tag_len + nonce_len) but you may pass a slice of the buffer to a BufferedReader to read_into() the plaintext. If you can directly collect the data to that buffer, like BufferedReader.read_into(), this is the preffered way to go.
  2. From some bytes into the buffer: using seal_in_place_from()/open_in_place_from(), when you have some arbitrary data that you want to work with. It will first copy those bytes to the buffer then do the operation in-place in the buffer. This is a bit slower, especially for large data, because it first needs to copy the bytes to the buffer.

block_index, aad and nonce are optional.

If nonce is not provided, on each encrypt operation (seal_in_place*()) it will generate a cryptographically secure random nonce using ChaCha20. You can also provide your own nonce, there is an example below.

Security

  • The total number of invocations of the encryption functions (seal_in_place*()) shall not exceed 2^32, including all nonce lengths and all instances of Cipher with the given key. Following this guideline, only 4,294,967,296 messages with random nonces can be encrypted under a given key. While this bound is high, it's possible to encounter in practice, and systems which might reach it should consider alternatives to purely random nonces, like a counter or a combination of a random nonce + counter.
  • When encrypting more than one block you should provide block_index as it's more secure because it ensures the order of the blocks was not changed in ciphertext.
  • When you encrypt files it's more secure to generate a random number per file and include that in AAD, this will prevent ciphertext blocks from being swapped between files.
  • For security reasons it's a good practice to lock the memory with mlock() in which you keep sensitive data like passwords or encrryption keys, or any other plaintext sensitive content. Also it's important to zeroize the data when not used anymore.
  • In the case of Copy-on-write fork you need to zeroize the memory before forking the child process.

In the examples below you will see how to do it.

Encryption providers and algorithms (ciphers)

You will notice in the examples we create the Cipher from something like this cipher_meta = CipherMeta.Ring(RingAlgorithm.Aes256Gcm). The first part CipherMeta.Ring is the encryption provider. The last part is the algorithm for that provider, in this case Aes256Gcm. Each provier might expose specific algorithms.

Providers

enum CipherMeta {
    Ring { alg: RingAlgorithm },
    RustCrypto { alg: RustCryptoAlgorithm },
    Sodiumoxide { alg: SodiumoxideAlgorithm },
    Orion { alg: OrionAlgorithm },
}
  • Ring: Based on ring crate. ring is focused on the implementation, testing, and optimization of a core set of cryptographic operations exposed via an easy-to-use (and hard-to-misuse) API. ring exposes a Rust API and is written in a hybrid of Rust, C, and assembly language. Particular attention is being paid to making it easy to build and integrate ring into applications and higher-level frameworks, and to ensuring that ring works optimally on small devices, and eventually microcontrollers, to support Internet of Things (IoT) applications. Most of the C and assembly language code in ring comes from BoringSSL, and BoringSSL is derived from OpenSSL. ring merges changes from BoringSSL regularly. Also, several changes that were developed for ring have been contributed to and integrated into BoringSSL.
  • RustCrypto: Based on RustCrypto collection of Authenticated Encryption with Associated Data (AEAD) algorithms written in pure Rust. AEADs are high-level symmetric encryption primitives which defend against a wide range of potential attacks (i.e. IND-CCA3).
  • Sodiumoxide: Based on sodiumoxide crate which aims to provide a type-safe and efficient Rust binding that's just as easy to use. NaCl (pronounced "salt") is a new easy-to-use high-speed software library for network communication, encryption, decryption, signatures, etc. NaCl's goal is to provide all of the core operations needed to build higher-level cryptographic tools. Of course, other libraries already exist for these core operations. NaCl advances the state of the art by improving security, by improving usability, and by improving speed. Sodium is a portable, cross-compilable, installable, packageable fork of NaCl (based on the latest released upstream version nacl-20110221), with a compatible API.
  • Orion: Based on orion crate. Written in pure Rust, it aims to provide easy and usable crypto while trying to minimize the use of unsafe code. You can read more about Orion in the wiki.

Algorithms

enum RingAlgorithm {
    ChaCha20Poly1305,
    Aes128Gcm,
    Aes256Gcm,
}
enum RustCryptoAlgorithm {
    ChaCha20Poly1305,
    XChaCha20Poly1305,
    Aes128Gcm,
    Aes256Gcm,
    Aes128GcmSiv,
    Aes256GcmSiv,
    Aes128Siv,
    Aes256Siv,
    Ascon128,
    Ascon128a,
    Ascon80pq,
    DeoxysI128,
    DeoxysI256,
    DeoxysII128,
    DeoxysII256,
    Aes128Eax,
    Aes256Eax,
}
enum SodiumoxideAlgorithm {
    ChaCha20Poly1305,
    ChaCha20Poly1305Ietf,
    XChaCha20Poly1305Ietf,
}
enum OrionAlgorithm {
    ChaCha20Poly1305,
    XChaCha20Poly1305,
}

Audited

Only for Aes128Gcm, Aes256Gcm and ChaCha20Poly1305 with Ring and RustCrypto providers underlying crates have been audited.

  • Aes128Gcm/Aes256Gcm: If you have hardware acceleration ( e.g. AES-NI), then AES-GCM provides better performance. If you do not have a hardware acceleration, AES-GCM is either slower than ChaCha20Poly1305, or it leaks your encryption keys in cache timing. With RustCrypto provider the underlying aes-gcm has received one security audit by NCC Group, with no significant findings. With Ring provider the underlying ring crate was also audited.
  • ChaCha20Poly1305: Is notable for being simple and fast when implemented in pure software. The underlying ChaCha20 stream cipher uses a simple combination of add, rotate, and XOR instructions (a.k.a. "ARX"), and the Poly1305 hash function is likewise extremely simple. With RustCrypto provider the underlying chacha20poly1305 has received one security audit by NCC Group, with no significant findings. With Ring provider the underlying ring crtate was also audited. If you do not have a hardware acceleration, ChaCha20Poly1305 is faster than AES-GCM. While it hasn't received approval from certain standards bodies (i.e. NIST) the algorithm is widely used and deployed. Notably it's mandatory to implement in the Transport Layer Security (TLS) protocol. The underlying ChaCha20 cipher is also widely used as a cryptographically secure random number generator, including internal use by the Rust standard library.
  • XChaCha20Poly1305: A variant of ChaCha20Poly1305 with an extended 192-bit (24-byte) nonce.

Not audited

USE AT YOUR OWN RISK!

  • Aes128GcmSiv / Aes256GcmSiv: Provides nonce reuse misuse resistance. Suitable as a general purpose symmetric encryption cipher, AES-GCM-SIV also removes many of the "sharp edges" of AES-GCM, providing significantly better security bounds while simultaneously eliminating the most catastrophic risks of nonce reuse that exist in AES-GCM. Decryption performance is equivalent to AES-GCM. Encryption is marginally slower.
  • Aes128Siv / Aes256Siv: Cipher which also provides nonce reuse misuse resistance.
  • Ascon128 / Ascon128a / Ascon80pq: Designed to be lightweight and easy to implement, even with added countermeasures against side-channel attacks. Ascon has been selected as new standard for lightweight cryptography in the NIST Lightweight Cryptography competition (2019–2023). Ascon has also been selected as the primary choice for lightweight authenticated encryption in the final portfolio of the CAESAR competition ( 2014–2019).
  • Deoxys: Based on a 128-bit lightweight ad-hoc tweakable block cipher. It may be used in two modes to handle nonce-respecting users (Deoxys-I) or nonce-reusing user (Deoxys-II). Deoxys-II has been selected as first choice for the "in-depth security" portfolio of the CAESAR competition.
  • Aes128Eax / Aes256Eax: Designed with a two-pass scheme, one pass for achieving privacy and one for authenticity for each block. EAX mode was submitted on October 3, 2003, to the attention of NIST in order to replace CCM as standard AEAD mode of operation, since CCM mode lacks some desirable attributes of EAX and is more complex.
  • For Sodiumoxide provider ChaCha20Poly1305: The original ChaCha20-Poly1305 construction can safely encrypt a pratically unlimited number of messages with the same key, without any practical limit to the size of a message (up to ~ 2^64 bytes).
  • For Sodiumoxide provider ChaChaCha20Poly1305Ietf: The IETF variant of the ChaCha20-Poly1305 construction can safely encrypt a practically unlimited number of messages, but individual messages cannot exceed 64*(2^32)-64 bytes (approximatively 256 GB).

Examples

You can see more in examples directory and in bench.py which has some benchmarks. Here are few simple examples:

Encrypt and decrypt with a buffer in memory

seal_in_place()/open_in_place()

This is the most performant way to use it as it will not copy bytes to the buffer nor allocate new memory for plaintext and ciphertext.

from rencrypt import Cipher, CipherMeta, RingAlgorithm
import os
from zeroize import zeroize1, mlock, munlock
import numpy as np
import platform


def setup_memory_limit():
    if not platform.system() == "Windows":
        return

    import ctypes
    from ctypes import wintypes

    # Define the Windows API functions
    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

    GetCurrentProcess = kernel32.GetCurrentProcess
    GetCurrentProcess.restype = wintypes.HANDLE

    SetProcessWorkingSetSize = kernel32.SetProcessWorkingSetSize
    SetProcessWorkingSetSize.restype = wintypes.BOOL
    SetProcessWorkingSetSize.argtypes = [wintypes.HANDLE, ctypes.c_size_t, ctypes.c_size_t]

    # Get the handle of the current process
    current_process = GetCurrentProcess()

    # Set the working set size
    min_size = 6 * 1024 * 1024  # Minimum working set size
    max_size = 10 * 1024 * 1024  # Maximum working set size

    result = SetProcessWorkingSetSize(current_process, min_size, max_size)

    if not result:
        error_code = ctypes.get_last_error()
        error_message = ctypes.FormatError(error_code)
        raise RuntimeError(f"SetProcessWorkingSetSize failed with error code {error_code}: {error_message}")


if __name__ == "__main__":
    try:
        setup_memory_limit()

        # You can use also other algorithms like cipher_meta = CipherMeta.Ring(RingAlgorithm.ChaCha20Poly1305)`.
        cipher_meta = CipherMeta.Ring(RingAlgorithm.Aes256Gcm)
        key_len = cipher_meta.key_len()
        key = bytearray(key_len)
        # for security reasons we lock the memory of the key so it won't be swapped to disk
        mlock(key)
        cipher_meta.generate_key(key)
        # The key is copied and the input key is zeroized for security reasons.
        # The copied key will also be zeroized when the object is dropped.
        cipher = Cipher(cipher_meta, key)
        # it was zeroized we can unlock it
        munlock(key)

        # we create a buffer based on plaintext block len of 4096
        # the actual buffer needs to be a bit larger as the ciphertext also includes the tag and nonce
        plaintext_len = 4096
        ciphertext_len = cipher_meta.ciphertext_len(plaintext_len)
        buf = np.array([0] * ciphertext_len, dtype=np.uint8)
        # for security reasons we lock the memory of the buffer so it won't be swapped to disk, because it contains plaintext after decryption
        mlock(buf)

        aad = b"AAD"

        # put some plaintext in the buffer, it would be ideal if you can directly collect the data into the buffer without allocating new memory
        # but for the sake of example we will allocate and copy the data
        plaintext = bytearray(os.urandom(plaintext_len))
        # for security reasons we lock the memory of the plaintext so it won't be swapped to disk
        mlock(plaintext)
        # cipher.copy_slice is slighlty faster than buf[:plaintext_len] = plaintext, especially for large plaintext, because it copies the data in parallel
        # cipher.copy_slice takes bytes as input, cipher.copy_slice1 takes bytearray
        cipher.copy_slice(plaintext, buf)
        # encrypt it, this will encrypt in-place the data in the buffer
        print("encrypting...")
        ciphertext_len = cipher.seal_in_place(buf, plaintext_len, 42, aad)
        cipertext = buf[:ciphertext_len]
        # you can do something with the ciphertext

        # decrypt it
        # if you need to copy ciphertext to buffer, we don't need to do it now as it's already in the buffer
        # cipher.copy_slice(ciphertext, buf[:len(ciphertext)])
        print("decrypting...")
        plaintext_len = cipher.open_in_place(buf, ciphertext_len, 42, aad)
        plaintext2 = buf[:plaintext_len]
        # for security reasons we lock the memory of the plaintext so it won't be swapped to disk
        mlock(plaintext2)
        assert plaintext == plaintext2

    finally:
        # best practice, you should always zeroize the plaintext and keys after you are done with it (key will be zeroized when the enc object is dropped)
        zeroize1(plaintext)
        zeroize1(buf)

        munlock(buf)
        munlock(plaintext)

        print("bye!")

You can use other ciphers like cipher_meta = CipherMeta.Ring(RingAlgorithm.ChaCha20Poly1305).

You can also provide your own nonce that you can generate based on your contraints.

from rencrypt import Cipher, CipherMeta, RingAlgorithm
import os
from zeroize import zeroize1, mlock, munlock
import numpy as np
import platform


def setup_memory_limit():
    if not platform.system() == "Windows":
        return

    import ctypes
    from ctypes import wintypes

    # Define the Windows API functions
    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

    GetCurrentProcess = kernel32.GetCurrentProcess
    GetCurrentProcess.restype = wintypes.HANDLE

    SetProcessWorkingSetSize = kernel32.SetProcessWorkingSetSize
    SetProcessWorkingSetSize.restype = wintypes.BOOL
    SetProcessWorkingSetSize.argtypes = [wintypes.HANDLE, ctypes.c_size_t, ctypes.c_size_t]

    # Get the handle of the current process
    current_process = GetCurrentProcess()

    # Set the working set size
    min_size = 6 * 1024 * 1024  # Minimum working set size
    max_size = 10 * 1024 * 1024  # Maximum working set size

    result = SetProcessWorkingSetSize(current_process, min_size, max_size)

    if not result:
        error_code = ctypes.get_last_error()
        error_message = ctypes.FormatError(error_code)
        raise RuntimeError(f"SetProcessWorkingSetSize failed with error code {error_code}: {error_message}")


if __name__ == "__main__":
    try:
        setup_memory_limit()

        # You can use also other algorithms like cipher_meta = CipherMeta.Ring(RingAlgorithm.ChaCha20Poly1305)`.
        cipher_meta = CipherMeta.Ring(RingAlgorithm.Aes256Gcm)
        key_len = cipher_meta.key_len()
        key = bytearray(key_len)
        # for security reasons we lock the memory of the key so it won't be swapped to disk
        mlock(key)
        cipher_meta.generate_key(key)
        # The key is copied and the input key is zeroized for security reasons.
        # The copied key will also be zeroized when the object is dropped.
        cipher = Cipher(cipher_meta, key)
        # it was zeroized we can unlock it
        munlock(key)

        # we create a buffer based on plaintext block len of 4096
        # the actual buffer needs to be a bit larger as the ciphertext also includes the tag and nonce
        plaintext_len = 4096
        ciphertext_len = cipher_meta.ciphertext_len(plaintext_len)
        buf = np.array([0] * ciphertext_len, dtype=np.uint8)
        # for security reasons we lock the memory of the buffer so it won't be swapped to disk, because it contains plaintext after decryption
        mlock(buf)

        aad = b"AAD"
        # create our own nonce
        nonce = os.urandom(cipher_meta.nonce_len())

        # put some plaintext in the buffer, it would be ideal if you can directly collect the data into the buffer without allocating new memory
        # but for the sake of example we will allocate and copy the data
        plaintext = bytearray(os.urandom(plaintext_len))
        # for security reasons we lock the memory of the plaintext so it won't be swapped to disk
        mlock(plaintext)
        # cipher.copy_slice is slighlty faster than buf[:plaintext_len] = plaintext, especially for large plaintext, because it copies the data in parallel
        # cipher.copy_slice takes bytes as input, cipher.copy_slice1 takes bytearray
        cipher.copy_slice(plaintext, buf)
        # encrypt it, this will encrypt in-place the data in the buffer
        print("encrypting...")
        ciphertext_len = cipher.seal_in_place(buf, plaintext_len, 42, aad, nonce)
        cipertext = buf[:ciphertext_len]
        # you can do something with the ciphertext

        # decrypt it
        # if you need to copy ciphertext to buffer, we don't need to do it now as it's already in the buffer
        # cipher.copy_slice(ciphertext, buf[:len(ciphertext)])
        print("decrypting...")
        plaintext_len = cipher.open_in_place(buf, ciphertext_len, 42, aad, nonce)
        plaintext2 = buf[:plaintext_len]
        # for security reasons we lock the memory of the plaintext so it won't be swapped to disk
        mlock(plaintext2)
        assert plaintext == plaintext2

    finally:
        # best practice, you should always zeroize the plaintext and keys after you are done with it (key will be zeroized when the enc object is dropped)
        zeroize1(plaintext)
        zeroize1(buf)

        munlock(buf)
        munlock(plaintext)

        print("bye!")

Encrypt and decrypt a file

import errno
import io
import os
from pathlib import Path
import shutil
from rencrypt import Cipher, CipherMeta, RingAlgorithm
import hashlib
from zeroize import zeroize1, mlock, munlock
import numpy as np
import platform


def setup_memory_limit():
    if not platform.system() == "Windows":
        return

    import ctypes
    from ctypes import wintypes

    # Define the Windows API functions
    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

    GetCurrentProcess = kernel32.GetCurrentProcess
    GetCurrentProcess.restype = wintypes.HANDLE

    SetProcessWorkingSetSize = kernel32.SetProcessWorkingSetSize
    SetProcessWorkingSetSize.restype = wintypes.BOOL
    SetProcessWorkingSetSize.argtypes = [wintypes.HANDLE, ctypes.c_size_t, ctypes.c_size_t]

    # Get the handle of the current process
    current_process = GetCurrentProcess()

    # Set the working set size
    min_size = 6 * 1024 * 1024  # Minimum working set size
    max_size = 10 * 1024 * 1024  # Maximum working set size

    result = SetProcessWorkingSetSize(current_process, min_size, max_size)

    if not result:
        error_code = ctypes.get_last_error()
        error_message = ctypes.FormatError(error_code)
        raise RuntimeError(f"SetProcessWorkingSetSize failed with error code {error_code}: {error_message}")


def read_file_in_chunks(file_path, buf):
    with open(file_path, "rb") as file:
        buffered_reader = io.BufferedReader(file, buffer_size=len(buf))
        while True:
            read = buffered_reader.readinto(buf)
            if read == 0:
                break
            yield read


def hash_file(file_path):
    hash_algo = hashlib.sha256()
    with open(file_path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_algo.update(chunk)
    return hash_algo.hexdigest()


def compare_files_by_hash(file1, file2):
    return hash_file(file1) == hash_file(file2)


def silentremove(filename):
    try:
        os.remove(filename)
    except OSError as e:  # this would be "except OSError, e:" before Python 2.6
        if e.errno != errno.ENOENT:  # errno.ENOENT = no such file or directory
            raise  # re-raise exception if a different error occurred


def create_directory_in_home(dir_name):
    # Get the user's home directory
    home_dir = Path.home()

    # Create the full path for the new directory
    new_dir_path = home_dir / dir_name

    # Create the directory
    try:
        new_dir_path.mkdir(parents=True, exist_ok=True)
    except Exception as e:
        print(f"Error creating directory: {e}")

    return new_dir_path.absolute().__str__()


def create_file_with_size(file_path_str, size_in_bytes):
    with open(file_path_str, "wb") as f:
        for _ in range((size_in_bytes // 4096) + 1):
            f.write(os.urandom(min(4096, size_in_bytes)))
        f.flush()


def delete_dir(path):
    if os.path.exists(path):
        shutil.rmtree(path)
    else:
        print(f"Directory {path} does not exist.")


if __name__ == "__main__":
    try:
        setup_memory_limit()

        tmp_dir = create_directory_in_home("rencrypt_tmp")
        fin = tmp_dir + "/" + "fin"
        fout = tmp_dir + "/" + "fout.enc"
        create_file_with_size(fin, 1 * 1024 * 1024)

        chunk_len = 256 * 1024

        # You can use also other algorithms like cipher_meta = CipherMeta.Ring(RingAlgorithm.ChaCha20Poly1305)`.
        cipher_meta = CipherMeta.Ring(RingAlgorithm.Aes256Gcm)
        key_len = cipher_meta.key_len()
        key = bytearray(key_len)
        # for security reasons we lock the memory of the key so it won't be swapped to disk
        mlock(key)
        cipher_meta.generate_key(key)
        # The key is copied and the input key is zeroized for security reasons.
        # The copied key will also be zeroized when the object is dropped.
        cipher = Cipher(cipher_meta, key)
        # it was zeroized we can unlock it
        munlock(key)

        plaintext_len = chunk_len
        ciphertext_len = cipher_meta.ciphertext_len(plaintext_len)
        buf = np.array([0] * ciphertext_len, dtype=np.uint8)
        mlock(buf)

        # use some random per file in additional authenticated data to prevent blocks from being swapped between files
        aad = os.urandom(16)

        # encrypt
        print("encrypting...")
        with open(fout, "wb", buffering=plaintext_len) as file_out:
            i = 0
            for read in read_file_in_chunks(fin, buf[:plaintext_len]):
                ciphertext_len = cipher.seal_in_place(buf, read, i, aad)
                file_out.write(buf[:ciphertext_len])
                i += 1
            file_out.flush()

        # decrypt
        print("decrypting...")
        tmp = fout + ".dec"
        with open(tmp, "wb", buffering=plaintext_len) as file_out:
            i = 0
            for read in read_file_in_chunks(fout, buf):
                plaintext_len2 = cipher.open_in_place(buf, read, i, aad)
                file_out.write(buf[:plaintext_len2])
                i += 1
            file_out.flush()

        assert compare_files_by_hash(fin, tmp)

        delete_dir(tmp_dir)

    finally:
        # best practice, you should always zeroize the plaintext and keys after you are done with it (key will be zeroized when the enc object is dropped)
        # buf will containt the last block plaintext so we need to zeroize it
        zeroize1(buf)

        munlock(buf)

    print("bye!")

Encrypt and decrypt from some bytes into the buffer

encrypt_from()/decrypt_from()

This is a bit slower than handling data only via the buffer, especially for large plaintext, but there are situations when you can't directly collect the data to the buffer but have some data from somewhere else.

from rencrypt import Cipher, CipherMeta, RingAlgorithm
import os
from zeroize import zeroize1, mlock, munlock
import numpy as np
import platform


def setup_memory_limit():
    if not platform.system() == "Windows":
        return

    import ctypes
    from ctypes import wintypes

    # Define the Windows API functions
    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

    GetCurrentProcess = kernel32.GetCurrentProcess
    GetCurrentProcess.restype = wintypes.HANDLE

    SetProcessWorkingSetSize = kernel32.SetProcessWorkingSetSize
    SetProcessWorkingSetSize.restype = wintypes.BOOL
    SetProcessWorkingSetSize.argtypes = [wintypes.HANDLE, ctypes.c_size_t, ctypes.c_size_t]

    # Get the handle of the current process
    current_process = GetCurrentProcess()

    # Set the working set size
    min_size = 6 * 1024 * 1024  # Minimum working set size
    max_size = 10 * 1024 * 1024  # Maximum working set size

    result = SetProcessWorkingSetSize(current_process, min_size, max_size)

    if not result:
        error_code = ctypes.get_last_error()
        error_message = ctypes.FormatError(error_code)
        raise RuntimeError(f"SetProcessWorkingSetSize failed with error code {error_code}: {error_message}")


if __name__ == "__main__":
    try:
        setup_memory_limit()

        # You can use also other algorithms like cipher_meta = CipherMeta.Ring(RingAlgorithm.ChaCha20Poly1305)`.
        cipher_meta = CipherMeta.Ring(RingAlgorithm.Aes256Gcm)
        key_len = cipher_meta.key_len()
        key = bytearray(key_len)
        # for security reasons we lock the memory of the key so it won't be swapped to disk
        mlock(key)
        cipher_meta.generate_key(key)
        # The key is copied and the input key is zeroized for security reasons.
        # The copied key will also be zeroized when the object is dropped.
        cipher = Cipher(cipher_meta, key)
        # it was zeroized we can unlock it
        munlock(key)

        # we create a buffer based on plaintext block len of 4096
        # the actual buffer needs to be a bit larger as the ciphertext also includes the tag and nonce
        plaintext_len = 4096
        ciphertext_len = cipher_meta.ciphertext_len(plaintext_len)
        buf = np.array([0] * ciphertext_len, dtype=np.uint8)
        # for security reasons we lock the memory of the buffer so it won't be swapped to disk, because it contains plaintext after decryption
        mlock(buf)

        aad = b"AAD"

        plaintext = bytearray(os.urandom(plaintext_len))
        # for security reasons we lock the memory of the plaintext so it won't be swapped to disk
        mlock(plaintext)

        # encrypt it, after this will have the ciphertext in the buffer
        print("encrypting...")
        ciphertext_len = cipher.seal_in_place_from(plaintext, buf, 42, aad)
        cipertext = bytes(buf[:ciphertext_len])

        # decrypt it
        print("decrypting...")
        plaintext_len = cipher.open_in_place_from(cipertext, buf, 42, aad)
        plaintext2 = buf[:plaintext_len]
        # for security reasons we lock the memory of the plaintext so it won't be swapped to disk
        mlock(plaintext2)
        assert plaintext == plaintext2

    finally:
        # best practice, you should always zeroize the plaintext and keys after you are done with it (key will be zeroized when the enc object is dropped)
        zeroize1(plaintext)
        zeroize1(buf)

        munlock(buf)
        munlock(plaintext)

        print("bye!")

Zeroing memory before forking child process

This mitigates the problems that appears on Copy-on-write fork. You need to zeroize the data before forking the child process.

import os
from zeroize import zeroize1, mlock, munlock

if __name__ == "__main__":
    try:
        # Maximum you can mlock is 4MB
        sensitive_data = bytearray(b"Sensitive Information")
        mlock(sensitive_data)

        print("Before zeroization:", sensitive_data)

        zeroize1(sensitive_data)
        print("After zeroization:", sensitive_data)

        # Forking after zeroization to ensure no sensitive data is copied
        pid = os.fork()
        if pid == 0:
            # This is the child process
            print("Child process memory after fork:", sensitive_data)
        else:
            # This is the parent process
            os.wait()  # Wait for the child process to exit

        print("all good, bye!")

    finally:
        # Unlock the memory
        print("unlocking memory")
        munlock(sensitive_data)

Build from source

Browser

Open in Gitpod

Open in Codespaces

Geting sources from GitHub

Skip this if you're starting it in browser.

git clone https://github.com/radumarias/rencrypt-python && cd Cipher-python

Compile and run

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

To configure your current shell, you need to source the corresponding env file under $HOME/.cargo. This is usually done by running one of the following (note the leading DOT):

. "$HOME/.cargo/env"
python -m venv .env
source .env/bin/activate
pip install -r requirements.txt
maturin develop --release
pytest
python examples/encrypt.py
python examples/encrypt_into.py
python examples/encrypt_from.py
python examples/encrypt_file.py
python benches/bench.py

More benchmarks

Different ways to use the lib

Encrypt Encrypt buffer

Decrypt Decrypt buffer

Block size and duration in seconds

MB rencrypt
encrypt
PyFLocker
encrypt update_into
rencrypt
encrypt_from
PyFLocker
encrypt update
rencrypt
decrypt
PyFLocker
decrypt update_into
rencrypt
decrypt_from
PyFLocker
decrypt update
0.03125 0.00001 0.00091 0.00001 0.00009 0.00001 0.00004 0.00001 0.00005
0.0625 0.00001 0.00005 0.00002 0.00005 0.00001 0.00004 0.00002 0.00008
0.125 0.00002 0.00005 0.00003 0.00011 0.00003 0.00005 0.00003 0.00013
0.25 0.00004 0.00008 0.00007 0.00019 0.00005 0.00009 0.00007 0.00023
0.5 0.0001 0.00014 0.00015 0.00035 0.00011 0.00015 0.00014 0.00043
1 0.00021 0.00024 0.0008 0.00082 0.00021 0.00029 0.00044 0.00103
2 0.00043 0.00052 0.00082 0.00147 0.00044 0.00058 0.00089 0.00176
4 0.00089 0.00098 0.00174 0.00284 0.00089 0.00117 0.0013 0.0034
8 0.00184 0.0019 0.00263 0.00523 0.00192 0.00323 0.00283 0.00571
16 0.00353 0.00393 0.00476 0.0141 0.00367 0.00617 0.00509 0.01031
32 0.00678 0.00748 0.00904 0.0244 0.00749 0.01348 0.01014 0.02543
64 0.01361 0.01461 0.01595 0.05064 0.0146 0.02697 0.0192 0.05296
128 0.02923 0.03027 0.03343 0.10362 0.03134 0.0541 0.03558 0.1138
256 0.06348 0.06188 0.07303 0.20911 0.06136 0.10417 0.07572 0.20828
512 0.11782 0.13463 0.14283 0.41929 0.1209 0.21114 0.14434 0.41463
1024 0.25001 0.24953 0.28912 0.8237 0.25377 0.42581 0.29795 0.82588

Speed throughput

256KB seems to be the sweet spot for buffer size that offers the max MB/s speed for encryption, on benchmarks that seem to be the case. We performed 10.000 encryption operations for each size varying from 1KB to 16MB.

Speed throughput

MB MB/s
0.0009765625 1083
0.001953125 1580
0.00390625 2158
0.0078125 2873
0.015625 3348
0.03125 3731
0.0625 4053
0.125 4156
0.25 4247
0.5 4182
1.0 3490
2.0 3539
4.0 3684
8.0 3787
16.0 3924

For the future

  • Generating key from password (KDF)
  • Maybe add support for RSA and Elliptic-curve cryptography
  • Saving and loading keys from file

Considerations

This lib hasn't been audited, but it wraps ring crate (well known and audited library) and RustCrypto (AES-GCM and ChaCha20Poly1305 ciphers are audited), so in principle at least the primitives should offer a similar level of security.

Contribute

Feel free to fork it, change and use it in any way that you want. If you build something interesting and feel like sharing pull requests are always appreciated.

How to contribute

Please see CONTRIBUTING.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rencrypt-1.2.2.tar.gz (290.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (530.3 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (598.4 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ s390x

rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (491.8 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (512.5 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl (539.4 kB view details)

Uploaded PyPymanylinux: glibc 2.12+ i686

rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (531.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (600.0 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ s390x

rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (492.8 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (513.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl (540.1 kB view details)

Uploaded PyPymanylinux: glibc 2.12+ i686

rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (599.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ s390x

rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (492.9 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (513.9 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (600.8 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ s390x

rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (494.5 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (516.0 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-cp312-none-win_amd64.whl (361.8 kB view details)

Uploaded CPython 3.12Windows x86-64

rencrypt-1.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (528.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rencrypt-1.2.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl (601.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ s390x

rencrypt-1.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (490.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (513.0 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl (538.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.12+ i686

rencrypt-1.2.2-cp312-cp312-macosx_11_0_arm64.whl (345.1 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

rencrypt-1.2.2-cp312-cp312-macosx_10_12_x86_64.whl (483.4 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

rencrypt-1.2.2-cp311-none-win_amd64.whl (363.2 kB view details)

Uploaded CPython 3.11Windows x86-64

rencrypt-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (532.0 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

rencrypt-1.2.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl (598.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ s390x

rencrypt-1.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (492.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (513.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl (540.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.12+ i686

rencrypt-1.2.2-cp311-cp311-macosx_11_0_arm64.whl (346.1 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

rencrypt-1.2.2-cp311-cp311-macosx_10_12_x86_64.whl (485.6 kB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

rencrypt-1.2.2-cp310-none-win_amd64.whl (363.4 kB view details)

Uploaded CPython 3.10Windows x86-64

rencrypt-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (532.2 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

rencrypt-1.2.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl (598.7 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ s390x

rencrypt-1.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (492.9 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (513.9 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl (540.6 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.12+ i686

rencrypt-1.2.2-cp310-cp310-macosx_11_0_arm64.whl (346.1 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

rencrypt-1.2.2-cp310-cp310-macosx_10_12_x86_64.whl (484.8 kB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

rencrypt-1.2.2-cp39-none-win_amd64.whl (363.0 kB view details)

Uploaded CPython 3.9Windows x86-64

rencrypt-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (532.4 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

rencrypt-1.2.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl (599.7 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ s390x

rencrypt-1.2.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (492.9 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (514.6 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl (540.9 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.12+ i686

rencrypt-1.2.2-cp39-cp39-macosx_11_0_arm64.whl (346.4 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

rencrypt-1.2.2-cp39-cp39-macosx_10_12_x86_64.whl (485.1 kB view details)

Uploaded CPython 3.9macOS 10.12+ x86-64

rencrypt-1.2.2-cp38-none-win_amd64.whl (363.2 kB view details)

Uploaded CPython 3.8Windows x86-64

rencrypt-1.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (532.6 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64

rencrypt-1.2.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl (599.7 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ s390x

rencrypt-1.2.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (493.0 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (514.6 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl (541.0 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.12+ i686

rencrypt-1.2.2-cp37-none-win_amd64.whl (363.3 kB view details)

Uploaded CPython 3.7Windows x86-64

rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (532.7 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ x86-64

rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl (600.6 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ s390x

rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (492.8 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ ppc64le

rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (514.1 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ ARMv7l

rencrypt-1.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl (540.7 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.12+ i686

File details

Details for the file rencrypt-1.2.2.tar.gz.

File metadata

  • Download URL: rencrypt-1.2.2.tar.gz
  • Upload date:
  • Size: 290.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for rencrypt-1.2.2.tar.gz
Algorithm Hash digest
SHA256 11e747a46012fcea9582e1060564a57ca01d0fee4fb5836e66febe4856878c3e
MD5 e3ab018b589ad2820c4482b0de5569f4
BLAKE2b-256 4f2491f4932479cdb8141a2eda56423b2f054a9d62567355e7a63271c373a676

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7e2b0eca8b14d2d8ec9d1e6dbee5e7e111a3ae101d4d14da5f25fb97fc0eb3bc
MD5 67a681117c95a30d037a147485663396
BLAKE2b-256 3b68d965495c734314def5073e6894ac790c518bd3939904b91a2f12ca766bb1

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 0ad3f19e4a29246c2eed3f0e005568f5d34a439bdb81e2e2d72cd0e2cee497fc
MD5 4a45ebf0726d801142823282ac3cb47c
BLAKE2b-256 adc0ceca89dc058c27553e2389d6c132cd1194799131ded2cbe11d8cb3267421

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 4694189f2cd10fa7878ea84efc04d4311e84ffabfa6db5c2a23b0abcd882fb3e
MD5 851b4578ecca80f81e3b79b43aa5b34c
BLAKE2b-256 7b4b53f2c69871d07f390020b08f6a5b10160000ecf228b16bd46e8d677cddc3

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 da377ed1c22ea9d3fa4ce2a5c1ccfde801600583c1840c573f7f7b56b9688875
MD5 f49a9124a9d88324b84fe9319553538a
BLAKE2b-256 ee24af7a525a3f16df3ad07c6ed005d2ae2aeebda2b398a0612617fa7a939b36

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 74f36e3a54dcd5ae5171ec21a6547abba7fd46209b97f6f1df2141c0bf1878d6
MD5 c54c4ef56b3cf3c5be7e79455d0d45d3
BLAKE2b-256 7d4d54b9f790fb30c58ed33767bc622624a6447c3ad2fdfbc523502daf60ebae

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9a888d8af81394aa136032a3109fd3cae766833cf4bc8192cc95353df3cabd99
MD5 4d200173b042642874c947c31555e0cc
BLAKE2b-256 aaeefad009f66ef45caeda7297c107a7598a70702c5dc448a4191d12f3bba772

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 a25f1b0c35af1614142bf552e9d9b55dc8b532251065e4b00b86db28a7036636
MD5 779e57748a3a444efaab650a1506a7a6
BLAKE2b-256 b7f0dd83a0d00cf123c7e87251640282fa93424ce5f30a2c91de6c36929a4f6b

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 0747fe69e514541acd9cdb0145caba2374e55e5af2257cb56c5a196d979b822a
MD5 3a8dab058fabc6c23fe4e90df51dc3f9
BLAKE2b-256 236707e0c9b795158f030d672fe55b811a5f6ccc3dece5a0d40622b379ebe0db

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 5ce97ae0a9b5833e815e11d844ff4a56df93aa2e1e97288a0154c6a8a8084994
MD5 561ee179dd46b64073e19b21ed118a5a
BLAKE2b-256 9ad15cde7366d962f1c433ba3365806f58f99dc3b037936106121211be38bb01

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 36fc48a5f9fd4e4bd845243b46b36ed7d607a2e102520e3222ff9b2d8872355b
MD5 45ad91a16c78c2499225fe3be2dd3cb0
BLAKE2b-256 ffdce9f0adee424e2280be8afd5602e8d258fa3051f75f06327ce134d38cf3d3

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 1accedcb2b559136167e9918fa073897308511ff82eaef7960ad5c3dd75e144c
MD5 a9fed0801d7b1644212d6a6f1f66c958
BLAKE2b-256 7e0a6f76df320ac26cc93aa0eb22219e4d0ee9673c7fdc4bf05b458793550f52

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 a9a524ab8ffa915e33e8070f586d3f1be68b9cedc00ba7d068dad33ac4c509fe
MD5 eb63b0036f953448397ca88c9519b130
BLAKE2b-256 b574959edf8a669aef3e466b0051a8528912d0c6232f291edcdbf084aa9f3b5e

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 9f0637bdfa234db30e565b00803de82333c36ddcb6c1b6a727c1b2a38af46998
MD5 eb215d51be1d7ae3fd2806fd7ce38008
BLAKE2b-256 dd7c5c76fe31d63daebe9759a63447670092a8fdee84ee603add26bd8f48c2f9

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 15736a843e77d1f1566bf2bdbc83cf679544323f4761d81752611262845de323
MD5 c5c88efcca6074de6f00a0bb2637ee43
BLAKE2b-256 6af00ed43c5f690f4bbe7f4e7ed0c4f964b24511a33d41124b971922d33dc65d

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 b8dcf619147b2a6035e88bbb64ee8198bf11ab9f250257066076c23b60cb2e86
MD5 8d345f0b022f459e732779c49d155856
BLAKE2b-256 87cd04ec88753f8d2b33c4846ee5af0ec0eafac94150e513b98ebde92d223942

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-pp37-pypy37_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 4969c660ba7974f51e112e094d37a226870f250ac788f3d108b68e381c695df5
MD5 791be9c30fffe8ff9468a12884312ddf
BLAKE2b-256 b44e371fc88db2acea04e855eb90449c827620b714051f1ad4b81bc58bc9c84c

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp312-none-win_amd64.whl.

File metadata

  • Download URL: rencrypt-1.2.2-cp312-none-win_amd64.whl
  • Upload date:
  • Size: 361.8 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for rencrypt-1.2.2-cp312-none-win_amd64.whl
Algorithm Hash digest
SHA256 54c6c918a40be2e17208f01fee9f6f945c424d4b7762a96c6d1bd0a7c7bdc6fd
MD5 fc2652af375c5b8056e5ea2b21d2d92e
BLAKE2b-256 b5ae2dbf13744fa38ca190323ffe8d302c6fb2972d286f4cd19887beb44047f0

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4b6f3de39ead1a7fe66f3eba7e09fa02b3e962575fafc91345cc4c1de6a7dcb9
MD5 d7acb0375948dd9dfda76ef18218e7f5
BLAKE2b-256 cc1f6324de2a16fd8ebb2f7a02cb3e4a9cb1a6f16b89f5f4c9bc49019479985c

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 950dd42c680fed1bd8f00ee2d0cf158f3f9042ca8f55b714e1ac92183d5a2500
MD5 55e60154797ab15bd197c53a24455b99
BLAKE2b-256 32d2527bbb6df7e9918afc913b1ce2f5e7061adca5deafc4df0db4e13448bbc9

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 88ab1a4e6125b0fac252f04e6c11e1e626945cf05c0259570d49a35a9adbb4ed
MD5 913f762ee4bf6450d8b37470748008fc
BLAKE2b-256 5e640c48f47905f097151feef26ce31a1824fc17bb6c4b245754d7227f2f5e08

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 38289d81ce75fb62ecce2b64ac19ff53f71413edc932287993e453f1a216aa27
MD5 47aed6260803f085e93802dbae0a07cd
BLAKE2b-256 a65022e2a5904104da208460540680573c26074bd8050d79cad73e5e7fa626f1

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 069b02a8b5b123c2984c9d92a240acce2051b200c579996fbf4bc502af5ee08a
MD5 07a0d6571c235e11f8fa9b703b0205cc
BLAKE2b-256 1eb25d2b3cef4d6793af2b387326eb2c59a91c81031d516c8eb26fc1e154607b

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1cef1862a070cd4d4c1054ed19142c9c96faae851710c349020105c26d836c56
MD5 5c12302cedcf08925beb794cb336dbf4
BLAKE2b-256 cd8c9b427397293d4dbab2f37a494f54c83fa30165210de63e8df1c140f0e9e7

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f503945880b8863f4722611b8f3a2846b69f985548ce3a1002d46da2dba5c7e1
MD5 3d93f5af9cb793dc2dd6bf8f7ff9b7de
BLAKE2b-256 2343fc7347acddda857d9a0534d9843b366136e37a9495a42d02b74cad542a9a

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp311-none-win_amd64.whl.

File metadata

  • Download URL: rencrypt-1.2.2-cp311-none-win_amd64.whl
  • Upload date:
  • Size: 363.2 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for rencrypt-1.2.2-cp311-none-win_amd64.whl
Algorithm Hash digest
SHA256 04e733e980830fe70361321de2e996d0ce9227abe7b1097c8edf38723b4a1ca4
MD5 d61394eaaf7925a4c77ba031229fd6d2
BLAKE2b-256 7da1cf9e4d5da7daa89293e9623e88518409931bc345bd2ffd0225c674b1c489

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 36ce62d26d38466e82ffe7c82201c76d902bd2229d7f458d086292a6a2fb672c
MD5 2e36e6c870ab8d7cd6fd14108efee668
BLAKE2b-256 5f10d873d1167b91d0c6b292ce22a2ed9db1e42e21f782b1b9fcdcfe8b28a2cc

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 fc90eeffad3ad24bdedfbc47ca4e6365869138598fe5e3599cb28b23c0b9542f
MD5 134ac945744085a89b31156e54e0ca46
BLAKE2b-256 860a7e9c64d60ae6d6eac88ea2fbfc0fb9304caea77776ad64fe224aa22c7506

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 21f1b5c109b99ffd1c03c6cd705d64a3f4eb6419e81d1d51387f69917573dbbe
MD5 aa7c422ef9deeba18c2828ce11eafb14
BLAKE2b-256 0218da0342178028bd3527c48557e5fefebcad31c42a43e98e3825a0126c9669

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 2dced1a85f126b741c01b2b6ece8219e13240c41e6d33bf934efa4891492052b
MD5 23b59f644745c728f69627b603b9ed90
BLAKE2b-256 d1ec80cf3e2c28058aed3c055afeec03461bfa4fcccbf756c21cfc63ebd5a171

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 27a366e05705a8c3bb4f53d724d895368d1594225ef4c8b1bbc6b092f6a3aeb1
MD5 e8568baf95e6c5d37ff3de5f07123dc5
BLAKE2b-256 02badb6046a244f9ed04594e3c7992af180670943020c69c9b79a2cb37cc9ebe

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 45b3621e9a86934269fcf1be1b57a998c0389df2b2ed328cb77d2bcffa266e04
MD5 a521baf72942be1f5a5a5e637934dc35
BLAKE2b-256 5d5664555d3d6c8abca52cc084a026960584ab9e79433df113d3d8890a32d4db

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 161be96e4a295483ad3f938041439e25a8c9ede427f71fd99e4d2ec75cc3f20b
MD5 e314bf6881e5ce722b7da7e7212079b4
BLAKE2b-256 8ed48b992d8bedd4659a4586e51323f6aa568764bfe8ade10f57e116525e8c36

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp310-none-win_amd64.whl.

File metadata

  • Download URL: rencrypt-1.2.2-cp310-none-win_amd64.whl
  • Upload date:
  • Size: 363.4 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for rencrypt-1.2.2-cp310-none-win_amd64.whl
Algorithm Hash digest
SHA256 c1cd92858f028b8a89dc9479c121bfee664238869d46580c40ccadb2fd18f258
MD5 6c395c3a45c06c6bae370e43bb54711c
BLAKE2b-256 f8b5c3d11212a8548dc8bb5ac968ece4ec71821942301fa8f992b6ae4ec166ed

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1a0b080ba351c4a392a90f1d64239282d23a1c2adc443b23953ba3304cac4170
MD5 73fbc9910975bd1d98d50f370ea5f59c
BLAKE2b-256 87ebdf527e4918f5d0a5f1df6265dad8fa82e2745986e8e14093680a6d244023

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 cfad6d12c90f0d833e19029008445b3ec83639659f009ea2cb076a9ff379eab1
MD5 00da67ea6e5535d5690f86616f0077c9
BLAKE2b-256 1b5719d574200d363f8ac44b6a6e8f79c55a0b1960cee438eace6e922b8b0ed1

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 9207c1553e52c35e6ae8e633c1cb4e2e4b85055c40e8a71f95bc0f9689ee5508
MD5 575546766a205be34f6aca3b50cfa364
BLAKE2b-256 870d6ac7cc4355962faa1a5658631f5e950ec761d617b0d1d6b132fe49f2f6de

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 31b573b047fa7a8bb45b064a09225172385ce783e15122d110592a82687cad6e
MD5 390a02e1f50f2056d0b8303187c1b5b8
BLAKE2b-256 de4ddee94305094506670d3121e8bfbca7e9fd36b9f207c5feacdc88c44f1dde

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 7777608ffddd38363c84ae32557488b913e1ccf1a5a9f5e13d870991684fa53b
MD5 9b8805edade1e75f1df99e3c0a459581
BLAKE2b-256 a680b1ffa867b690d3c63ba521d8e90c98b6024155f705748d7da4dc9ac0b5d9

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9dbd5146a319d8c80c39a71b3db59417429221a5fca0799c84f5c2513a3307e5
MD5 37ea2fe96fc14b712612c72219b27867
BLAKE2b-256 8098fa56ee341bd4772713c03a9411b145c40f201b352c74eb1e3953360433e5

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 38697587e693e34c361b06fdc81ffbd19168b2f951b603ff95c5b3accf811ed3
MD5 783cc9cc8934eb4c11e7eeadd326249e
BLAKE2b-256 a2ca165a877615bc620dbd852ed1e11c11e5705280ac8b6bdc9cca07570898ea

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp39-none-win_amd64.whl.

File metadata

  • Download URL: rencrypt-1.2.2-cp39-none-win_amd64.whl
  • Upload date:
  • Size: 363.0 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for rencrypt-1.2.2-cp39-none-win_amd64.whl
Algorithm Hash digest
SHA256 8c28a76e83f1264b1602888eea719b51dcfcc8785d51ae061fd87d5a8cb78170
MD5 6f535333d74e29fcf8c71d461036c4b7
BLAKE2b-256 73de6fe4b93a1dc2bea608bc84f28997f88ac0614fb23c09a38eb2845c4b6fc9

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 67fde306d30131d37b0bfcca78840a5b60b5ae43fa65117afe8afb8846f531c6
MD5 c5663efc597ea3573b4b7f3092ec76b7
BLAKE2b-256 89b52d343bd167d3c3c51db1d651ef70bc60674d0066b4b3800308a2c0ce034e

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 a964f04841a2fc7b78b23cda75ae70a8ef3ce854cc99551eb3d02904d07bb448
MD5 b1f44853d30854048196f39e46c4cb84
BLAKE2b-256 5aa28cdee4cda757510d2c321229713b3ad3d8f632984e26fba237016d01a16b

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 6f5d50aa345eb54874dbd194a57a8e5bf10b372a24e4959fdfd627f44707d48f
MD5 8174eb296dd64cb51b48ed0cbf2423fa
BLAKE2b-256 8ff486f37866d32e471f2ecc4ddc1161a132ac46d197e92d372ac7f90072abda

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 be15816b5b1952a165ad67111fc24b91cd2cc07b1e91713747d188057b681752
MD5 0d4b14df38dc007c284f0856322afd04
BLAKE2b-256 1526219478e60ca73ac94b0e117d875f4a3a30936a2d1d0b04381a778c181656

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 8fe0274cbb87cbbe82ea4ea71aee3ed6ba097f95080aa568ab28c9206d9f4778
MD5 a7fad8fa79748718dd6e7bf63ada4f0b
BLAKE2b-256 5a1ca2cb0a67d883b1870d8b484a16ab61ff9d6ef7734c405317cae1c166c47f

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e9d467642ca89b8724056e313de9285ab66d925d1a0fdcd4bec24953a99d5416
MD5 94aafad84a6b6364431d57a3e59c3a01
BLAKE2b-256 be19bdf844ad8a3dbe1ae7cad53d53814a4262a1cec746763e12a975233028fa

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp39-cp39-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp39-cp39-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 bccabe9e7feb34743367aa106c4a20700342df253a41afb4aba9a0cd169929bb
MD5 2c912200f49b291c27c215b399dd0ba2
BLAKE2b-256 3c50b344e1c3e9efb8b378360e720e802313d078fabf7adcea454f0efdc7451a

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp38-none-win_amd64.whl.

File metadata

  • Download URL: rencrypt-1.2.2-cp38-none-win_amd64.whl
  • Upload date:
  • Size: 363.2 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for rencrypt-1.2.2-cp38-none-win_amd64.whl
Algorithm Hash digest
SHA256 cdded4e4e6267417c7e5647075eb0a96e8a272ba6eb74a2eef628d00ce7cf899
MD5 df03a8f17bb2a967794819f428d5fb79
BLAKE2b-256 f4dae5735c37bc75ea4d64676b0c68f6357d0fbdf5892eeebb136313cdcb0296

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5511918200bc40e7bd75ad02c3db4540fa651902019e518a7e4932158d4c781c
MD5 0dbebcbcd28f71046edb4b750ccede04
BLAKE2b-256 06f8931a8deda7232b796610452ddb1c7d2e0450860738c1a3028514c66b02a4

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 220b3dded13e341de4e87f76851571b85dc492a51321f28c2737f2a6d7cc8b63
MD5 7dcfa9e68edeb828c6e30893313c51e8
BLAKE2b-256 eef9ad4fc62bd68da955e8207733a3a702bd5794f79688db489ed922ef96b634

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 a235d8c0a57d11a7ae96fbc67bf153e2c9adf175e44d5e839f956eb1fa247cbe
MD5 67e36858ec556a92edd10953e201345a
BLAKE2b-256 d5b1c28c5ec73a16a1972e04a1dd8b30437dfd4306c2ff8ab723715ac7d80013

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 0d78f4263cc12d5d1e8d2afbee27750db8486822f2e631b499501020d5da9674
MD5 27fad43dd75ce628d1b46fa337c32011
BLAKE2b-256 db7fd03d1eec2b4c66685927e9d704de0274f5d9c79a9560ce296deba56ebe3e

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 9090b91a29527fdb409d6301bab5be0b7b0fac8f787546d0dccf5de6270b3ff7
MD5 5adb70d2d24a8745d6a4f3b26156aba7
BLAKE2b-256 b30d426fe1db7a7176be3a504c04c4a1430a2d2de2081d554067901435690488

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp37-none-win_amd64.whl.

File metadata

  • Download URL: rencrypt-1.2.2-cp37-none-win_amd64.whl
  • Upload date:
  • Size: 363.3 kB
  • Tags: CPython 3.7, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for rencrypt-1.2.2-cp37-none-win_amd64.whl
Algorithm Hash digest
SHA256 a1bce70efdceef224d5c01e3796256f6f67507f1abe70f9d71ce903ce0d29ca6
MD5 1c9e5cc2817f8faa0980301c20c8dd67
BLAKE2b-256 15f48239c0de7e7ff4e525ca1d3bf8501d15f6736b0f41bcfab4fcf7af62ad89

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 61444a0bd2b4b9c29e152bd30e92b4abec4426289fc7d552880fe8a8c6031737
MD5 371a94159ba3ee29e3e400d0ccd9530a
BLAKE2b-256 64bf5480948778cbf18a39109e67e3ff025091f8da529b331cbeee8bfe4c8de3

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 b046dd5ed41ca52a32f1804da763b789dbce587a890b63526c9bc54f0a752221
MD5 13fd705130463ac757687e1e27251240
BLAKE2b-256 00ddf14f11c91edff32fdbb8c32aab4eb41d2b015001f4a21c6a58e05ffaa686

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 260349b85794c991fdfd47a037aa9abf877105c9463a172d9ebb2ba232b011b0
MD5 19c229264054bd3335786ae5cb0eac67
BLAKE2b-256 9a52d1c709d2c7275e10990447d82e97cb2d955c70fbfa8b637f6a5b1013a7a6

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 ff2420fd96073adfb915ec0ef1fab48a20d9c6db85f9ae1765c20cb9babb514d
MD5 639d3e1f1f2721c4736c29520765ac1d
BLAKE2b-256 e677ddd89ddc44662ab049846bf85f17f9dc08c2df898ae9d99a4fa6f6818308

See more details on using hashes here.

File details

Details for the file rencrypt-1.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for rencrypt-1.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 20735c29b8b64fccb313c3422ba8ddcbd754cdd16e7f7fc4dd9e797c770e4427
MD5 a53df7ec5af1338454ab2df28eb4fc8a
BLAKE2b-256 4c5c7459801d00f94f1be2c1a86758a4b4dd1e7a12618265c4256608407ecade

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page