{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": "true" }, "source": [ "# Table of Contents\n", "

1  Implementing the ChaCha Pseudo-Random Number Generator (PNRG) in Julia
1.1  Implementation
1.1.1  Preliminary functions
1.2  Examples
1.3  Tests
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Implementing the ChaCha Pseudo-Random Number Generator (PNRG) in Julia\n", "\n", "- This post is inspired by [this recent blog post by John D. Cook](https://www.johndcook.com/blog/2019/03/03/do-the-chacha/),\n", "- The reference is the official reference, the [RFC-8439](https://tools.ietf.org/html/rfc8439),\n", "- Author: [Lilian Besson](https://github.com/Naereen),\n", "- License: [MIT License](https://lbesson.mit-license.org/)\n", "- Date: 4th of March, 2019." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Implementation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Preliminary functions" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(4294967296, 4294967296, 4294967296)" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 ^ 32, 1 << 32, 2 << 31" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 0.000010 seconds (5 allocations: 176 bytes)\n", " 0.000127 seconds (5 allocations: 176 bytes)\n" ] }, { "data": { "text/plain": [ "2147483648" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@time 1 << 31\n", "@time 2 ^ 31" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "roll (generic function with 1 method)" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function roll(x, n)\n", " return (x << n) % (1 << 32) + (x >> (32 - n))\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can test our operation:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2023406814\n", "2023406814\n", "2040053722\n", "2040053722\n", "3428838716\n", "3428838716\n" ] } ], "source": [ "a = 0x11111111\n", "b = 0x01020304\n", "c = 0x77777777\n", "d = 0x01234567\n", "println(c + d)\n", "println(0x789abcde)\n", "c = c + d\n", "println(xor(b, c))\n", "println(0x7998bfda)\n", "b = xor(b, c)\n", "println(roll(b, 7))\n", "println(0xcc5fed3c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now the \"quarter round\" is implemented like this:" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "quarter_round (generic function with 2 methods)" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function quarter_round(a, b, c, d)\n", " a = (a + b) % (1 << 32)\n", " d = roll(xor(d, a), 16)\n", " c = (c + d) % (1 << 32)\n", " b = roll(xor(b, c), 12)\n", " a = (a + b) % (1 << 32)\n", " d = roll(xor(d, a), 8)\n", " c = (c + d) % (1 << 32)\n", " b = roll(xor(b, c), 7)\n", " return a, b, c, d\n", "end" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0x00000000ea2a92f4, 0x00000000cb1cf8ce, 0x000000004581472e, 0x000000005881c4bb)" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 0x11111111\n", "b = 0x01020304\n", "c = 0x9b8d6f43\n", "d = 0x01234567\n", "\n", "quarter_round(a, b, c, d)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UInt32" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "typeof(a)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb)" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Examples" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tests" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.1.0", "language": "julia", "name": "julia-1.1" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.1.0" }, "toc": { "colors": { "hover_highlight": "#DAA520", "running_highlight": "#FF0000", "selected_highlight": "#FFD700" }, "moveMenuLeft": true, "nav_menu": { "height": "112px", "width": "252px" }, "navigate_menu": true, "number_sections": true, "sideBar": false, "threshold": 4, "toc_cell": true, "toc_section_display": "block", "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 2 }