/usr/lib/python3/dist-packages/Cryptodome/Cipher/Salsa20.py is in python3-pycryptodome 3.4.7-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | # -*- coding: utf-8 -*-
#
# Cipher/Salsa20.py : Salsa20 stream cipher (http://cr.yp.to/snuffle.html)
#
# Contributed by Fabrizio Tarizzo <fabrizio@fabriziotarizzo.org>.
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
create_string_buffer,
get_raw_buffer, VoidPointer,
SmartPointer, c_size_t,
expect_byte_string)
from Cryptodome.Random import get_random_bytes
_raw_salsa20_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._Salsa20",
"""
int Salsa20_stream_init(uint8_t *key, size_t keylen,
uint8_t *nonce, size_t nonce_len,
void **pSalsaState);
int Salsa20_stream_destroy(void *salsaState);
int Salsa20_stream_encrypt(void *salsaState,
const uint8_t in[],
uint8_t out[], size_t len);
""")
class Salsa20Cipher:
"""Salsa20 cipher object. Do not create it directly. Use :py:func:`new`
instead.
:var nonce: The nonce with length 8
:vartype nonce: byte string
"""
def __init__(self, key, nonce):
"""Initialize a Salsa20 cipher object
See also `new()` at the module level."""
if len(key) not in key_size:
raise ValueError("Incorrect key length for Salsa20 (%d bytes)" % len(key))
if len(nonce) != 8:
raise ValueError("Incorrect nonce length for Salsa20 (%d bytes)" %
len(nonce))
self.nonce = nonce
expect_byte_string(key)
expect_byte_string(nonce)
self._state = VoidPointer()
result = _raw_salsa20_lib.Salsa20_stream_init(
key,
c_size_t(len(key)),
nonce,
c_size_t(len(nonce)),
self._state.address_of())
if result:
raise ValueError("Error %d instantiating a Salsa20 cipher")
self._state = SmartPointer(self._state.get(),
_raw_salsa20_lib.Salsa20_stream_destroy)
self.block_size = 1
self.key_size = len(key)
def encrypt(self, plaintext):
"""Encrypt a piece of data.
:param plaintext: The data to encrypt, of any size.
:type plaintext: byte string
:returns: the encrypted byte string, of equal length as the
plaintext.
"""
expect_byte_string(plaintext)
ciphertext = create_string_buffer(len(plaintext))
result = _raw_salsa20_lib.Salsa20_stream_encrypt(
self._state.get(),
plaintext,
ciphertext,
c_size_t(len(plaintext)))
if result:
raise ValueError("Error %d while encrypting with Salsa20" % result)
return get_raw_buffer(ciphertext)
def decrypt(self, ciphertext):
"""Decrypt a piece of data.
:param ciphertext: The data to decrypt, of any size.
:type ciphertext: byte string
:returns: the decrypted byte string, of equal length as the
ciphertext.
"""
try:
return self.encrypt(ciphertext)
except ValueError as e:
raise ValueError(str(e).replace("enc", "dec"))
def new(key, nonce=None):
"""Create a new Salsa20 cipher
:keyword key: The secret key to use. It must be 16 or 32 bytes long.
:type key: byte string
:keyword nonce:
A value that must never be reused for any other encryption
done with this key. It must be 8 bytes long.
If not provided, a random byte string will be generated (you can read
it back via the ``nonce`` attribute of the returned object).
:type nonce: byte string
:Return: a :class:`Cryptodome.Cipher.Salsa20.Salsa20Cipher` object
"""
if nonce is None:
nonce = get_random_bytes(8)
return Salsa20Cipher(key, nonce)
# Size of a data block (in bytes)
block_size = 1
# Size of a key (in bytes)
key_size = (16, 32)
|