• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/cfe/cfe/arch/arm/board/bcm947xx/src/
1/**
2 * @file tinymt32.c
3 *
4 * @brief Tiny Mersenne Twister only 127 bit internal state
5 *
6 * @author Mutsuo Saito (Hiroshima University)
7 * @author Makoto Matsumoto (The University of Tokyo)
8 *
9 * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
10 * Hiroshima University and The University of Tokyo.
11 * All rights reserved.
12 *
13 * The 3-clause BSD License is applied to this software, see
14 * LICENSE.txt
15 *
16 * $Id:: tinymt32.c 1306 2012-06-21 14:10:10Z jeung               $:
17 * $Rev::file = 1306 : Global SVN Revision = 1306                 $:
18 *
19 */
20
21/* FILE-CSTYLED */
22
23#include <tinymt32.h>
24
25#define MIN_LOOP 8
26#define PRE_LOOP 8
27
28/**
29 * This function represents a function used in the initialization
30 * by init_by_array
31 * @param x 32-bit integer
32 * @return 32-bit integer
33 */
34static uint32_t ini_func1(uint32_t x) {
35    return (x ^ (x >> 27)) * (uint32_t)1664525UL;
36}
37
38/**
39 * This function represents a function used in the initialization
40 * by init_by_array
41 * @param x 32-bit integer
42 * @return 32-bit integer
43 */
44static uint32_t ini_func2(uint32_t x) {
45    return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
46}
47
48/**
49 * This function certificate the period of 2^127-1.
50 * @param random tinymt state vector.
51 */
52static void period_certification(tinymt32_t * random) {
53    if ((random->status[0] & TINYMT32_MASK) == 0 &&
54	random->status[1] == 0 &&
55	random->status[2] == 0 &&
56	random->status[3] == 0) {
57	random->status[0] = 'T';
58	random->status[1] = 'I';
59	random->status[2] = 'N';
60	random->status[3] = 'Y';
61    }
62}
63
64/**
65 * This function initializes the internal state array with a 32-bit
66 * unsigned integer seed.
67 * @param random tinymt state vector.
68 * @param seed a 32-bit unsigned integer used as a seed.
69 */
70void tinymt32_init(tinymt32_t * random, uint32_t seed) {
71  int i;
72    random->status[0] = seed;
73    random->status[1] = random->mat1;
74    random->status[2] = random->mat2;
75    random->status[3] = random->tmat;
76    for ( i = 1; i < MIN_LOOP; i++) {
77	random->status[i & 3] ^= i + UINT32_C(1812433253)
78	    * (random->status[(i - 1) & 3]
79	       ^ (random->status[(i - 1) & 3] >> 30));
80    }
81    period_certification(random);
82    for ( i = 0; i < PRE_LOOP; i++) {
83	tinymt32_next_state(random);
84    }
85}
86
87/**
88 * This function initializes the internal state array,
89 * with an array of 32-bit unsigned integers used as seeds
90 * @param random tinymt state vector.
91 * @param init_key the array of 32-bit integers, used as a seed.
92 * @param key_length the length of init_key.
93 */
94void tinymt32_init_by_array(tinymt32_t * random, uint32_t init_key[],
95			    int key_length) {
96    const int lag = 1;
97    const int mid = 1;
98    const int size = 4;
99    int i, j;
100    int count;
101    uint32_t r;
102    uint32_t * st = &random->status[0];
103
104    st[0] = 0;
105    st[1] = random->mat1;
106    st[2] = random->mat2;
107    st[3] = random->tmat;
108    if (key_length + 1 > MIN_LOOP) {
109	count = key_length + 1;
110    } else {
111	count = MIN_LOOP;
112    }
113    r = ini_func1(st[0] ^ st[mid % size]
114		  ^ st[(size - 1) % size]);
115    st[mid % size] += r;
116    r += key_length;
117    st[(mid + lag) % size] += r;
118    st[0] = r;
119    count--;
120    for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
121	r = ini_func1(st[i] ^ st[(i + mid) % size] ^ st[(i + size - 1) % size]);
122	st[(i + mid) % size] += r;
123	r += init_key[j] + i;
124	st[(i + mid + lag) % size] += r;
125	st[i] = r;
126	i = (i + 1) % size;
127    }
128    for (; j < count; j++) {
129	r = ini_func1(st[i] ^ st[(i + mid) % size] ^ st[(i + size - 1) % size]);
130	st[(i + mid) % size] += r;
131	r += i;
132	st[(i + mid + lag) % size] += r;
133	st[i] = r;
134	i = (i + 1) % size;
135    }
136    for (j = 0; j < size; j++) {
137	r = ini_func2(st[i] + st[(i + mid) % size] + st[(i + size - 1) % size]);
138	st[(i + mid) % size] ^= r;
139	r -= i;
140	st[(i + mid + lag) % size] ^= r;
141	st[i] = r;
142	i = (i + 1) % size;
143    }
144    period_certification(random);
145    for (i = 0; i < PRE_LOOP; i++) {
146	tinymt32_next_state(random);
147    }
148}
149