xref: /dragonfly/contrib/gmp/randmt.c (revision 86d7f5d3)
1*86d7f5d3SJohn Marino /* Mersenne Twister pseudo-random number generator functions.
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino    THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY.  THEY'RE ALMOST
4*86d7f5d3SJohn Marino    CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
5*86d7f5d3SJohn Marino    FUTURE GNU MP RELEASES.
6*86d7f5d3SJohn Marino 
7*86d7f5d3SJohn Marino Copyright 2002, 2003, 2006 Free Software Foundation, Inc.
8*86d7f5d3SJohn Marino 
9*86d7f5d3SJohn Marino This file is part of the GNU MP Library.
10*86d7f5d3SJohn Marino 
11*86d7f5d3SJohn Marino The GNU MP Library is free software; you can redistribute it and/or modify
12*86d7f5d3SJohn Marino it under the terms of the GNU Lesser General Public License as published by
13*86d7f5d3SJohn Marino the Free Software Foundation; either version 3 of the License, or (at your
14*86d7f5d3SJohn Marino option) any later version.
15*86d7f5d3SJohn Marino 
16*86d7f5d3SJohn Marino The GNU MP Library is distributed in the hope that it will be useful, but
17*86d7f5d3SJohn Marino WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18*86d7f5d3SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
19*86d7f5d3SJohn Marino License for more details.
20*86d7f5d3SJohn Marino 
21*86d7f5d3SJohn Marino You should have received a copy of the GNU Lesser General Public License
22*86d7f5d3SJohn Marino along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
23*86d7f5d3SJohn Marino 
24*86d7f5d3SJohn Marino #include <stdio.h>   /* for NULL */
25*86d7f5d3SJohn Marino 
26*86d7f5d3SJohn Marino #include "gmp.h"
27*86d7f5d3SJohn Marino #include "gmp-impl.h"
28*86d7f5d3SJohn Marino #include "randmt.h"
29*86d7f5d3SJohn Marino 
30*86d7f5d3SJohn Marino 
31*86d7f5d3SJohn Marino /* This code implements the Mersenne Twister pseudorandom number generator
32*86d7f5d3SJohn Marino    by Takuji Nishimura and Makoto Matsumoto.  The buffer initialization
33*86d7f5d3SJohn Marino    function is different in order to permit seeds greater than 2^32-1.
34*86d7f5d3SJohn Marino 
35*86d7f5d3SJohn Marino    This file contains a special __gmp_randinit_mt_noseed which excludes the
36*86d7f5d3SJohn Marino    seeding function from the gmp_randfnptr_t routines.  This is for use by
37*86d7f5d3SJohn Marino    mpn_random and mpn_random2 on the global random generator.  MT seeding
38*86d7f5d3SJohn Marino    uses mpz functions, and we don't want mpn routines dragging mpz functions
39*86d7f5d3SJohn Marino    into the link.  */
40*86d7f5d3SJohn Marino 
41*86d7f5d3SJohn Marino 
42*86d7f5d3SJohn Marino /* Default seed to use when the generator is not initialized.  */
43*86d7f5d3SJohn Marino #define DEFAULT_SEED 5489 /* was 4357 */
44*86d7f5d3SJohn Marino 
45*86d7f5d3SJohn Marino /* Tempering masks.  */
46*86d7f5d3SJohn Marino #define MASK_1 0x9D2C5680
47*86d7f5d3SJohn Marino #define MASK_2 0xEFC60000
48*86d7f5d3SJohn Marino 
49*86d7f5d3SJohn Marino /* Initial state of buffer when initialized with default seed.  */
50*86d7f5d3SJohn Marino static const gmp_uint_least32_t default_state[N] =
51*86d7f5d3SJohn Marino {
52*86d7f5d3SJohn Marino   0xD247B233,0x9E5AA8F1,0x0FFA981B,0x9DCB0980,0x74200F2B,0xA576D044,
53*86d7f5d3SJohn Marino   0xE9F05ADF,0x1538BFF5,0x59818BBF,0xCF9E58D8,0x09FCE032,0x6A1C663F,
54*86d7f5d3SJohn Marino   0x5116E78A,0x69B3E0FA,0x6D92D665,0xD0A8BE98,0xF669B734,0x41AC1B68,
55*86d7f5d3SJohn Marino   0x630423F1,0x4B8D6B8A,0xC2C46DD7,0x5680747D,0x43703E8F,0x3B6103D2,
56*86d7f5d3SJohn Marino   0x49E5EB3F,0xCBDAB4C1,0x9C988E23,0x747BEE0B,0x9111E329,0x9F031B5A,
57*86d7f5d3SJohn Marino   0xECCA71B9,0x2AFE4EF8,0x8421C7ED,0xAC89AFF1,0xAED90DF3,0x2DD74F01,
58*86d7f5d3SJohn Marino   0x14906A13,0x75873FA9,0xFF83F877,0x5028A0C9,0x11B4C41D,0x7CAEDBC4,
59*86d7f5d3SJohn Marino   0x8672D0A7,0x48A7C109,0x8320E59F,0xBC0B3D5F,0x75A30886,0xF9E0D128,
60*86d7f5d3SJohn Marino   0x41AF7580,0x239BB94D,0xC67A3C81,0x74EEBD6E,0xBC02B53C,0x727EA449,
61*86d7f5d3SJohn Marino   0x6B8A2806,0x5853B0DA,0xBDE032F4,0xCE234885,0x320D6145,0x48CC053F,
62*86d7f5d3SJohn Marino   0x00DBC4D2,0xD55A2397,0xE1059B6F,0x1C3E05D1,0x09657C64,0xD07CB661,
63*86d7f5d3SJohn Marino   0x6E982E34,0x6DD1D777,0xEDED1071,0xD79DFD65,0xF816DDCE,0xB6FAF1E4,
64*86d7f5d3SJohn Marino   0x1C771074,0x311835BD,0x18F952F7,0xF8F40350,0x4ECED354,0x7C8AC12B,
65*86d7f5d3SJohn Marino   0x31A9994D,0x4FD47747,0xDC227A23,0x6DFAFDDF,0x6796E748,0x0C6F634F,
66*86d7f5d3SJohn Marino   0xF992FA1D,0x4CF670C9,0x067DFD31,0xA7A3E1A5,0x8CD7D9DF,0x972CCB34,
67*86d7f5d3SJohn Marino   0x67C82156,0xD548F6A8,0x045CEC21,0xF3240BFB,0xDEF656A7,0x43DE08C5,
68*86d7f5d3SJohn Marino   0xDAD1F92F,0x3726C56B,0x1409F19A,0x942FD147,0xB926749C,0xADDC31B8,
69*86d7f5d3SJohn Marino   0x53D0D869,0xD1BA52FE,0x6722DF8C,0x22D95A74,0x7DC1B52A,0x1DEC6FD5,
70*86d7f5d3SJohn Marino   0x7262874D,0x0A725DC9,0xE6A8193D,0xA052835A,0xDC9AD928,0xE59EBB90,
71*86d7f5d3SJohn Marino   0x70DBA9FF,0xD612749D,0x5A5A638C,0x6086EC37,0x2A579709,0x1449EA3A,
72*86d7f5d3SJohn Marino   0xBC8E3C06,0x2F900666,0xFBE74FD1,0x6B35B911,0xF8335008,0xEF1E979D,
73*86d7f5d3SJohn Marino   0x738AB29D,0xA2DC0FDC,0x7696305D,0xF5429DAC,0x8C41813B,0x8073E02E,
74*86d7f5d3SJohn Marino   0xBEF83CCD,0x7B50A95A,0x05EE5862,0x00829ECE,0x8CA1958C,0xBE4EA2E2,
75*86d7f5d3SJohn Marino   0x4293BB73,0x656F7B23,0x417316D8,0x4467D7CF,0x2200E63B,0x109050C8,
76*86d7f5d3SJohn Marino   0x814CBE47,0x36B1D4A8,0x36AF9305,0x308327B3,0xEBCD7344,0xA738DE27,
77*86d7f5d3SJohn Marino   0x5A10C399,0x4142371D,0x64A18528,0x0B31E8B2,0x641057B9,0x6AFC363B,
78*86d7f5d3SJohn Marino   0x108AD953,0x9D4DA234,0x0C2D9159,0x1C8A1A1F,0x310C66BA,0x87AA1070,
79*86d7f5d3SJohn Marino   0xDAC832FF,0x0A433422,0x7AF15812,0x2D8D9BD0,0x995A25E9,0x25326CAC,
80*86d7f5d3SJohn Marino   0xA34384DB,0x4C8421CC,0x4F0315EC,0x29E8649E,0xA7732D6F,0x2E94D3E3,
81*86d7f5d3SJohn Marino   0x7D98A340,0x397C4D74,0x659DB4DE,0x747D4E9A,0xD9DB8435,0x4659DBE9,
82*86d7f5d3SJohn Marino   0x313E6DC5,0x29D104DC,0x9F226CBA,0x452F18B0,0xD0BC5068,0x844CA299,
83*86d7f5d3SJohn Marino   0x782B294E,0x4AE2EB7B,0xA4C475F8,0x70A81311,0x4B3E8BCC,0x7E20D4BA,
84*86d7f5d3SJohn Marino   0xABCA33C9,0x57BE2960,0x44F9B419,0x2E567746,0x72EB757A,0x102CC0E8,
85*86d7f5d3SJohn Marino   0xB07F32B9,0xD0DABD59,0xBA85AD6B,0xF3E20667,0x98D77D81,0x197AFA47,
86*86d7f5d3SJohn Marino   0x518EE9AC,0xE10CE5A2,0x01CF2C2A,0xD3A3AF3D,0x16DDFD65,0x669232F8,
87*86d7f5d3SJohn Marino   0x1C50A301,0xB93D9151,0x9354D3F4,0x847D79D0,0xD5FE2EC6,0x1F7B0610,
88*86d7f5d3SJohn Marino   0xFA6B90A5,0xC5879041,0x2E7DC05E,0x423F1F32,0xEF623DDB,0x49C13280,
89*86d7f5d3SJohn Marino   0x98714E92,0xC7B6E4AD,0xC4318466,0x0737F312,0x4D3C003F,0x9ACC1F1F,
90*86d7f5d3SJohn Marino   0x5F1C926D,0x085FA771,0x185A83A2,0xF9AA159D,0x0B0B0132,0xF98E7A43,
91*86d7f5d3SJohn Marino   0xCD9EBDBE,0x0190CB29,0x10D93FB6,0x3B8A4D97,0x66A65A41,0xE43E766F,
92*86d7f5d3SJohn Marino   0x77BE3C41,0xB9686364,0xCB36994D,0x6846A287,0x567E77F7,0x36178DD8,
93*86d7f5d3SJohn Marino   0xBDE6B1F2,0xB6EFDC64,0x82950324,0x42053F47,0xC09BE51C,0x0942D762,
94*86d7f5d3SJohn Marino   0x35F92C7F,0x367DEC61,0x6EE3D983,0xDBAAF78A,0x265D2C47,0x8EB4BF5C,
95*86d7f5d3SJohn Marino   0x33B232D7,0xB0137E77,0x373C39A7,0x8D2B2E76,0xC7510F01,0x50F9E032,
96*86d7f5d3SJohn Marino   0x7B1FDDDB,0x724C2AAE,0xB10ECB31,0xCCA3D1B8,0x7F0BCF10,0x4254BBBD,
97*86d7f5d3SJohn Marino   0xE3F93B97,0x2305039B,0x53120E22,0x1A2F3B9A,0x0FDDBD97,0x0118561E,
98*86d7f5d3SJohn Marino   0x0A798E13,0x9E0B3ACD,0xDB6C9F15,0xF512D0A2,0x9E8C3A28,0xEE2184AE,
99*86d7f5d3SJohn Marino   0x0051EC2F,0x2432F74F,0xB0AA66EA,0x55128D88,0xF7D83A38,0x4DAE8E82,
100*86d7f5d3SJohn Marino   0x3FDC98D6,0x5F0BD341,0x7244BE1D,0xC7B48E78,0x2D473053,0x43892E20,
101*86d7f5d3SJohn Marino   0xBA0F1F2A,0x524D4895,0x2E10BCB1,0x4C372D81,0x5C3E50CD,0xCF61CC2E,
102*86d7f5d3SJohn Marino   0x931709AB,0x81B3AEFC,0x39E9405E,0x7FFE108C,0x4FBB3FF8,0x06ABE450,
103*86d7f5d3SJohn Marino   0x7F5BF51E,0xA4E3CDFD,0xDB0F6C6F,0x159A1227,0x3B9FED55,0xD20B6F7F,
104*86d7f5d3SJohn Marino   0xFBE9CC83,0x64856619,0xBF52B8AF,0x9D7006B0,0x71165BC6,0xAE324AEE,
105*86d7f5d3SJohn Marino   0x29D27F2C,0x794C2086,0x74445CE2,0x782915CC,0xD4CE6886,0x3289AE7C,
106*86d7f5d3SJohn Marino   0x53DEF297,0x4185F7ED,0x88B72400,0x3C09DC11,0xBCE3AAB6,0x6A75934A,
107*86d7f5d3SJohn Marino   0xB267E399,0x000DF1BF,0x193BA5E2,0xFA3E1977,0x179E14F6,0x1EEDE298,
108*86d7f5d3SJohn Marino   0x691F0B06,0xB84F78AC,0xC1C15316,0xFFFF3AD6,0x0B457383,0x518CD612,
109*86d7f5d3SJohn Marino   0x05A00F3E,0xD5B7D275,0x4C5ECCD7,0xE02CD0BE,0x5558E9F2,0x0C89BBF0,
110*86d7f5d3SJohn Marino   0xA3D96227,0x2832D2B2,0xF667B897,0xD4556554,0xF9D2F01F,0xFA1E3FAE,
111*86d7f5d3SJohn Marino   0x52C2E1EE,0xE5451F31,0x7E849729,0xDABDB67A,0x54BF5E7E,0xF831C271,
112*86d7f5d3SJohn Marino   0x5F1A17E3,0x9D140AFE,0x92741C47,0x48CFABCE,0x9CBBE477,0x9C3EE57F,
113*86d7f5d3SJohn Marino   0xB07D4C39,0xCC21BCE2,0x697708B1,0x58DA2A6B,0x2370DB16,0x6E641948,
114*86d7f5d3SJohn Marino   0xACC5BD52,0x868F24CC,0xCA1DB0F5,0x4CADA492,0x3F443E54,0xC4A4D5E9,
115*86d7f5d3SJohn Marino   0xF00AD670,0xE93C86E0,0xFE90651A,0xDDE532A3,0xA66458DF,0xAB7D7151,
116*86d7f5d3SJohn Marino   0x0E2E775F,0xC9109F99,0x8D96D59F,0x73CEF14C,0xC74E88E9,0x02712DC0,
117*86d7f5d3SJohn Marino   0x04F41735,0x2E5914A2,0x59F4B2FB,0x0287FC83,0x80BC0343,0xF6B32559,
118*86d7f5d3SJohn Marino   0xC74178D4,0xF1D99123,0x383CCC07,0xACC0637D,0x0863A548,0xA6FCAC85,
119*86d7f5d3SJohn Marino   0x2A13EFF0,0xAF2EEDB1,0x41E72750,0xE0C6B342,0x5DA22B46,0x635559E0,
120*86d7f5d3SJohn Marino   0xD2EA40AC,0x10AA98C0,0x19096497,0x112C542B,0x2C85040C,0xA868E7D0,
121*86d7f5d3SJohn Marino   0x6E260188,0xF596D390,0xC3BB5D7A,0x7A2AA937,0xDFD15032,0x6780AE3B,
122*86d7f5d3SJohn Marino   0xDB5F9CD8,0x8BD266B0,0x7744AF12,0xB463B1B0,0x589629C9,0xE30DBC6E,
123*86d7f5d3SJohn Marino   0x880F5569,0x209E6E16,0x9DECA50C,0x02987A57,0xBED3EA57,0xD3A678AA,
124*86d7f5d3SJohn Marino   0x70DD030D,0x0CFD9C5D,0x92A18E99,0xF5740619,0x7F6F0A7D,0x134CAF9A,
125*86d7f5d3SJohn Marino   0x70F5BAE4,0x23DCA7B5,0x4D788FCD,0xC7F07847,0xBCF77DA1,0x9071D568,
126*86d7f5d3SJohn Marino   0xFC627EA1,0xAE004B77,0x66B54BCB,0x7EF2DAAC,0xDCD5AC30,0xB9BDF730,
127*86d7f5d3SJohn Marino   0x505A97A7,0x9D881FD3,0xADB796CC,0x94A1D202,0x97535D7F,0x31EC20C0,
128*86d7f5d3SJohn Marino   0xB1887A98,0xC1475069,0xA6F73AF3,0x71E4E067,0x46A569DE,0xD2ADE430,
129*86d7f5d3SJohn Marino   0x6F0762C7,0xF50876F4,0x53510542,0x03741C3E,0x53502224,0xD8E54D60,
130*86d7f5d3SJohn Marino   0x3C44AB1A,0x34972B46,0x74BFA89D,0xD7D768E0,0x37E605DC,0xE13D1BDF,
131*86d7f5d3SJohn Marino   0x5051C421,0xB9E057BE,0xB717A14C,0xA1730C43,0xB99638BE,0xB5D5F36D,
132*86d7f5d3SJohn Marino   0xE960D9EA,0x6B1388D3,0xECB6D3B6,0xBDBE8B83,0x2E29AFC5,0x764D71EC,
133*86d7f5d3SJohn Marino   0x4B8F4F43,0xC21DDC00,0xA63F657F,0x82678130,0xDBF535AC,0xA594FC58,
134*86d7f5d3SJohn Marino   0x942686BC,0xBD9B657B,0x4A0F9B61,0x44FF184F,0x38E10A2F,0x61910626,
135*86d7f5d3SJohn Marino   0x5E247636,0x7106D137,0xC62802F0,0xBD1D1F00,0x7CC0DCB2,0xED634909,
136*86d7f5d3SJohn Marino   0xDC13B24E,0x9799C499,0xD77E3D6A,0x14773B68,0x967A4FB7,0x35EECFB1,
137*86d7f5d3SJohn Marino   0x2A5110B8,0xE2F0AF94,0x9D09DEA5,0x20255D27,0x5771D34B,0xE1089EE4,
138*86d7f5d3SJohn Marino   0x246F330B,0x8F7CAEE5,0xD3064712,0x75CAFBEE,0xB94F7028,0xED953666,
139*86d7f5d3SJohn Marino   0x5D1975B4,0x5AF81271,0x13BE2025,0x85194659,0x30805331,0xEC9D46C0,
140*86d7f5d3SJohn Marino   0xBC027C36,0x2AF84188,0xC2141B80,0xC02B1E4A,0x04D36177,0xFC50E9D7,
141*86d7f5d3SJohn Marino   0x39CE79DA,0x917E0A00,0xEF7A0BF4,0xA98BD8D1,0x19424DD2,0x9439DF1F,
142*86d7f5d3SJohn Marino   0xC42AF746,0xADDBE83E,0x85221F0D,0x45563E90,0x9095EC52,0x77887B25,
143*86d7f5d3SJohn Marino   0x8AE46064,0xBD43B71A,0xBB541956,0x7366CF9D,0xEE8E1737,0xB5A727C9,
144*86d7f5d3SJohn Marino   0x5076B3E7,0xFC70BACA,0xCE135B75,0xC4E91AA3,0xF0341911,0x53430C3F,
145*86d7f5d3SJohn Marino   0x886B0824,0x6BB5B8B7,0x33E21254,0xF193B456,0x5B09617F,0x215FFF50,
146*86d7f5d3SJohn Marino   0x48D97EF1,0x356479AB,0x6EA9DDC4,0x0D352746,0xA2F5CE43,0xB226A1B3,
147*86d7f5d3SJohn Marino   0x1329EA3C,0x7A337CC2,0xB5CCE13D,0x563E3B5B,0x534E8E8F,0x561399C9,
148*86d7f5d3SJohn Marino   0xE1596392,0xB0F03125,0x4586645B,0x1F371847,0x94EAABD1,0x41F97EDD,
149*86d7f5d3SJohn Marino   0xE3E5A39B,0x71C774E2,0x507296F4,0x5960133B,0x7852C494,0x3F5B2691,
150*86d7f5d3SJohn Marino   0xA3F87774,0x5A7AF89E,0x17DA3F28,0xE9D9516D,0xFCC1C1D5,0xE4618628,
151*86d7f5d3SJohn Marino   0x04081047,0xD8E4DB5F,0xDC380416,0x8C4933E2,0x95074D53,0xB1B0032D,
152*86d7f5d3SJohn Marino   0xCC8102EA,0x71641243,0x98D6EB6A,0x90FEC945,0xA0914345,0x6FAB037D,
153*86d7f5d3SJohn Marino   0x70F49C4D,0x05BF5B0E,0x927AAF7F,0xA1940F61,0xFEE0756F,0xF815369F,
154*86d7f5d3SJohn Marino   0x5C00253B,0xF2B9762F,0x4AEB3CCC,0x1069F386,0xFBA4E7B9,0x70332665,
155*86d7f5d3SJohn Marino   0x6BCA810E,0x85AB8058,0xAE4B2B2F,0x9D120712,0xBEE8EACB,0x776A1112
156*86d7f5d3SJohn Marino };
157*86d7f5d3SJohn Marino 
158*86d7f5d3SJohn Marino void
__gmp_mt_recalc_buffer(gmp_uint_least32_t mt[])159*86d7f5d3SJohn Marino __gmp_mt_recalc_buffer (gmp_uint_least32_t mt[])
160*86d7f5d3SJohn Marino {
161*86d7f5d3SJohn Marino   gmp_uint_least32_t y;
162*86d7f5d3SJohn Marino   int kk;
163*86d7f5d3SJohn Marino 
164*86d7f5d3SJohn Marino   for (kk = 0; kk < N - M; kk++)
165*86d7f5d3SJohn Marino     {
166*86d7f5d3SJohn Marino       y = (mt[kk] & 0x80000000) | (mt[kk + 1] & 0x7FFFFFFF);
167*86d7f5d3SJohn Marino       mt[kk] = mt[kk + M] ^ (y >> 1) ^ ((y & 0x01) != 0 ? MATRIX_A : 0);
168*86d7f5d3SJohn Marino     }
169*86d7f5d3SJohn Marino   for (; kk < N - 1; kk++)
170*86d7f5d3SJohn Marino     {
171*86d7f5d3SJohn Marino       y = (mt[kk] & 0x80000000) | (mt[kk + 1] & 0x7FFFFFFF);
172*86d7f5d3SJohn Marino       mt[kk] = mt[kk - (N - M)] ^ (y >> 1) ^ ((y & 0x01) != 0 ? MATRIX_A : 0);
173*86d7f5d3SJohn Marino     }
174*86d7f5d3SJohn Marino 
175*86d7f5d3SJohn Marino   y = (mt[N - 1] & 0x80000000) | (mt[0] & 0x7FFFFFFF);
176*86d7f5d3SJohn Marino   mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ ((y & 0x01) != 0 ? MATRIX_A : 0);
177*86d7f5d3SJohn Marino }
178*86d7f5d3SJohn Marino 
179*86d7f5d3SJohn Marino 
180*86d7f5d3SJohn Marino /* Get nbits bits of output from the generator into dest.
181*86d7f5d3SJohn Marino    Note that Mersenne Twister is designed to produce outputs in
182*86d7f5d3SJohn Marino    32-bit words.  */
183*86d7f5d3SJohn Marino void
__gmp_randget_mt(gmp_randstate_t rstate,mp_ptr dest,unsigned long int nbits)184*86d7f5d3SJohn Marino __gmp_randget_mt (gmp_randstate_t rstate, mp_ptr dest, unsigned long int nbits)
185*86d7f5d3SJohn Marino {
186*86d7f5d3SJohn Marino   gmp_uint_least32_t y;
187*86d7f5d3SJohn Marino   int rbits;
188*86d7f5d3SJohn Marino   mp_size_t i;
189*86d7f5d3SJohn Marino   mp_size_t nlimbs;
190*86d7f5d3SJohn Marino   int *pmti;
191*86d7f5d3SJohn Marino   gmp_uint_least32_t *mt;
192*86d7f5d3SJohn Marino 
193*86d7f5d3SJohn Marino   pmti = &((gmp_rand_mt_struct *) RNG_STATE (rstate))->mti;
194*86d7f5d3SJohn Marino   mt = ((gmp_rand_mt_struct *) RNG_STATE (rstate))->mt;
195*86d7f5d3SJohn Marino 
196*86d7f5d3SJohn Marino   nlimbs = nbits / GMP_NUMB_BITS;
197*86d7f5d3SJohn Marino   rbits = nbits % GMP_NUMB_BITS;
198*86d7f5d3SJohn Marino 
199*86d7f5d3SJohn Marino #define NEXT_RANDOM			\
200*86d7f5d3SJohn Marino   do					\
201*86d7f5d3SJohn Marino     {					\
202*86d7f5d3SJohn Marino       if (*pmti >= N)			\
203*86d7f5d3SJohn Marino 	{				\
204*86d7f5d3SJohn Marino 	  __gmp_mt_recalc_buffer (mt);  \
205*86d7f5d3SJohn Marino 	  *pmti = 0;			\
206*86d7f5d3SJohn Marino 	}				\
207*86d7f5d3SJohn Marino       y = mt[(*pmti)++];		\
208*86d7f5d3SJohn Marino       y ^= (y >> 11);			\
209*86d7f5d3SJohn Marino       y ^= (y << 7) & MASK_1;		\
210*86d7f5d3SJohn Marino       y ^= (y << 15) & MASK_2;		\
211*86d7f5d3SJohn Marino       y ^= (y >> 18);			\
212*86d7f5d3SJohn Marino     }					\
213*86d7f5d3SJohn Marino   while (0)
214*86d7f5d3SJohn Marino 
215*86d7f5d3SJohn Marino 
216*86d7f5d3SJohn Marino   /* Handle the common cases of 32- or 64-bit limbs with fast,
217*86d7f5d3SJohn Marino      optimized routines, and the rest of cases with a general
218*86d7f5d3SJohn Marino      routine.  In all cases, no more than 31 bits are rejected
219*86d7f5d3SJohn Marino      for the last limb so that every version of the code is
220*86d7f5d3SJohn Marino      consistent with the others.  */
221*86d7f5d3SJohn Marino 
222*86d7f5d3SJohn Marino #if (GMP_NUMB_BITS == 32)
223*86d7f5d3SJohn Marino 
224*86d7f5d3SJohn Marino   for (i = 0; i < nlimbs; i++)
225*86d7f5d3SJohn Marino     {
226*86d7f5d3SJohn Marino       NEXT_RANDOM;
227*86d7f5d3SJohn Marino       dest[i] = (mp_limb_t) y;
228*86d7f5d3SJohn Marino     }
229*86d7f5d3SJohn Marino   if (rbits)
230*86d7f5d3SJohn Marino     {
231*86d7f5d3SJohn Marino       NEXT_RANDOM;
232*86d7f5d3SJohn Marino       dest[nlimbs] = (mp_limb_t) (y & ~(ULONG_MAX << rbits));
233*86d7f5d3SJohn Marino     }
234*86d7f5d3SJohn Marino 
235*86d7f5d3SJohn Marino #else /* GMP_NUMB_BITS != 32 */
236*86d7f5d3SJohn Marino #if (GMP_NUMB_BITS == 64)
237*86d7f5d3SJohn Marino 
238*86d7f5d3SJohn Marino   for (i = 0; i < nlimbs; i++)
239*86d7f5d3SJohn Marino     {
240*86d7f5d3SJohn Marino       NEXT_RANDOM;
241*86d7f5d3SJohn Marino       dest[i] = (mp_limb_t) y;
242*86d7f5d3SJohn Marino       NEXT_RANDOM;
243*86d7f5d3SJohn Marino       dest[i] |= (mp_limb_t) y << 32;
244*86d7f5d3SJohn Marino     }
245*86d7f5d3SJohn Marino   if (rbits)
246*86d7f5d3SJohn Marino     {
247*86d7f5d3SJohn Marino       if (rbits < 32)
248*86d7f5d3SJohn Marino 	{
249*86d7f5d3SJohn Marino 	  NEXT_RANDOM;
250*86d7f5d3SJohn Marino 	  dest[nlimbs] = (mp_limb_t) (y & ~(ULONG_MAX << rbits));
251*86d7f5d3SJohn Marino 	}
252*86d7f5d3SJohn Marino       else
253*86d7f5d3SJohn Marino 	{
254*86d7f5d3SJohn Marino 	  NEXT_RANDOM;
255*86d7f5d3SJohn Marino 	  dest[nlimbs] = (mp_limb_t) y;
256*86d7f5d3SJohn Marino 	  if (rbits > 32)
257*86d7f5d3SJohn Marino 	    {
258*86d7f5d3SJohn Marino 	      NEXT_RANDOM;
259*86d7f5d3SJohn Marino 	      dest[nlimbs] |=
260*86d7f5d3SJohn Marino 		((mp_limb_t) (y & ~(ULONG_MAX << (rbits-32)))) << 32;
261*86d7f5d3SJohn Marino 	    }
262*86d7f5d3SJohn Marino 	}
263*86d7f5d3SJohn Marino     }
264*86d7f5d3SJohn Marino 
265*86d7f5d3SJohn Marino #else /* GMP_NUMB_BITS != 64 */
266*86d7f5d3SJohn Marino 
267*86d7f5d3SJohn Marino   {
268*86d7f5d3SJohn Marino     /* Fall back to a general algorithm.  This algorithm works by
269*86d7f5d3SJohn Marino        keeping a pool of up to 64 bits (2 outputs from MT) acting
270*86d7f5d3SJohn Marino        as a shift register from which bits are consumed as needed.
271*86d7f5d3SJohn Marino        Bits are consumed using the LSB bits of bitpool_l, and
272*86d7f5d3SJohn Marino        inserted via bitpool_h and shifted to the right place.  */
273*86d7f5d3SJohn Marino 
274*86d7f5d3SJohn Marino     gmp_uint_least32_t bitpool_h = 0;
275*86d7f5d3SJohn Marino     gmp_uint_least32_t bitpool_l = 0;
276*86d7f5d3SJohn Marino     int bits_in_pool = 0;	/* Holds number of valid bits in the pool.  */
277*86d7f5d3SJohn Marino     int bits_to_fill;		/* Holds total number of bits to put in
278*86d7f5d3SJohn Marino 				   destination.  */
279*86d7f5d3SJohn Marino     int bitidx;			/* Holds the destination bit position.  */
280*86d7f5d3SJohn Marino     mp_size_t nlimbs2;		/* Number of whole+partial limbs to fill.  */
281*86d7f5d3SJohn Marino 
282*86d7f5d3SJohn Marino     nlimbs2 = nlimbs + (rbits != 0);
283*86d7f5d3SJohn Marino 
284*86d7f5d3SJohn Marino     for (i = 0; i < nlimbs2; i++)
285*86d7f5d3SJohn Marino       {
286*86d7f5d3SJohn Marino 	bitidx = 0;
287*86d7f5d3SJohn Marino 	if (i < nlimbs)
288*86d7f5d3SJohn Marino 	  bits_to_fill = GMP_NUMB_BITS;
289*86d7f5d3SJohn Marino 	else
290*86d7f5d3SJohn Marino 	  bits_to_fill = rbits;
291*86d7f5d3SJohn Marino 
292*86d7f5d3SJohn Marino 	dest[i] = CNST_LIMB (0);
293*86d7f5d3SJohn Marino 	while (bits_to_fill >= 32) /* Process whole 32-bit blocks first.  */
294*86d7f5d3SJohn Marino 	  {
295*86d7f5d3SJohn Marino 	    if (bits_in_pool < 32)	/* Need more bits.  */
296*86d7f5d3SJohn Marino 	      {
297*86d7f5d3SJohn Marino 		/* 64-bit right shift.  */
298*86d7f5d3SJohn Marino 		NEXT_RANDOM;
299*86d7f5d3SJohn Marino 		bitpool_h = y;
300*86d7f5d3SJohn Marino 		bitpool_l |= (bitpool_h << bits_in_pool) & 0xFFFFFFFF;
301*86d7f5d3SJohn Marino 		if (bits_in_pool == 0)
302*86d7f5d3SJohn Marino 		  bitpool_h = 0;
303*86d7f5d3SJohn Marino 		else
304*86d7f5d3SJohn Marino 		  bitpool_h >>= 32 - bits_in_pool;
305*86d7f5d3SJohn Marino 		bits_in_pool += 32;	/* We've got 32 more bits.  */
306*86d7f5d3SJohn Marino 	      }
307*86d7f5d3SJohn Marino 
308*86d7f5d3SJohn Marino 	    /* Fill a 32-bit chunk.  */
309*86d7f5d3SJohn Marino 	    dest[i] |= ((mp_limb_t) bitpool_l) << bitidx;
310*86d7f5d3SJohn Marino 	    bitpool_l = bitpool_h;
311*86d7f5d3SJohn Marino 	    bits_in_pool -= 32;
312*86d7f5d3SJohn Marino 	    bits_to_fill -= 32;
313*86d7f5d3SJohn Marino 	    bitidx += 32;
314*86d7f5d3SJohn Marino 	  }
315*86d7f5d3SJohn Marino 
316*86d7f5d3SJohn Marino 	/* Cover the case where GMP_NUMB_BITS is not a multiple of 32.  */
317*86d7f5d3SJohn Marino 	if (bits_to_fill != 0)
318*86d7f5d3SJohn Marino 	  {
319*86d7f5d3SJohn Marino 	    if (bits_in_pool < bits_to_fill)
320*86d7f5d3SJohn Marino 	      {
321*86d7f5d3SJohn Marino 		NEXT_RANDOM;
322*86d7f5d3SJohn Marino 		bitpool_h = y;
323*86d7f5d3SJohn Marino 		bitpool_l |= (bitpool_h << bits_in_pool) & 0xFFFFFFFF;
324*86d7f5d3SJohn Marino 		if (bits_in_pool == 0)
325*86d7f5d3SJohn Marino 		  bitpool_h = 0;
326*86d7f5d3SJohn Marino 		else
327*86d7f5d3SJohn Marino 		  bitpool_h >>= 32 - bits_in_pool;
328*86d7f5d3SJohn Marino 		bits_in_pool += 32;
329*86d7f5d3SJohn Marino 	      }
330*86d7f5d3SJohn Marino 
331*86d7f5d3SJohn Marino 	    dest[i] |= (((mp_limb_t) bitpool_l
332*86d7f5d3SJohn Marino 			 & ~(~CNST_LIMB (0) << bits_to_fill))
333*86d7f5d3SJohn Marino 			<< bitidx);
334*86d7f5d3SJohn Marino 	    bitpool_l = ((bitpool_l >> bits_to_fill)
335*86d7f5d3SJohn Marino 			 | (bitpool_h << (32 - bits_to_fill))) & 0xFFFFFFFF;
336*86d7f5d3SJohn Marino 	    bitpool_h >>= bits_to_fill;
337*86d7f5d3SJohn Marino 	    bits_in_pool -= bits_to_fill;
338*86d7f5d3SJohn Marino 	  }
339*86d7f5d3SJohn Marino       }
340*86d7f5d3SJohn Marino   }
341*86d7f5d3SJohn Marino 
342*86d7f5d3SJohn Marino #endif /* GMP_NUMB_BITS != 64 */
343*86d7f5d3SJohn Marino #endif /* GMP_NUMB_BITS != 32 */
344*86d7f5d3SJohn Marino }
345*86d7f5d3SJohn Marino 
346*86d7f5d3SJohn Marino void
__gmp_randclear_mt(gmp_randstate_t rstate)347*86d7f5d3SJohn Marino __gmp_randclear_mt (gmp_randstate_t rstate)
348*86d7f5d3SJohn Marino {
349*86d7f5d3SJohn Marino   (*__gmp_free_func) ((void *) RNG_STATE (rstate),
350*86d7f5d3SJohn Marino 		      ALLOC (rstate->_mp_seed) * BYTES_PER_MP_LIMB);
351*86d7f5d3SJohn Marino }
352*86d7f5d3SJohn Marino 
353*86d7f5d3SJohn Marino void __gmp_randiset_mt __GMP_PROTO ((gmp_randstate_ptr dst, gmp_randstate_srcptr src));
354*86d7f5d3SJohn Marino 
355*86d7f5d3SJohn Marino static const gmp_randfnptr_t Mersenne_Twister_Generator_Noseed = {
356*86d7f5d3SJohn Marino   NULL,
357*86d7f5d3SJohn Marino   __gmp_randget_mt,
358*86d7f5d3SJohn Marino   __gmp_randclear_mt,
359*86d7f5d3SJohn Marino   __gmp_randiset_mt
360*86d7f5d3SJohn Marino };
361*86d7f5d3SJohn Marino 
362*86d7f5d3SJohn Marino void
__gmp_randiset_mt(gmp_randstate_ptr dst,gmp_randstate_srcptr src)363*86d7f5d3SJohn Marino __gmp_randiset_mt (gmp_randstate_ptr dst, gmp_randstate_srcptr src)
364*86d7f5d3SJohn Marino {
365*86d7f5d3SJohn Marino   const mp_size_t sz = ((sizeof (gmp_rand_mt_struct) - 1) / BYTES_PER_MP_LIMB) + 1;
366*86d7f5d3SJohn Marino   gmp_rand_mt_struct *dstp, *srcp;
367*86d7f5d3SJohn Marino   mp_size_t i;
368*86d7f5d3SJohn Marino 
369*86d7f5d3SJohn Marino   /* Set the generator functions.  */
370*86d7f5d3SJohn Marino   RNG_FNPTR (dst) = (void *) &Mersenne_Twister_Generator_Noseed;
371*86d7f5d3SJohn Marino 
372*86d7f5d3SJohn Marino   /* Allocate the MT-specific state.  */
373*86d7f5d3SJohn Marino   dstp = (gmp_rand_mt_struct *) __GMP_ALLOCATE_FUNC_LIMBS (sz);
374*86d7f5d3SJohn Marino   RNG_STATE (dst) = (mp_ptr) dstp;
375*86d7f5d3SJohn Marino   ALLOC (dst->_mp_seed) = sz;     /* Initialize alloc field to placate Camm.  */
376*86d7f5d3SJohn Marino 
377*86d7f5d3SJohn Marino   /* Copy state.  */
378*86d7f5d3SJohn Marino   srcp = (gmp_rand_mt_struct *) RNG_STATE (src);
379*86d7f5d3SJohn Marino   for (i = 0; i < N; i++)
380*86d7f5d3SJohn Marino     dstp->mt[i] = srcp->mt[i];
381*86d7f5d3SJohn Marino 
382*86d7f5d3SJohn Marino   dstp->mti = srcp->mti;
383*86d7f5d3SJohn Marino }
384*86d7f5d3SJohn Marino 
385*86d7f5d3SJohn Marino void
__gmp_randinit_mt_noseed(gmp_randstate_ptr dst)386*86d7f5d3SJohn Marino __gmp_randinit_mt_noseed (gmp_randstate_ptr dst)
387*86d7f5d3SJohn Marino {
388*86d7f5d3SJohn Marino   const mp_size_t sz = ((sizeof (gmp_rand_mt_struct) - 1) / BYTES_PER_MP_LIMB) + 1;
389*86d7f5d3SJohn Marino   gmp_rand_mt_struct *dstp;
390*86d7f5d3SJohn Marino   mp_size_t i;
391*86d7f5d3SJohn Marino 
392*86d7f5d3SJohn Marino   /* Set the generator functions.  */
393*86d7f5d3SJohn Marino   RNG_FNPTR (dst) = (void *) &Mersenne_Twister_Generator_Noseed;
394*86d7f5d3SJohn Marino 
395*86d7f5d3SJohn Marino   /* Allocate the MT-specific state.  */
396*86d7f5d3SJohn Marino   dstp = (gmp_rand_mt_struct *) __GMP_ALLOCATE_FUNC_LIMBS (sz);
397*86d7f5d3SJohn Marino   RNG_STATE (dst) = (mp_ptr) dstp;
398*86d7f5d3SJohn Marino   ALLOC (dst->_mp_seed) = sz;     /* Initialize alloc field to placate Camm.  */
399*86d7f5d3SJohn Marino 
400*86d7f5d3SJohn Marino   /* Set state for default seed.  */
401*86d7f5d3SJohn Marino   for (i = 0; i < N; i++)
402*86d7f5d3SJohn Marino     dstp->mt[i] = default_state[i];
403*86d7f5d3SJohn Marino 
404*86d7f5d3SJohn Marino   dstp->mti = WARM_UP % N;
405*86d7f5d3SJohn Marino }
406