Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
tea.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010-2020 darktable developers.
4
5 darktable is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 darktable is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with darktable. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#pragma once
20
21// Allocate a buffer for storing the internal state of 'numthreads' parallel instances of the Tiny Encryption
22// Algorithm. We need to ensure that each state falls in a separate cache line, or all threads sharing a
23// cache line will be running in lock-step as the cache line bounces back and forth between them, effectively
24// cutting throughput by a factor equal to the number of threads sharing a cache line (8 with a 64-byte cache
25// line and 32-bit ints)
26#define TEA_STATE_SIZE (MAX(DT_CACHELINE_BYTES, 2*sizeof(unsigned int)))
27static inline unsigned int* alloc_tea_states(size_t numthreads)
28{
29 unsigned int* states = dt_alloc_align(numthreads * TEA_STATE_SIZE);
30 if (states) memset(states, 0, numthreads * TEA_STATE_SIZE);
31 return states;
32}
33
34// retrieve the state for the instance in the given thread from the array of states previously allocated with
35// alloc_tea_states()
36static inline unsigned int* get_tea_state(unsigned int* const states, int threadnum)
37{
38 return states + threadnum * TEA_STATE_SIZE/sizeof(states[0]);
39}
40
41static inline void free_tea_states(unsigned int* states)
42{
43 dt_free_align(states);
44}
45
46// How many rounds of the mixing function to run for one encryption
47#define TEA_ROUNDS 8
48
49// Run the encryption mixing function using and updating the given internal state. For use as a PRNG, you can
50// set arg[0] to the random-number seed, then read out the value of arg[0] after each call to this function.
51static inline void encrypt_tea(unsigned int *arg)
52{
53 const unsigned int key[] = { 0xa341316c, 0xc8013ea4, 0xad90777d, 0x7e95761e };
54 unsigned int v0 = arg[0], v1 = arg[1];
55 unsigned int sum = 0;
56 unsigned int delta = 0x9e3779b9;
57 for(int i = 0; i < TEA_ROUNDS; i++)
58 {
59 sum += delta;
60 v0 += ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + key[1]);
61 v1 += ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + key[3]);
62 }
63 arg[0] = v0;
64 arg[1] = v1;
65}
66
67static inline float tpdf(unsigned int urandom)
68{
69 float frandom = (float)urandom / (float)0xFFFFFFFFu;
70
71 return (frandom < 0.5f ? (sqrtf(2.0f * frandom) - 1.0f) : (1.0f - sqrtf(2.0f * (1.0f - frandom))));
72}
73
74
75// clang-format off
76// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
77// vim: shiftwidth=2 expandtab tabstop=2 cindent
78// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
79// clang-format on
80
char * key
Definition common/metadata.c:40
#define dt_free_align(A)
Definition darktable.h:334
static float tpdf(unsigned int urandom)
Definition tea.h:67
#define TEA_ROUNDS
Definition tea.h:47
static unsigned int * get_tea_state(unsigned int *const states, int threadnum)
Definition tea.h:36
static void free_tea_states(unsigned int *states)
Definition tea.h:41
#define TEA_STATE_SIZE
Definition tea.h:26
static unsigned int * alloc_tea_states(size_t numthreads)
Definition tea.h:27
static void encrypt_tea(unsigned int *arg)
Definition tea.h:51
#define dt_alloc_align(B)
Definition tests/cache.c:22