Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encrypt/decrypt examples #98

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
315 changes: 315 additions & 0 deletions notebooks/encrypt_decrypt.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Encryption examples.ipynb",
"provenance": [],
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/github/pbelevich/csprng/blob/encrypt_decrypt_notebook/notebooks/encrypt_decrypt.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4JG-7IJgz_dK"
},
"source": [
"# PyTorch/CSPRNG encrypt/decrypt examples"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "H8TZemj30JvQ"
},
"source": [
"torchcsprng 0.2.0 exposes new API for tensor encryption/decryption. Tensor encryption/decryption API is dtype agnostic, so a tensor of any dtype can be encrypted and the result can be stored to a tensor of any dtype. An encryption key also can be a tensor of any dtype. Currently torchcsprng supports AES cipher with 128-bit key in two modes: ECB and CTR."
]
},
{
"cell_type": "code",
"metadata": {
"id": "jC1O-C25vI0W",
"outputId": "beee40f0-7fa8-4354-affd-2fcf18305685",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"source": [
"# !pip install --pre torchcsprng -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html\n",
"# for CUDA runtime:\n",
"!pip install --pre torchcsprng -f https://download.pytorch.org/whl/nightly/cu101/torch_nightly.html"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"text": [
"Looking in links: https://download.pytorch.org/whl/nightly/cu101/torch_nightly.html\n",
"Collecting torchcsprng\n",
"\u001b[?25l Downloading https://download.pytorch.org/whl/nightly/cu101/torchcsprng-0.2.0.dev20201210%2Bcu101-cp36-cp36m-linux_x86_64.whl (4.4MB)\n",
"\u001b[K |████████████████████████████████| 4.4MB 552kB/s \n",
"\u001b[?25hCollecting torch==1.8.0.dev20201210+cu101\n",
"\u001b[?25l Downloading https://download.pytorch.org/whl/nightly/cu101/torch-1.8.0.dev20201210%2Bcu101-cp36-cp36m-linux_x86_64.whl (788.6MB)\n",
"\u001b[K |████████████████████████████████| 788.6MB 25kB/s \n",
"\u001b[?25hRequirement already satisfied: typing-extensions in /usr/local/lib/python3.6/dist-packages (from torch==1.8.0.dev20201210+cu101->torchcsprng) (3.7.4.3)\n",
"Requirement already satisfied: dataclasses; python_version < \"3.7\" in /usr/local/lib/python3.6/dist-packages (from torch==1.8.0.dev20201210+cu101->torchcsprng) (0.8)\n",
"Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from torch==1.8.0.dev20201210+cu101->torchcsprng) (1.18.5)\n",
"\u001b[31mERROR: torchvision 0.8.1+cu101 has requirement torch==1.7.0, but you'll have torch 1.8.0.dev20201210+cu101 which is incompatible.\u001b[0m\n",
"Installing collected packages: torch, torchcsprng\n",
" Found existing installation: torch 1.7.0+cu101\n",
" Uninstalling torch-1.7.0+cu101:\n",
" Successfully uninstalled torch-1.7.0+cu101\n",
"Successfully installed torch-1.8.0.dev20201210+cu101 torchcsprng-0.2.0.dev20201210+cu101\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "su2RWWdOrWFU"
},
"source": [
"import torch\n",
"import torchcsprng as csprng"
],
"execution_count": 2,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "NHTOLPZ_3254"
},
"source": [
"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')"
],
"execution_count": 3,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "17L0sgmy0R6o"
},
"source": [
"torchcsprng implementation of AES with 128 bit key requires to have a key tensor of 16 bytes but of any dtype"
]
},
{
"cell_type": "code",
"metadata": {
"id": "rw7WYZ-50To9",
"outputId": "7e9accec-5ac1-4de2-fcc5-860df06ad338",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"source": [
"key = torch.empty(16, dtype=torch.uint8, device=device).random_(0, 256)\n",
"key"
],
"execution_count": 4,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"tensor([ 94, 155, 111, 73, 36, 65, 95, 175, 103, 249, 39, 221, 225, 106,\n",
" 147, 18], dtype=torch.uint8)"
]
},
"metadata": {
"tags": []
},
"execution_count": 4
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RRfvyfHM4MY1"
},
"source": [
"Alternatively it can be a tensor of 8 elements of `torch.int16` or even 4 elements of `torch.float32`"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rCy01t1-0dtO"
},
"source": [
"The size of input tensor is 42 * (32/8) = 168 bytes. AES 128 operates with 16-bytes blocks, so zero-padding of 8 bytes will be used to form 176 bytes(eleven 16-bytes blocks)"
]
},
{
"cell_type": "code",
"metadata": {
"id": "LcuVmhyU0WTn",
"outputId": "2b887caa-ef4c-4e2a-bc7e-d00191cb727c",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"source": [
"initial = torch.empty(42, dtype=torch.float32, device=device).normal_(-24.0, 42.0)\n",
"initial"
],
"execution_count": 5,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"tensor([ -33.2154, -4.4617, -2.9105, -37.1893, -6.0623, -47.4273,\n",
" -44.7682, 23.7199, 52.3595, -80.1355, 10.7041, -52.0069,\n",
" -59.1335, -51.7051, -96.7531, -47.6263, -37.4668, -26.9140,\n",
" -8.7239, -68.0884, -73.8865, -35.0378, -24.9022, -71.3780,\n",
" -83.3700, -73.9181, -56.9136, -14.0332, -0.1193, -24.6635,\n",
" -12.3755, 26.1501, -21.7292, 61.0362, -8.2424, -27.3287,\n",
" -116.2249, -32.5120, -56.9908, -44.0908, 15.9910, -12.2838])"
]
},
"metadata": {
"tags": []
},
"execution_count": 5
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rPNq2u4e3tlJ"
},
"source": [
"torchcsprng requires output tensor to be of the same size in bytes as input tensor rounded up to 16 bytes(AES 128 block size), so if `torch.int64` is dtype of the destination tensor size must be 176 / (64/8) = 22"
]
},
{
"cell_type": "code",
"metadata": {
"id": "RAJya9GT0gb4"
},
"source": [
"encrypted = torch.empty(22, dtype=torch.int64, device=device)"
],
"execution_count": 6,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "-DCI4QOh4oGX"
},
"source": [
"Call `torchcsprng.encrypt` to encrypt `initial` tensor in [ECB](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)) mode with 128-bit `key` tensor and store the result to `encrypted` tensor."
]
},
{
"cell_type": "code",
"metadata": {
"id": "TK4OjPRq4lsJ",
"outputId": "a9c7bee0-e95c-49fa-a6a8-8a33b58695e0",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"source": [
"csprng.encrypt(initial, encrypted, key, \"aes128\", \"ecb\")"
],
"execution_count": 7,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"tensor([-1712310488599806515, -8311769289706173237, -8219472943074007291,\n",
" 4944862344658876406, 5289614356287313567, -6556419268017486570,\n",
" -2070634943111059129, -6988005632242749066, -6786984565899259673,\n",
" 2617853683610034142, 7394987086142621793, 9037048344238914391,\n",
" -4389724417591829293, 639143755047053321, 6630155308790632093,\n",
" 8233678956273288167, 7762736707078557167, -66820074992426839,\n",
" 2506358826618882964, 3811127519115226076, 7223286519671228245,\n",
" -4680879586720463643])"
]
},
"metadata": {
"tags": []
},
"execution_count": 7
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yXUAwFHh5PSy"
},
"source": [
"Create an output tensor"
]
},
{
"cell_type": "code",
"metadata": {
"id": "4LtJ-kD446DJ"
},
"source": [
"decrypted = torch.empty_like(initial)"
],
"execution_count": 8,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "8VcF04mf6Rn5"
},
"source": [
"Call `torchcsprng.decrypt` to decrypt `encrypted` tensor in ECB mode with 128-bit `key` tensor and store the result to `decrypted` tensor."
]
},
{
"cell_type": "code",
"metadata": {
"id": "kojXCFGK5v6l"
},
"source": [
"# csprng.decrypt(encrypted, decrypted, key, \"aes128\", \"ecb\")"
],
"execution_count": 10,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "yOc1ftnM5yyj"
},
"source": [
""
],
"execution_count": null,
"outputs": []
}
]
}