1 /*
2  * mpi-test.c
3  *
4  * This is a general test suite for the MPI library, which tests
5  * all the functions in the library with known values.  The program
6  * exits with a zero (successful) status if the tests pass, or a
7  * nonzero status if the tests fail.
8  *
9  * This Source Code Form is subject to the terms of the Mozilla Public
10  * License, v. 2.0. If a copy of the MPL was not distributed with this
11  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <stdarg.h>
17 #include <limits.h>
18 #include <time.h>
19 
20 #include "mpi.h"
21 #include "mpprime.h"
22 
23 #include "test-info.c"
24 
25 /* ZS means Zero Suppressed (no leading zeros) */
26 #if MP_USE_LONG_DIGIT
27 #define ZS_DIGIT_FMT "%lX"
28 #elif MP_USE_LONG_LONG_DIGIT
29 #define ZS_DIGIT_FMT "%llX"
30 #elif MP_USE_UINT_DIGIT
31 #define ZS_DIGIT_FMT "%X"
32 #else
33 #error "unknown type of digit"
34 #endif
35 
36 /*
37   Test vectors
38 
39   If you intend to change any of these values, you must also recompute
40   the corresponding solutions below.  Basically, these are just hex
41   strings (for the big integers) or integer values (for the digits).
42 
43   The comparison tests think they know what relationships hold between
44   these values.  If you change that, you may have to adjust the code
45   for the comparison tests accordingly.  Most of the other tests
46   should be fine as long as you re-compute the solutions, though.
47  */
48 const char *mp1 = "639A868CDA0C569861B";
49 const char *mp2 = "AAFC0A3FE45E5E09DBE2C29";
50 const char *mp3 = "B55AA8DF8A7E83241F38AC7A9E479CAEF2E4D7C5";
51 const char *mp4 = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
52 const char *mp5 = "F595CB42";
53 const char *mp5a = "-4B597E";
54 const char *mp6 = "0";
55 const char *mp7 = "EBFA7121CD838CE6439CC59DDB4CBEF3";
56 const char *mp8 = "5";
57 const char *mp9 = "F74A2876A1432698923B0767DA19DCF3D71795EE";
58 const char *mp10 = "9184E72A000";
59 const char *mp11 = "54D79A3557E8";
60 const char *mp12 = "10000000000000000";
61 const char *mp13 =
62     "34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342BDAB6163963C"
63     "D5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45F2B050D226E6DA88";
64 const char *mp14 =
65     "AC3FA0EABAAC45724814D798942A1E28E14C81E0DE8055CED630E7689DA648683645DB6E"
66     "458D9F5338CC3D4E33A5D1C9BF42780133599E60DEE0049AFA8F9489501AE5C9AA2B8C13"
67     "FD21285A538B2CA87A626BB56E0A654C8707535E637FF4E39174157402BDE3AA30C9F134"
68     "0C1307BAA864B075A9CC828B6A5E2B2BF1AE406D920CC5E7657D7C0E697DEE5375773AF9"
69     "E200A1B8FAD7CD141F9EE47ABB55511FEB9A4D99EBA22F3A3FF6792FA7EE9E5DC0EE94F7"
70     "7A631EDF3D7DD7C2DAAAFDF234D60302AB63D5234CEAE941B9AF0ADDD9E6E3A940A94EE5"
71     "5DB45A7C66E61EDD0477419BBEFA44C325129601C4F45671C6A0E64665DF341D17FBC71F"
72     "77418BD9F4375DDB3B9D56126526D8E5E0F35A121FD4F347013DA880020A752324F31DDD"
73     "9BCDB13A3B86E207A2DE086825E6EEB87B3A64232CFD8205B799BC018634AAE193F19531"
74     "D6EBC19A75F27CFFAA03EB5974898F53FD569AA5CE60F431B53B0CDE715A5F382405C9C4"
75     "761A8E24888328F09F7BCE4E8D80C957DF177629C8421ACCD0C268C63C0DD47C3C0D954F"
76     "D79F7D7297C6788DF4B3E51381759864D880ACA246DF09533739B8BB6085EAF7AE8DC2D9"
77     "F224E6874926C8D24D34B457FD2C9A586C6B99582DC24F787A39E3942786CF1D494B6EB4"
78     "A513498CDA0B217C4E80BCE7DA1C704C35E071AC21E0DA9F57C27C3533F46A8D20B04137"
79     "C1B1384BE4B2EB46";
80 const char *mp15 =
81     "39849CF7FD65AF2E3C4D87FE5526221103D90BA26A6642FFE3C3ECC0887BBBC57E011BF1"
82     "05D822A841653509C68F79EBE51C0099B8CBB04DEF31F36F5954208A3209AC122F0E11D8"
83     "4AE67A494D78336A2066D394D42E27EF6B03DDAF6D69F5112C93E714D27C94F82FC7EF77"
84     "445768C68EAE1C4A1407BE1B303243391D325090449764AE469CC53EC8012C4C02A72F37"
85     "07ED7275D2CC8D0A14B5BCC6BF264941520EBA97E3E6BAE4EE8BC87EE0DDA1F5611A6ECB"
86     "65F8AEF4F184E10CADBDFA5A2FEF828901D18C20785E5CC63473D638762DA80625003711"
87     "9E984AC43E707915B133543AF9D5522C3E7180DC58E1E5381C1FB7DC6A5F4198F3E88FA6"
88     "CBB6DFA8B2D1C763226B253E18BCCB79A29EE82D2DE735078C8AE3C3C86D476AAA08434C"
89     "09C274BDD40A1D8FDE38D6536C22F44E807EB73DE4FB36C9F51E0BC835DDBE3A8EFCF2FE"
90     "672B525769DC39230EE624D5EEDBD837C82A52E153F37378C3AD68A81A7ADBDF3345DBCE"
91     "8FA18CA1DE618EF94DF72EAD928D4F45B9E51632ACF158CF8332C51891D1D12C2A7E6684"
92     "360C4BF177C952579A9F442CFFEC8DAE4821A8E7A31C4861D8464CA9116C60866C5E72F7"
93     "434ADBED36D54ACDFDFF70A4EFB46E285131FE725F1C637D1C62115EDAD01C4189716327"
94     "BFAA79618B1656CBFA22C2C965687D0381CC2FE0245913C4D8D96108213680BD8E93E821"
95     "822AD9DDBFE4BD04";
96 const char *mp16 = "4A724340668DB150339A70";
97 const char *mp17 = "8ADB90F58";
98 const char *mp18 = "C64C230AB20E5";
99 const char *mp19 =
100     "F1C9DACDA287F2E3C88DCE2393B8F53DAAAC1196DC36510962B6B59454CFE64B";
101 const char *mp20 =
102     "D445662C8B6FE394107B867797750C326E0F4A967E135FC430F6CD7207913AC7";
103 const char *mp21 = "2";
104 
105 const mp_digit md1 = 0;
106 const mp_digit md2 = 0x1;
107 const mp_digit md3 = 0x80;
108 const mp_digit md4 = 0x9C97;
109 const mp_digit md5 = 0xF5BF;
110 const mp_digit md6 = 0x14A0;
111 const mp_digit md7 = 0x03E8;
112 const mp_digit md8 = 0x0101;
113 const mp_digit md9 = 0xA;
114 
115 /*
116    Solutions of the form x_mpABC, where:
117 
118    x = (p)roduct, (s)um, (d)ifference, (q)uotient, (r)emainder, (g)cd,
119        (i)nverse, (e)xponent, square roo(t), (g)cd, (l)cm.  A
120        leading 'm' indicates a modular operation, e.g. ms_mp12 is the
121        modular sum of operands 1 and 2
122 
123    ABC are the operand numbers involved in the computation.  If a 'd'
124    precedes the number, it is a digit operand; if a 'c' precedes it,
125    it is a constant; otherwise, it is a full integer.
126  */
127 
128 const char *p_mp12 = "4286AD72E095C9FE009938750743174ADDD7FD1E53";
129 const char *p_mp34 = "-46BDBD66CA108C94A8CF46C325F7B6E2F2BA82D35"
130                      "A1BFD6934C441EE369B60CA29BADC26845E918B";
131 const char *p_mp57 = "E260C265A0A27C17AD5F4E59D6E0360217A2EBA6";
132 const char *p_mp22 = "7233B5C1097FFC77CCF55928FDC3A5D31B712FDE7A1E91";
133 const char *p_mp1d4 = "3CECEA2331F4220BEF68DED";
134 const char *p_mp8d6 = "6720";
135 const char *p_mp1113 =
136     "11590FC3831C8C3C51813142C88E566408DB04F9E27642F6471A1822E0100B12F7F1"
137     "5699A127C0FA9D26DCBFF458522661F30C6ADA4A07C8C90F9116893F6DBFBF24C3A2"
138     "4340";
139 const char *p_mp1415 =
140     "26B36540DE8B3586699CCEAE218A2842C7D5A01590E70C4A26E789107FBCDB06AA2C"
141     "6DDC39E6FA18B16FCB2E934C9A5F844DAD60EE3B1EA82199EC5E9608F67F860FB965"
142     "736055DF0E8F2540EB28D07F47E309B5F5D7C94FF190AB9C83A6970160CA700B1081"
143     "F60518132AF28C6CEE6B7C473E461ABAC52C39CED50A08DD4E7EA8BA18DAD545126D"
144     "A388F6983C29B6BE3F9DCBC15766E8E6D626A92C5296A9C4653CAE5788350C0E2107"
145     "F57E5E8B6994C4847D727FF1A63A66A6CEF42B9C9E6BD04C92550B85D5527DE8A132"
146     "E6BE89341A9285C7CE7FB929D871BBCBD0ED2863B6B078B0DBB30FCA66D6C64284D6"
147     "57F394A0271E15B6EC7A9D530EBAC6CA262EF6F97E1A29FCE7749240E4AECA591ECF"
148     "272122BC587370F9371B67BB696B3CDC1BC8C5B64B6280994EBA00CDEB8EB0F5D06E"
149     "18F401D65FDCECF23DD7B9BB5B4C5458AEF2CCC09BA7F70EACB844750ACFD027521E"
150     "2E047DE8388B35F8512D3DA46FF1A12D4260213602BF7BFFDB6059439B1BD0676449"
151     "8D98C74F48FB3F548948D5BA0C8ECFCD054465132DC43466D6BBD59FBAF8D6D4E157"
152     "2D612B40A956C7D3E140F3B8562EF18568B24D335707D5BAC7495014DF2444172426"
153     "FD099DED560D30D1F945386604AFC85C64BD1E5F531F5C7840475FC0CF0F79810012"
154     "4572BAF5A9910CDBD02B27FFCC3C7E5E88EF59F3AE152476E33EDA696A4F751E0AE4"
155     "A3D2792DEA78E25B9110E12A19EFD09EA47FF9D6594DA445478BEB6901EAF8A35B2D"
156     "FD59BEE9BF7AA8535B7D326EFA5AA2121B5EBE04DD85827A3D43BD04F4AA6D7B62A2"
157     "B6D7A3077286A511A431E1EF75FCEBA3FAE9D5843A8ED17AA02BBB1B571F904699C5"
158     "A6073F87DDD012E2322AB3F41F2A61F428636FE86914148E19B8EF8314ED83332F2F"
159     "8C2ADE95071E792C0A68B903E060DD322A75FD0C2B992059FCCBB58AFA06B50D1634"
160     "BBD93F187FCE0566609FCC2BABB269C66CEB097598AA17957BB4FDA3E64A1B30402E"
161     "851CF9208E33D52E459A92C63FBB66435BB018E155E2C7F055E0B7AB82CD58FC4889"
162     "372ED9EEAC2A07E8E654AB445B9298D2830D6D4DFD117B9C8ABE3968927DC24B3633"
163     "BAD6E6466DB45DDAE87A0AB00336AC2CCCE176704F7214FCAB55743AB76C2B6CA231"
164     "7984610B27B5786DE55C184DDF556EDFEA79A3652831940DAD941E243F482DC17E50"
165     "284BC2FB1AD712A92542C573E55678878F02DFD9E3A863C7DF863227AEDE14B47AD3"
166     "957190124820ADC19F5353878EDB6BF7D0C77352A6E3BDB53EEB88F5AEF6226D6E68"
167     "756776A8FB49B77564147A641664C2A54F7E5B680CCC6A4D22D894E464DF20537094"
168     "548F1732452F9E7F810C0B4B430C073C0FBCE03F0D03F82630654BCE166AA772E1EE"
169     "DD0C08D3E3EBDF0AF54203B43AFDFC40D8FC79C97A4B0A4E1BEB14D8FCEFDDED8758"
170     "6ED65B18";
171 const char *p_mp2121 = "4";
172 const char *mp_mp345 = "B9B6D3A3";
173 const char *mp_mp335 = "16609C2D";
174 
175 const char *s_mp13 = "B55AA8DF8A7E83241F38B2B446B06A4FB84E5DE0";
176 const char *s_mp34 = "517EE6B92EF65C965736EB6BF7C325F73504CEB6";
177 const char *s_mp46 = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
178 const char *s_mp5d4 = "F59667D9";
179 const char *s_mp2d5 = "AAFC0A3FE45E5E09DBF21E8";
180 const char *s_mp1415 =
181     "E5C43DE2B811F4A084625F96E9504039E5258D8348E698CEB9F4D4292622042DB446"
182     "F75F4B65C1FB7A317257FA354BB5A45E789AEC254EAECE11F80A53E3B513822491DB"
183     "D9399DEC4807A2A3A10360129AC93F4A42388D3BF20B310DD0E9E9F4BE07FC88D53A"
184     "78A26091E0AB506A70813712CCBFBDD440A69A906E650EE090FDD6A42A95AC1A414D"
185     "317F1A9F781E6A30E9EE142ECDA45A1E3454A1417A7B9A613DA90831CF88EA1F2E82"
186     "41AE88CC4053220903C2E05BCDD42F02B8CF8868F84C64C5858BAD356143C5494607"
187     "EE22E11650148BAF65A985F6FC4CA540A55697F2B5AA95D6B8CF96EF638416DE1DD6"
188     "3BA9E2C09E22D03E75B60BE456C642F86B82A709253E5E087B507DE3A45F8392423F"
189     "4DBC284E8DC88C43CA77BC8DCEFB6129A59025F80F90FF978116DEBB9209E306FBB9"
190     "1B6111F8B8CFACB7C7C9BC12691C22EE88303E1713F1DFCEB622B8EA102F6365678B"
191     "C580ED87225467AA78E875868BD53B17574BA59305BC1AC666E4B7E9ED72FCFC200E"
192     "189D98FC8C5C7533739C53F52DDECDDFA5A8668BFBD40DABC9640F8FCAE58F532940"
193     "8162261320A25589E9FB51B50F80056471F24B7E1AEC35D1356FC2747FFC13A04B34"
194     "24FCECE10880BD9D97CA8CDEB2F5969BF4F30256EB5ED2BCD1DC64BDC2EE65217848"
195     "48A37FB13F84ED4FB7ACA18C4639EE64309BDD3D552AEB4AAF44295943DC1229A497"
196     "A84A";
197 
198 const char *ms_mp345 = "1E71E292";
199 
200 const char *d_mp12 = "-AAFBA6A55DD183FD854A60E";
201 const char *d_mp34 = "119366B05E606A9B1E73A6D8944CC1366B0C4E0D4";
202 const char *d_mp5d4 = "F5952EAB";
203 const char *d_mp6d2 = "-1";
204 const char *md_mp345 = "26596B86";
205 
206 const char *q_mp42 = "-95825A1FFA1A155D5";
207 const char *r_mp42 = "-6312E99D7700A3DCB32ADF2";
208 const char *q_mp45a = "15344CDA3D841F661D2B61B6EDF7828CE36";
209 const char *r_mp45a = "-47C47B";
210 const char *q_mp7c2 = "75FD3890E6C1C67321CE62CEEDA65F79";
211 const char *q_mp3d6 = "8CAFD53C272BD6FE8B0847BDC3B539EFAB5C3";
212 const char *r_mp3d6 = "1E5";
213 const char *r_mp5d5 = "1257";
214 const char *r_mp47 = "B3A9018D970281A90FB729A181D95CB8";
215 const char *q_mp1404 =
216     "-1B994D869142D3EF6123A3CBBC3C0114FA071CFCEEF4B7D231D65591D32501AD80F"
217     "FF49AE4EC80514CC071EF6B42521C2508F4CB2FEAD69A2D2EF3934087DCAF88CC4C4"
218     "659F1CA8A7F4D36817D802F778F1392337FE36302D6865BF0D4645625DF8BB044E19"
219     "930635BE2609FAC8D99357D3A9F81F2578DE15A300964188292107DAC980E0A08CD7"
220     "E938A2135FAD45D50CB1D8C2D4C4E60C27AB98B9FBD7E4DBF752C57D2674520E4BB2"
221     "7E42324C0EFE84FB3E38CF6950E699E86FD45FE40D428400F2F94EDF7E94FAE10B45"
222     "89329E1BF61E5A378C7B31C9C6A234F8254D4C24823B84D0BF8D671D8BC9154DFAC9"
223     "49BD8ACABD6BD32DD4DC587F22C86153CB3954BDF7C2A890D623642492C482CF3E2C"
224     "776FC019C3BBC61688B485E6FD35D6376089C1E33F880E84C4E51E8ABEACE1B3FB70"
225     "3EAD0E28D2D44E7F1C0A859C840775E94F8C1369D985A3C5E8114B21D68B3CBB75D2"
226     "791C586153C85B90CAA483E57A40E2D97950AAB84920A4396C950C87C7FFFE748358"
227     "42A0BF65445B26D40F05BE164B822CA96321F41D85A289C5F5CD5F438A78704C9683"
228     "422299D21899A22F853B0C93081CC9925E350132A0717A611DD932A68A0ACC6E4C7F"
229     "7F685EF8C1F4910AEA5DC00BB5A36FCA07FFEAA490C547F6E14A08FE87041AB803E1"
230     "BD9E23E4D367A2C35762F209073DFF48F3";
231 const char *r_mp1404 = "12FF98621ABF63144BFFC3207AC8FC10D8D1A09";
232 
233 const char *q_mp13c =
234     "34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342"
235     "BDAB6163963CD5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45";
236 const char *r_mp13c = "F2B050D226E6DA88";
237 const char *q_mp9c16 = "F74A2876A1432698923B0767DA19DCF3D71795E";
238 const char *r_mp9c16 = "E";
239 
240 const char *e_mp5d9 = "A8FD7145E727A20E52E73D22990D35D158090307A"
241                       "13A5215AAC4E9AB1E96BD34E531209E03310400";
242 const char *e_mp78 = "AA5F72C737DFFD8CCD108008BFE7C79ADC01A819B"
243                      "32B75FB82EC0FB8CA83311DA36D4063F1E57857A2"
244                      "1AB226563D84A15BB63CE975FF1453BD6750C58D9"
245                      "D113175764F5D0B3C89B262D4702F4D9640A3";
246 const char *me_mp817 = "E504493ACB02F7F802B327AB13BF25";
247 const char *me_mp5d47 = "1D45ED0D78F2778157992C951DD2734C";
248 const char *me_mp1512 = "FB5B2A28D902B9D9";
249 const char *me_mp161718 = "423C6AC6DBD74";
250 const char *me_mp5114 =
251     "64F0F72807993578BBA3C7C36FFB184028F9EB9A810C92079E1498D8A80FC848E1F0"
252     "25F1DE43B7F6AC063F5CC29D8A7C2D7A66269D72BF5CDC327AF88AF8EF9E601DCB0A"
253     "3F35BFF3525FB1B61CE3A25182F17C0A0633B4089EA15BDC47664A43FEF639748AAC"
254     "19CF58E83D8FA32CD10661D2D4210CC84792937E6F36CB601851356622E63ADD4BD5"
255     "542412C2E0C4958E51FD2524AABDC7D60CFB5DB332EEC9DC84210F10FAE0BA2018F2"
256     "14C9D6867C9D6E49CF28C18D06CE009FD4D04BFC8837C3FAAA773F5CCF6DED1C22DE"
257     "181786AFE188540586F2D74BF312E595244E6936AE52E45742109BAA76C36F2692F5"
258     "CEF97AD462B138BE92721194B163254CBAAEE9B9864B21CCDD5375BCAD0D24132724"
259     "113D3374B4BCF9AA49BA5ACBC12288C0BCF46DCE6CB4A241A91BD559B130B6E9CD3D"
260     "D7A2C8B280C2A278BA9BF5D93244D563015C9484B86D9FEB602501DC16EEBC3EFF19"
261     "53D7999682BF1A1E3B2E7B21F4BDCA3C355039FEF55B9C0885F98DC355CA7A6D8ECF"
262     "5F7F1A6E11A764F2343C823B879B44616B56BF6AE3FA2ACF5483660E618882018E3F"
263     "C8459313BACFE1F93CECC37B2576A5C0B2714BD3EEDEEC22F0E7E3E77B11396B9B99"
264     "D683F2447A4004BBD4A57F6A616CDDFEC595C4FC19884CC2FC21CF5BF5B0B81E0F83"
265     "B9DDA0CF4DFF35BB8D31245912BF4497FD0BD95F0C604E26EA5A8EA4F5EAE870A5BD"
266     "FE8C";
267 
268 const char *e_mpc2d3 = "100000000000000000000000000000000";
269 
270 const char *t_mp9 = "FB9B6E32FF0452A34746";
271 const char *i_mp27 = "B6AD8DCCDAF92B6FE57D062FFEE3A99";
272 const char *i_mp2019 =
273     "BDF3D88DC373A63EED92903115B03FC8501910AF68297B4C41870AED3EA9F839";
274 /* "15E3FE09E8AE5523AABA197BD2D16318D3CA148EDF4AE1C1C52FC96AFAF5680B"; */
275 
276 const char *t_mp15 =
277     "795853094E59B0008093BCA8DECF68587C64BDCA2F3F7F8963DABC12F1CFFFA9B8C4"
278     "365232FD4751870A0EF6CA619287C5D8B7F1747D95076AB19645EF309773E9EACEA0"
279     "975FA4AE16251A8DA5865349C3A903E3B8A2C0DEA3C0720B6020C7FED69AFF62BB72"
280     "10FAC443F9FFA2950776F949E819260C2AF8D94E8A1431A40F8C23C1973DE5D49AA2"
281     "0B3FF5DA5C1D5324E712A78FF33A9B1748F83FA529905924A31DF38643B3F693EF9B"
282     "58D846BB1AEAE4523ECC843FF551C1B300A130B65C1677402778F98C51C10813250E"
283     "2496882877B069E877B59740DC1226F18A5C0F66F64A5F59A9FAFC5E9FC45AEC0E7A"
284     "BEE244F7DD3AC268CF512A0E52E4F5BE5B94";
285 
286 const char *g_mp71 = "1";
287 const char *g_mp25 = "7";
288 const char *l_mp1011 = "C589E3D7D64A6942A000";
289 
290 /* mp9 in radices from 5 to 64 inclusive */
291 #define LOW_RADIX 5
292 #define HIGH_RADIX 64
293 const char *v_mp9[] = {
294     "404041130042310320100141302000203430214122130002340212132414134210033",
295     "44515230120451152500101352430105520150025145320010504454125502",
296     "644641136612541136016610100564613624243140151310023515322",
297     "173512120732412062323044435407317550316717172705712756",
298     "265785018434285762514442046172754680368422060744852",
299     "1411774500397290569709059837552310354075408897518",
300     "184064268501499311A17746095910428222A241708032A",
301     "47706011B225950B02BB45602AA039893118A85950892",
302     "1A188C826B982353CB58422563AC602B783101671A86",
303     "105957B358B89B018958908A9114BC3DDC410B77982",
304     "CB7B3387E23452178846C55DD9D70C7CA9AEA78E8",
305     "F74A2876A1432698923B0767DA19DCF3D71795EE",
306     "17BF7C3673B76D7G7A5GA836277296F806E7453A",
307     "2EBG8HH3HFA6185D6H0596AH96G24C966DD3HG2",
308     "6G3HGBFEG8I3F25EAF61B904EIA40CFDH2124F",
309     "10AHC3D29EBHDF3HD97905CG0JA8061855C3FI",
310     "3BA5A55J5K699B2D09C38A4B237CH51IHA132",
311     "EDEA90DJ0B5CB3FGG1C8587FEB99D3C143CA",
312     "31M26JI1BBD56K3I028MML4EEDMAJK60LGLE",
313     "GGG5M3142FKKG82EJ28111D70EMHC241E4E",
314     "4446F4D5H10982023N297BF0DKBBHLLJB0I",
315     "12E9DEEOBMKAKEP0IM284MIP7FO1O521M46",
316     "85NN0HD48NN2FDDB1F5BMMKIB8CK20MDPK",
317     "2D882A7A0O0JPCJ4APDRIB77IABAKDGJP2",
318     "MFMCI0R7S27AAA3O3L2S8K44HKA7O02CN",
319     "7IGQS73FFSHC50NNH44B6PTTNLC3M6H78",
320     "2KLUB3U9850CSN6ANIDNIF1LB29MJ43LH",
321     "UT52GTL18CJ9H4HR0TJTK6ESUFBHF5FE",
322     "BTVL87QQBMUGF8PFWU4W3VU7U922QTMW",
323     "4OG10HW0MSWJBIDEE2PDH24GA7RIHIAA",
324     "1W8W9AX2DRUX48GXOLMK0PE42H0FEUWN",
325     "SVWI84VBH069WR15W1U2VTK06USY8Z2",
326     "CPTPNPDa5TYCPPNLALENT9IMX2GL0W2",
327     "5QU21UJMRaUYYYYYN6GHSMPOYOXEEUY",
328     "2O2Q7C6RPPB1SXJ9bR4035SPaQQ3H2W",
329     "18d994IbT4PHbD7cGIPCRP00bbQO0bc",
330     "NcDUEEWRO7XT76260WGeBHPVa72RdA",
331     "BbX2WCF9VfSB5LPdJAdeXKV1fd6LC2",
332     "60QDKW67P4JSQaTdQg7JE9ISafLaVU",
333     "33ba9XbDbRdNF4BeDB2XYMhAVDaBdA",
334     "1RIPZJA8gT5L5H7fTcaRhQ39geMMTc",
335     "d65j70fBATjcDiidPYXUGcaBVVLME",
336     "LKA9jhPabDG612TXWkhfT2gMXNIP2",
337     "BgNaYhjfT0G8PBcYRP8khJCR3C9QE",
338     "6Wk8RhJTAgDh10fYAiUVB1aM0HacG",
339     "3dOCjaf78kd5EQNViUZWj3AfFL90I",
340     "290VWkL3aiJoW4MBbHk0Z0bDo22Ni",
341     "1DbDZ1hpPZNUDBUp6UigcJllEdC26",
342     "dFSOLBUM7UZX8Vnc6qokGIOiFo1h",
343     "NcoUYJOg0HVmKI9fR2ag0S8R2hrK",
344     "EOpiJ5Te7oDe2pn8ZhAUKkhFHlZh",
345     "8nXK8rp8neV8LWta1WDgd1QnlWsU",
346     "5T3d6bcSBtHgrH9bCbu84tblaa7r",
347     "3PlUDIYUvMqOVCir7AtquK5dWanq",
348     "2A70gDPX2AtiicvIGGk9poiMtgvu",
349     "1MjiRxjk10J6SVAxFguv9kZiUnIc",
350     "rpre2vIDeb4h3sp50r1YBbtEx9L",
351     "ZHcoip0AglDAfibrsUcJ9M1C8fm",
352     "NHP18+eoe6uU54W49Kc6ZK7+bT2",
353     "FTAA7QXGoQOaZi7PzePtFFN5vNk"
354 };
355 
356 const unsigned char b_mp4[] = {
357     0x01,
358 #if MP_DIGIT_MAX > MP_32BIT_MAX
359     0x00, 0x00, 0x00, 0x00,
360 #endif
361     0x63, 0xDB, 0xC2, 0x26,
362     0x5B, 0x88, 0x26, 0x8D,
363     0xC8, 0x01, 0xC1, 0x0E,
364     0xA6, 0x84, 0x76, 0xB7,
365     0xBD, 0xE0, 0x09, 0x0F
366 };
367 
368 /* Search for a test suite name in the names table  */
369 int find_name(char *name);
370 void reason(char *fmt, ...);
371 
372 /*------------------------------------------------------------------------*/
373 /*------------------------------------------------------------------------*/
374 
375 char g_intbuf[4096]; /* buffer for integer comparison   */
376 char a_intbuf[4096]; /* buffer for integer comparison   */
377 int g_verbose = 1;   /* print out reasons for failure?  */
378 
379 #define IFOK(x)                                                 \
380     {                                                           \
381         int ifok_res = (x);                                     \
382         if (MP_OKAY > ifok_res) {                               \
383             reason("test %s failed: error %d\n", #x, ifok_res); \
384             return 1;                                           \
385         }                                                       \
386     }
387 
388 int
main(int argc,char * argv[])389 main(int argc, char *argv[])
390 {
391     int which, res;
392 
393     srand((unsigned int)time(NULL));
394 
395     if (argc < 2) {
396         fprintf(stderr, "Usage: %s <test-suite> | list\n"
397                         "Type '%s help' for assistance\n",
398                 argv[0], argv[0]);
399         return 2;
400     } else if (argc > 2) {
401         if (strcmp(argv[2], "quiet") == 0)
402             g_verbose = 0;
403     }
404 
405     if (strcmp(argv[1], "help") == 0) {
406         fprintf(stderr, "Help for mpi-test\n\n"
407                         "This program is a test driver for the MPI library, which\n"
408                         "tests all the various functions in the library to make sure\n"
409                         "they are working correctly.  The syntax is:\n"
410                         "    %s <suite-name>\n"
411                         "...where <suite-name> is the name of the test you wish to\n"
412                         "run.  To get a list of the tests, use '%s list'.\n\n"
413                         "The program exits with a status of zero if the test passes,\n"
414                         "or non-zero if it fails.  Ordinarily, failure is accompanied\n"
415                         "by a diagnostic message to standard error.  To suppress this\n"
416                         "add the keyword 'quiet' after the suite-name on the command\n"
417                         "line.\n\n",
418                 argv[0], argv[0]);
419         return 0;
420     }
421 
422     if ((which = find_name(argv[1])) < 0) {
423         fprintf(stderr, "%s: test suite '%s' is not known\n", argv[0], argv[1]);
424         return 2;
425     }
426 
427     if ((res = (g_tests[which])()) < 0) {
428         fprintf(stderr, "%s: test suite not implemented yet\n", argv[0]);
429         return 2;
430     } else {
431         return res;
432     }
433 }
434 
435 /*------------------------------------------------------------------------*/
436 
437 int
find_name(char * name)438 find_name(char *name)
439 {
440     int ix = 0;
441 
442     while (ix < g_count) {
443         if (strcmp(name, g_names[ix]) == 0)
444             return ix;
445 
446         ++ix;
447     }
448 
449     return -1;
450 }
451 
452 /*------------------------------------------------------------------------*/
453 
454 int
test_list(void)455 test_list(void)
456 {
457     int ix;
458 
459     fprintf(stderr, "There are currently %d test suites available\n",
460             g_count);
461 
462     for (ix = 1; ix < g_count; ix++)
463         fprintf(stdout, "%-20s %s\n", g_names[ix], g_descs[ix]);
464 
465     return 0;
466 }
467 
468 /*------------------------------------------------------------------------*/
469 
470 int
test_copy(void)471 test_copy(void)
472 {
473     mp_int a, b;
474     int ix;
475 
476     mp_init(&a);
477     mp_init(&b);
478 
479     mp_read_radix(&a, mp3, 16);
480     mp_copy(&a, &b);
481 
482     if (SIGN(&a) != SIGN(&b) || USED(&a) != USED(&b)) {
483         if (SIGN(&a) != SIGN(&b)) {
484             reason("error: sign of original is %d, sign of copy is %d\n",
485                    SIGN(&a), SIGN(&b));
486         } else {
487             reason("error: original precision is %d, copy precision is %d\n",
488                    USED(&a), USED(&b));
489         }
490         mp_clear(&a);
491         mp_clear(&b);
492         return 1;
493     }
494 
495     for (ix = 0; ix < USED(&b); ix++) {
496         if (DIGIT(&a, ix) != DIGIT(&b, ix)) {
497             reason("error: digit %d " DIGIT_FMT " != " DIGIT_FMT "\n",
498                    ix, DIGIT(&a, ix), DIGIT(&b, ix));
499             mp_clear(&a);
500             mp_clear(&b);
501             return 1;
502         }
503     }
504 
505     mp_clear(&a);
506     mp_clear(&b);
507     return 0;
508 }
509 
510 /*------------------------------------------------------------------------*/
511 
512 int
test_exch(void)513 test_exch(void)
514 {
515     mp_int a, b;
516 
517     mp_init(&a);
518     mp_init(&b);
519     mp_read_radix(&a, mp7, 16);
520     mp_read_radix(&b, mp1, 16);
521 
522     mp_exch(&a, &b);
523     mp_toradix(&a, g_intbuf, 16);
524 
525     mp_clear(&a);
526     if (strcmp(g_intbuf, mp1) != 0) {
527         mp_clear(&b);
528         reason("error: exchange failed\n");
529         return 1;
530     }
531 
532     mp_toradix(&b, g_intbuf, 16);
533 
534     mp_clear(&b);
535     if (strcmp(g_intbuf, mp7) != 0) {
536         reason("error: exchange failed\n");
537         return 1;
538     }
539 
540     return 0;
541 }
542 
543 /*------------------------------------------------------------------------*/
544 
545 int
test_zero(void)546 test_zero(void)
547 {
548     mp_int a;
549 
550     mp_init(&a);
551     mp_read_radix(&a, mp7, 16);
552     mp_zero(&a);
553 
554     if (USED(&a) != 1 || DIGIT(&a, 1) != 0) {
555         mp_toradix(&a, g_intbuf, 16);
556         reason("error: result is %s\n", g_intbuf);
557         mp_clear(&a);
558         return 1;
559     }
560 
561     mp_clear(&a);
562     return 0;
563 }
564 
565 /*------------------------------------------------------------------------*/
566 
567 int
test_set(void)568 test_set(void)
569 {
570     mp_int a;
571 
572     /* Test single digit set */
573     mp_init(&a);
574     mp_set(&a, 5);
575     if (DIGIT(&a, 0) != 5) {
576         mp_toradix(&a, g_intbuf, 16);
577         reason("error: result is %s, expected 5\n", g_intbuf);
578         mp_clear(&a);
579         return 1;
580     }
581 
582     /* Test integer set */
583     mp_set_int(&a, -4938110);
584     mp_toradix(&a, g_intbuf, 16);
585     mp_clear(&a);
586     if (strcmp(g_intbuf, mp5a) != 0) {
587         reason("error: result is %s, expected %s\n", g_intbuf, mp5a);
588         return 1;
589     }
590 
591     return 0;
592 }
593 
594 /*------------------------------------------------------------------------*/
595 
596 int
test_abs(void)597 test_abs(void)
598 {
599     mp_int a;
600 
601     mp_init(&a);
602     mp_read_radix(&a, mp4, 16);
603     mp_abs(&a, &a);
604 
605     if (SIGN(&a) != ZPOS) {
606         reason("error: sign of result is negative\n");
607         mp_clear(&a);
608         return 1;
609     }
610 
611     mp_clear(&a);
612     return 0;
613 }
614 
615 /*------------------------------------------------------------------------*/
616 
617 int
test_neg(void)618 test_neg(void)
619 {
620     mp_int a;
621     mp_sign s;
622 
623     mp_init(&a);
624     mp_read_radix(&a, mp4, 16);
625 
626     s = SIGN(&a);
627     mp_neg(&a, &a);
628     if (SIGN(&a) == s) {
629         reason("error: sign of result is same as sign of nonzero input\n");
630         mp_clear(&a);
631         return 1;
632     }
633 
634     mp_clear(&a);
635     return 0;
636 }
637 
638 /*------------------------------------------------------------------------*/
639 
640 int
test_add_d(void)641 test_add_d(void)
642 {
643     mp_int a;
644 
645     mp_init(&a);
646 
647     mp_read_radix(&a, mp5, 16);
648     mp_add_d(&a, md4, &a);
649     mp_toradix(&a, g_intbuf, 16);
650 
651     if (strcmp(g_intbuf, s_mp5d4) != 0) {
652         reason("error: computed %s, expected %s\n", g_intbuf, s_mp5d4);
653         mp_clear(&a);
654         return 1;
655     }
656 
657     mp_read_radix(&a, mp2, 16);
658     mp_add_d(&a, md5, &a);
659     mp_toradix(&a, g_intbuf, 16);
660 
661     if (strcmp(g_intbuf, s_mp2d5) != 0) {
662         reason("error: computed %s, expected %s\n", g_intbuf, s_mp2d5);
663         mp_clear(&a);
664         return 1;
665     }
666 
667     mp_clear(&a);
668     return 0;
669 }
670 
671 /*------------------------------------------------------------------------*/
672 
673 int
test_add(void)674 test_add(void)
675 {
676     mp_int a, b;
677     int res = 0;
678 
679     mp_init(&a);
680     mp_init(&b);
681 
682     mp_read_radix(&a, mp1, 16);
683     mp_read_radix(&b, mp3, 16);
684     mp_add(&a, &b, &a);
685     mp_toradix(&a, g_intbuf, 16);
686 
687     if (strcmp(g_intbuf, s_mp13) != 0) {
688         reason("error: computed %s, expected %s\n", g_intbuf, s_mp13);
689         res = 1;
690         goto CLEANUP;
691     }
692 
693     mp_read_radix(&a, mp4, 16);
694     mp_add(&a, &b, &a);
695     mp_toradix(&a, g_intbuf, 16);
696 
697     if (strcmp(g_intbuf, s_mp34) != 0) {
698         reason("error: computed %s, expected %s\n", g_intbuf, s_mp34);
699         res = 1;
700         goto CLEANUP;
701     }
702 
703     mp_read_radix(&a, mp4, 16);
704     mp_read_radix(&b, mp6, 16);
705     mp_add(&a, &b, &a);
706     mp_toradix(&a, g_intbuf, 16);
707 
708     if (strcmp(g_intbuf, s_mp46) != 0) {
709         reason("error: computed %s, expected %s\n", g_intbuf, s_mp46);
710         res = 1;
711         goto CLEANUP;
712     }
713 
714     mp_read_radix(&a, mp14, 16);
715     mp_read_radix(&b, mp15, 16);
716     mp_add(&a, &b, &a);
717     mp_toradix(&a, g_intbuf, 16);
718 
719     if (strcmp(g_intbuf, s_mp1415) != 0) {
720         reason("error: computed %s, expected %s\n", g_intbuf, s_mp1415);
721         res = 1;
722     }
723 
724 CLEANUP:
725     mp_clear(&a);
726     mp_clear(&b);
727     return res;
728 }
729 
730 /*------------------------------------------------------------------------*/
731 
732 int
test_sub_d(void)733 test_sub_d(void)
734 {
735     mp_int a;
736 
737     mp_init(&a);
738     mp_read_radix(&a, mp5, 16);
739 
740     mp_sub_d(&a, md4, &a);
741     mp_toradix(&a, g_intbuf, 16);
742 
743     if (strcmp(g_intbuf, d_mp5d4) != 0) {
744         reason("error: computed %s, expected %s\n", g_intbuf, d_mp5d4);
745         mp_clear(&a);
746         return 1;
747     }
748 
749     mp_read_radix(&a, mp6, 16);
750 
751     mp_sub_d(&a, md2, &a);
752     mp_toradix(&a, g_intbuf, 16);
753 
754     mp_clear(&a);
755     if (strcmp(g_intbuf, d_mp6d2) != 0) {
756         reason("error: computed %s, expected %s\n", g_intbuf, d_mp6d2);
757         return 1;
758     }
759 
760     return 0;
761 }
762 
763 /*------------------------------------------------------------------------*/
764 
765 int
test_sub(void)766 test_sub(void)
767 {
768     mp_int a, b;
769 
770     mp_init(&a);
771     mp_init(&b);
772 
773     mp_read_radix(&a, mp1, 16);
774     mp_read_radix(&b, mp2, 16);
775     mp_sub(&a, &b, &a);
776     mp_toradix(&a, g_intbuf, 16);
777 
778     if (strcmp(g_intbuf, d_mp12) != 0) {
779         reason("error: computed %s, expected %s\n", g_intbuf, d_mp12);
780         mp_clear(&a);
781         mp_clear(&b);
782         return 1;
783     }
784 
785     mp_read_radix(&a, mp3, 16);
786     mp_read_radix(&b, mp4, 16);
787     mp_sub(&a, &b, &a);
788     mp_toradix(&a, g_intbuf, 16);
789 
790     if (strcmp(g_intbuf, d_mp34) != 0) {
791         reason("error: computed %s, expected %s\n", g_intbuf, d_mp34);
792         mp_clear(&a);
793         mp_clear(&b);
794         return 1;
795     }
796 
797     mp_clear(&a);
798     mp_clear(&b);
799     return 0;
800 }
801 
802 /*------------------------------------------------------------------------*/
803 
804 int
test_mul_d(void)805 test_mul_d(void)
806 {
807     mp_int a;
808 
809     mp_init(&a);
810     mp_read_radix(&a, mp1, 16);
811 
812     IFOK(mp_mul_d(&a, md4, &a));
813     mp_toradix(&a, g_intbuf, 16);
814 
815     if (strcmp(g_intbuf, p_mp1d4) != 0) {
816         reason("error: computed %s, expected %s\n", g_intbuf, p_mp1d4);
817         mp_clear(&a);
818         return 1;
819     }
820 
821     mp_read_radix(&a, mp8, 16);
822     IFOK(mp_mul_d(&a, md6, &a));
823     mp_toradix(&a, g_intbuf, 16);
824 
825     mp_clear(&a);
826     if (strcmp(g_intbuf, p_mp8d6) != 0) {
827         reason("error: computed %s, expected %s\n", g_intbuf, p_mp8d6);
828         return 1;
829     }
830 
831     return 0;
832 }
833 
834 /*------------------------------------------------------------------------*/
835 
836 int
test_mul(void)837 test_mul(void)
838 {
839     mp_int a, b;
840     int res = 0;
841 
842     mp_init(&a);
843     mp_init(&b);
844     mp_read_radix(&a, mp1, 16);
845     mp_read_radix(&b, mp2, 16);
846 
847     IFOK(mp_mul(&a, &b, &a));
848     mp_toradix(&a, g_intbuf, 16);
849 
850     if (strcmp(g_intbuf, p_mp12) != 0) {
851         reason("error: computed %s, expected %s\n", g_intbuf, p_mp12);
852         res = 1;
853         goto CLEANUP;
854     }
855 
856     mp_read_radix(&a, mp3, 16);
857     mp_read_radix(&b, mp4, 16);
858     IFOK(mp_mul(&a, &b, &a));
859     mp_toradix(&a, g_intbuf, 16);
860 
861     if (strcmp(g_intbuf, p_mp34) != 0) {
862         reason("error: computed %s, expected %s\n", g_intbuf, p_mp34);
863         res = 1;
864         goto CLEANUP;
865     }
866 
867     mp_read_radix(&a, mp5, 16);
868     mp_read_radix(&b, mp7, 16);
869     IFOK(mp_mul(&a, &b, &a));
870     mp_toradix(&a, g_intbuf, 16);
871 
872     if (strcmp(g_intbuf, p_mp57) != 0) {
873         reason("error: computed %s, expected %s\n", g_intbuf, p_mp57);
874         res = 1;
875         goto CLEANUP;
876     }
877 
878     mp_read_radix(&a, mp11, 16);
879     mp_read_radix(&b, mp13, 16);
880     IFOK(mp_mul(&a, &b, &a));
881     mp_toradix(&a, g_intbuf, 16);
882 
883     if (strcmp(g_intbuf, p_mp1113) != 0) {
884         reason("error: computed %s, expected %s\n", g_intbuf, p_mp1113);
885         res = 1;
886         goto CLEANUP;
887     }
888 
889     mp_read_radix(&a, mp14, 16);
890     mp_read_radix(&b, mp15, 16);
891     IFOK(mp_mul(&a, &b, &a));
892     mp_toradix(&a, g_intbuf, 16);
893 
894     if (strcmp(g_intbuf, p_mp1415) != 0) {
895         reason("error: computed %s, expected %s\n", g_intbuf, p_mp1415);
896         res = 1;
897     }
898     mp_read_radix(&a, mp21, 10);
899     mp_read_radix(&b, mp21, 10);
900 
901     IFOK(mp_mul(&a, &b, &a));
902     mp_toradix(&a, g_intbuf, 10);
903 
904     if (strcmp(g_intbuf, p_mp2121) != 0) {
905         reason("error: computed %s, expected %s\n", g_intbuf, p_mp2121);
906         res = 1;
907         goto CLEANUP;
908     }
909 
910 CLEANUP:
911     mp_clear(&a);
912     mp_clear(&b);
913     return res;
914 }
915 
916 /*------------------------------------------------------------------------*/
917 
918 int
test_sqr(void)919 test_sqr(void)
920 {
921     mp_int a;
922 
923     mp_init(&a);
924     mp_read_radix(&a, mp2, 16);
925 
926     mp_sqr(&a, &a);
927     mp_toradix(&a, g_intbuf, 16);
928 
929     mp_clear(&a);
930     if (strcmp(g_intbuf, p_mp22) != 0) {
931         reason("error: computed %s, expected %s\n", g_intbuf, p_mp22);
932         return 1;
933     }
934 
935     return 0;
936 }
937 
938 /*------------------------------------------------------------------------*/
939 
940 int
test_div_d(void)941 test_div_d(void)
942 {
943     mp_int a, q;
944     mp_digit r;
945     int err = 0;
946 
947     mp_init(&a);
948     mp_init(&q);
949     mp_read_radix(&a, mp3, 16);
950 
951     IFOK(mp_div_d(&a, md6, &q, &r));
952     mp_toradix(&q, g_intbuf, 16);
953 
954     if (strcmp(g_intbuf, q_mp3d6) != 0) {
955         reason("error: computed q = %s, expected %s\n", g_intbuf, q_mp3d6);
956         ++err;
957     }
958 
959     sprintf(g_intbuf, ZS_DIGIT_FMT, r);
960 
961     if (strcmp(g_intbuf, r_mp3d6) != 0) {
962         reason("error: computed r = %s, expected %s\n", g_intbuf, r_mp3d6);
963         ++err;
964     }
965 
966     mp_read_radix(&a, mp9, 16);
967     IFOK(mp_div_d(&a, 16, &q, &r));
968     mp_toradix(&q, g_intbuf, 16);
969 
970     if (strcmp(g_intbuf, q_mp9c16) != 0) {
971         reason("error: computed q = %s, expected %s\n", g_intbuf, q_mp9c16);
972         ++err;
973     }
974 
975     sprintf(g_intbuf, ZS_DIGIT_FMT, r);
976 
977     if (strcmp(g_intbuf, r_mp9c16) != 0) {
978         reason("error: computed r = %s, expected %s\n", g_intbuf, r_mp9c16);
979         ++err;
980     }
981 
982     mp_clear(&a);
983     mp_clear(&q);
984     return err;
985 }
986 
987 /*------------------------------------------------------------------------*/
988 
989 int
test_div_2(void)990 test_div_2(void)
991 {
992     mp_int a;
993 
994     mp_init(&a);
995     mp_read_radix(&a, mp7, 16);
996     IFOK(mp_div_2(&a, &a));
997     mp_toradix(&a, g_intbuf, 16);
998 
999     mp_clear(&a);
1000     if (strcmp(g_intbuf, q_mp7c2) != 0) {
1001         reason("error: computed %s, expected %s\n", g_intbuf, q_mp7c2);
1002         return 1;
1003     }
1004 
1005     return 0;
1006 }
1007 
1008 /*------------------------------------------------------------------------*/
1009 
1010 int
test_div_2d(void)1011 test_div_2d(void)
1012 {
1013     mp_int a, q, r;
1014 
1015     mp_init(&q);
1016     mp_init(&r);
1017     mp_init(&a);
1018     mp_read_radix(&a, mp13, 16);
1019 
1020     IFOK(mp_div_2d(&a, 64, &q, &r));
1021     mp_clear(&a);
1022 
1023     mp_toradix(&q, g_intbuf, 16);
1024 
1025     if (strcmp(g_intbuf, q_mp13c) != 0) {
1026         reason("error: computed %s, expected %s\n", g_intbuf, q_mp13c);
1027         mp_clear(&q);
1028         mp_clear(&r);
1029         return 1;
1030     }
1031 
1032     mp_clear(&q);
1033 
1034     mp_toradix(&r, g_intbuf, 16);
1035     if (strcmp(g_intbuf, r_mp13c) != 0) {
1036         reason("error, computed %s, expected %s\n", g_intbuf, r_mp13c);
1037         mp_clear(&r);
1038         return 1;
1039     }
1040 
1041     mp_clear(&r);
1042 
1043     return 0;
1044 }
1045 
1046 /*------------------------------------------------------------------------*/
1047 
1048 int
test_div(void)1049 test_div(void)
1050 {
1051     mp_int a, b, r;
1052     int err = 0;
1053 
1054     mp_init(&a);
1055     mp_init(&b);
1056     mp_init(&r);
1057 
1058     mp_read_radix(&a, mp4, 16);
1059     mp_read_radix(&b, mp2, 16);
1060     IFOK(mp_div(&a, &b, &a, &r));
1061     mp_toradix(&a, g_intbuf, 16);
1062 
1063     if (strcmp(g_intbuf, q_mp42) != 0) {
1064         reason("error: test 1 computed quot %s, expected %s\n", g_intbuf, q_mp42);
1065         ++err;
1066     }
1067 
1068     mp_toradix(&r, g_intbuf, 16);
1069 
1070     if (strcmp(g_intbuf, r_mp42) != 0) {
1071         reason("error: test 1 computed rem %s, expected %s\n", g_intbuf, r_mp42);
1072         ++err;
1073     }
1074 
1075     mp_read_radix(&a, mp4, 16);
1076     mp_read_radix(&b, mp5a, 16);
1077     IFOK(mp_div(&a, &b, &a, &r));
1078     mp_toradix(&a, g_intbuf, 16);
1079 
1080     if (strcmp(g_intbuf, q_mp45a) != 0) {
1081         reason("error: test 2 computed quot %s, expected %s\n", g_intbuf, q_mp45a);
1082         ++err;
1083     }
1084 
1085     mp_toradix(&r, g_intbuf, 16);
1086 
1087     if (strcmp(g_intbuf, r_mp45a) != 0) {
1088         reason("error: test 2 computed rem %s, expected %s\n", g_intbuf, r_mp45a);
1089         ++err;
1090     }
1091 
1092     mp_read_radix(&a, mp14, 16);
1093     mp_read_radix(&b, mp4, 16);
1094     IFOK(mp_div(&a, &b, &a, &r));
1095     mp_toradix(&a, g_intbuf, 16);
1096 
1097     if (strcmp(g_intbuf, q_mp1404) != 0) {
1098         reason("error: test 3 computed quot %s, expected %s\n", g_intbuf, q_mp1404);
1099         ++err;
1100     }
1101 
1102     mp_toradix(&r, g_intbuf, 16);
1103 
1104     if (strcmp(g_intbuf, r_mp1404) != 0) {
1105         reason("error: test 3 computed rem %s, expected %s\n", g_intbuf, r_mp1404);
1106         ++err;
1107     }
1108 
1109     mp_clear(&a);
1110     mp_clear(&b);
1111     mp_clear(&r);
1112 
1113     return err;
1114 }
1115 
1116 /*------------------------------------------------------------------------*/
1117 
1118 int
test_expt_d(void)1119 test_expt_d(void)
1120 {
1121     mp_int a;
1122 
1123     mp_init(&a);
1124     mp_read_radix(&a, mp5, 16);
1125     mp_expt_d(&a, md9, &a);
1126     mp_toradix(&a, g_intbuf, 16);
1127 
1128     mp_clear(&a);
1129     if (strcmp(g_intbuf, e_mp5d9) != 0) {
1130         reason("error: computed %s, expected %s\n", g_intbuf, e_mp5d9);
1131         return 1;
1132     }
1133 
1134     return 0;
1135 }
1136 
1137 /*------------------------------------------------------------------------*/
1138 
1139 int
test_expt(void)1140 test_expt(void)
1141 {
1142     mp_int a, b;
1143 
1144     mp_init(&a);
1145     mp_init(&b);
1146     mp_read_radix(&a, mp7, 16);
1147     mp_read_radix(&b, mp8, 16);
1148 
1149     mp_expt(&a, &b, &a);
1150     mp_toradix(&a, g_intbuf, 16);
1151     mp_clear(&a);
1152     mp_clear(&b);
1153 
1154     if (strcmp(g_intbuf, e_mp78) != 0) {
1155         reason("error: computed %s, expected %s\n", g_intbuf, e_mp78);
1156         return 1;
1157     }
1158 
1159     return 0;
1160 }
1161 
1162 /*------------------------------------------------------------------------*/
1163 
1164 int
test_2expt(void)1165 test_2expt(void)
1166 {
1167     mp_int a;
1168 
1169     mp_init(&a);
1170     mp_2expt(&a, md3);
1171     mp_toradix(&a, g_intbuf, 16);
1172     mp_clear(&a);
1173 
1174     if (strcmp(g_intbuf, e_mpc2d3) != 0) {
1175         reason("error: computed %s, expected %s\n", g_intbuf, e_mpc2d3);
1176         return 1;
1177     }
1178 
1179     return 0;
1180 }
1181 
1182 /*------------------------------------------------------------------------*/
1183 
1184 int
test_mod_d(void)1185 test_mod_d(void)
1186 {
1187     mp_int a;
1188     mp_digit r;
1189 
1190     mp_init(&a);
1191     mp_read_radix(&a, mp5, 16);
1192     IFOK(mp_mod_d(&a, md5, &r));
1193     sprintf(g_intbuf, ZS_DIGIT_FMT, r);
1194     mp_clear(&a);
1195 
1196     if (strcmp(g_intbuf, r_mp5d5) != 0) {
1197         reason("error: computed %s, expected %s\n", g_intbuf, r_mp5d5);
1198         return 1;
1199     }
1200 
1201     return 0;
1202 }
1203 
1204 /*------------------------------------------------------------------------*/
1205 
1206 int
test_mod(void)1207 test_mod(void)
1208 {
1209     mp_int a, m;
1210 
1211     mp_init(&a);
1212     mp_init(&m);
1213     mp_read_radix(&a, mp4, 16);
1214     mp_read_radix(&m, mp7, 16);
1215     IFOK(mp_mod(&a, &m, &a));
1216     mp_toradix(&a, g_intbuf, 16);
1217     mp_clear(&a);
1218     mp_clear(&m);
1219 
1220     if (strcmp(g_intbuf, r_mp47) != 0) {
1221         reason("error: computed %s, expected %s\n", g_intbuf, r_mp47);
1222         return 1;
1223     }
1224 
1225     return 0;
1226 }
1227 
1228 /*------------------------------------------------------------------------*/
1229 
1230 int
test_addmod(void)1231 test_addmod(void)
1232 {
1233     mp_int a, b, m;
1234 
1235     mp_init(&a);
1236     mp_init(&b);
1237     mp_init(&m);
1238     mp_read_radix(&a, mp3, 16);
1239     mp_read_radix(&b, mp4, 16);
1240     mp_read_radix(&m, mp5, 16);
1241 
1242     IFOK(mp_addmod(&a, &b, &m, &a));
1243     mp_toradix(&a, g_intbuf, 16);
1244     mp_clear(&a);
1245     mp_clear(&b);
1246     mp_clear(&m);
1247 
1248     if (strcmp(g_intbuf, ms_mp345) != 0) {
1249         reason("error: computed %s, expected %s\n", g_intbuf, ms_mp345);
1250         return 1;
1251     }
1252 
1253     return 0;
1254 }
1255 
1256 /*------------------------------------------------------------------------*/
1257 
1258 int
test_submod(void)1259 test_submod(void)
1260 {
1261     mp_int a, b, m;
1262 
1263     mp_init(&a);
1264     mp_init(&b);
1265     mp_init(&m);
1266     mp_read_radix(&a, mp3, 16);
1267     mp_read_radix(&b, mp4, 16);
1268     mp_read_radix(&m, mp5, 16);
1269 
1270     IFOK(mp_submod(&a, &b, &m, &a));
1271     mp_toradix(&a, g_intbuf, 16);
1272     mp_clear(&a);
1273     mp_clear(&b);
1274     mp_clear(&m);
1275 
1276     if (strcmp(g_intbuf, md_mp345) != 0) {
1277         reason("error: computed %s, expected %s\n", g_intbuf, md_mp345);
1278         return 1;
1279     }
1280 
1281     return 0;
1282 }
1283 
1284 /*------------------------------------------------------------------------*/
1285 
1286 int
test_mulmod(void)1287 test_mulmod(void)
1288 {
1289     mp_int a, b, m;
1290 
1291     mp_init(&a);
1292     mp_init(&b);
1293     mp_init(&m);
1294     mp_read_radix(&a, mp3, 16);
1295     mp_read_radix(&b, mp4, 16);
1296     mp_read_radix(&m, mp5, 16);
1297 
1298     IFOK(mp_mulmod(&a, &b, &m, &a));
1299     mp_toradix(&a, g_intbuf, 16);
1300     mp_clear(&a);
1301     mp_clear(&b);
1302     mp_clear(&m);
1303 
1304     if (strcmp(g_intbuf, mp_mp345) != 0) {
1305         reason("error: computed %s, expected %s\n", g_intbuf, mp_mp345);
1306         return 1;
1307     }
1308 
1309     return 0;
1310 }
1311 
1312 /*------------------------------------------------------------------------*/
1313 
1314 int
test_sqrmod(void)1315 test_sqrmod(void)
1316 {
1317     mp_int a, m;
1318 
1319     mp_init(&a);
1320     mp_init(&m);
1321     mp_read_radix(&a, mp3, 16);
1322     mp_read_radix(&m, mp5, 16);
1323 
1324     IFOK(mp_sqrmod(&a, &m, &a));
1325     mp_toradix(&a, g_intbuf, 16);
1326     mp_clear(&a);
1327     mp_clear(&m);
1328 
1329     if (strcmp(g_intbuf, mp_mp335) != 0) {
1330         reason("error: computed %s, expected %s\n", g_intbuf, mp_mp335);
1331         return 1;
1332     }
1333 
1334     return 0;
1335 }
1336 
1337 /*------------------------------------------------------------------------*/
1338 
1339 int
test_exptmod(void)1340 test_exptmod(void)
1341 {
1342     mp_int a, b, m;
1343     int res = 0;
1344 
1345     mp_init(&a);
1346     mp_init(&b);
1347     mp_init(&m);
1348     mp_read_radix(&a, mp8, 16);
1349     mp_read_radix(&b, mp1, 16);
1350     mp_read_radix(&m, mp7, 16);
1351 
1352     IFOK(mp_exptmod(&a, &b, &m, &a));
1353     mp_toradix(&a, g_intbuf, 16);
1354 
1355     if (strcmp(g_intbuf, me_mp817) != 0) {
1356         reason("case 1: error: computed %s, expected %s\n", g_intbuf, me_mp817);
1357         res = 1;
1358         goto CLEANUP;
1359     }
1360 
1361     mp_read_radix(&a, mp1, 16);
1362     mp_read_radix(&b, mp5, 16);
1363     mp_read_radix(&m, mp12, 16);
1364 
1365     IFOK(mp_exptmod(&a, &b, &m, &a));
1366     mp_toradix(&a, g_intbuf, 16);
1367 
1368     if (strcmp(g_intbuf, me_mp1512) != 0) {
1369         reason("case 2: error: computed %s, expected %s\n", g_intbuf, me_mp1512);
1370         res = 1;
1371         goto CLEANUP;
1372     }
1373 
1374     mp_read_radix(&a, mp5, 16);
1375     mp_read_radix(&b, mp1, 16);
1376     mp_read_radix(&m, mp14, 16);
1377 
1378     IFOK(mp_exptmod(&a, &b, &m, &a));
1379     mp_toradix(&a, g_intbuf, 16);
1380 
1381     if (strcmp(g_intbuf, me_mp5114) != 0) {
1382         reason("case 3: error: computed %s, expected %s\n", g_intbuf, me_mp5114);
1383         res = 1;
1384     }
1385 
1386     mp_read_radix(&a, mp16, 16);
1387     mp_read_radix(&b, mp17, 16);
1388     mp_read_radix(&m, mp18, 16);
1389 
1390     IFOK(mp_exptmod(&a, &b, &m, &a));
1391     mp_toradix(&a, g_intbuf, 16);
1392 
1393     if (strcmp(g_intbuf, me_mp161718) != 0) {
1394         reason("case 4: error: computed %s, expected %s\n", g_intbuf, me_mp161718);
1395         res = 1;
1396     }
1397 
1398 CLEANUP:
1399     mp_clear(&a);
1400     mp_clear(&b);
1401     mp_clear(&m);
1402     return res;
1403 }
1404 
1405 /*------------------------------------------------------------------------*/
1406 
1407 int
test_exptmod_d(void)1408 test_exptmod_d(void)
1409 {
1410     mp_int a, m;
1411 
1412     mp_init(&a);
1413     mp_init(&m);
1414     mp_read_radix(&a, mp5, 16);
1415     mp_read_radix(&m, mp7, 16);
1416 
1417     IFOK(mp_exptmod_d(&a, md4, &m, &a));
1418     mp_toradix(&a, g_intbuf, 16);
1419     mp_clear(&a);
1420     mp_clear(&m);
1421 
1422     if (strcmp(g_intbuf, me_mp5d47) != 0) {
1423         reason("error: computed %s, expected %s\n", g_intbuf, me_mp5d47);
1424         return 1;
1425     }
1426 
1427     return 0;
1428 }
1429 
1430 /*------------------------------------------------------------------------*/
1431 
1432 int
test_invmod(void)1433 test_invmod(void)
1434 {
1435     mp_int a, m, c;
1436     mp_int p1, p2, p3, p4, p5;
1437     mp_int t1, t2, t3, t4;
1438     mp_err res;
1439 
1440     /* 5 128-bit primes. */
1441     static const char ivp1[] = { "AAD8A5A2A2BEF644BAEE7DB0CA643719" };
1442     static const char ivp2[] = { "CB371AD2B79A90BCC88D0430663E40B9" };
1443     static const char ivp3[] = { "C6C818D4DF2618406CA09280C0400099" };
1444     static const char ivp4[] = { "CE949C04512E68918006B1F0D7E93F27" };
1445     static const char ivp5[] = { "F8EE999B6416645040687440E0B89F51" };
1446 
1447     mp_init(&a);
1448     mp_init(&m);
1449     mp_read_radix(&a, mp2, 16);
1450     mp_read_radix(&m, mp7, 16);
1451 
1452     IFOK(mp_invmod(&a, &m, &a));
1453 
1454     mp_toradix(&a, g_intbuf, 16);
1455     mp_clear(&a);
1456     mp_clear(&m);
1457 
1458     if (strcmp(g_intbuf, i_mp27) != 0) {
1459         reason("error: invmod test 1 computed %s, expected %s\n", g_intbuf, i_mp27);
1460         return 1;
1461     }
1462 
1463     mp_init(&a);
1464     mp_init(&m);
1465     mp_read_radix(&a, mp20, 16);
1466     mp_read_radix(&m, mp19, 16);
1467 
1468     IFOK(mp_invmod(&a, &m, &a));
1469 
1470     mp_toradix(&a, g_intbuf, 16);
1471     mp_clear(&a);
1472     mp_clear(&m);
1473 
1474     if (strcmp(g_intbuf, i_mp2019) != 0) {
1475         reason("error: invmod test 2 computed %s, expected %s\n", g_intbuf, i_mp2019);
1476         return 1;
1477     }
1478 
1479     /* Need the following test cases:
1480       Odd modulus
1481         - a is odd,      relatively prime to m
1482         - a is odd,  not relatively prime to m
1483         - a is even,     relatively prime to m
1484         - a is even, not relatively prime to m
1485       Even modulus
1486         - a is even  (should fail)
1487         - a is odd,  not relatively prime to m
1488         - a is odd,      relatively prime to m,
1489           m is not a power of 2
1490         - m has factor 2**k, k < 32
1491         - m has factor 2**k, k > 32
1492           m is a power of 2, 2**k
1493         - k < 32
1494         - k > 32
1495     */
1496 
1497     mp_init(&a);
1498     mp_init(&m);
1499     mp_init(&c);
1500     mp_init(&p1);
1501     mp_init(&p2);
1502     mp_init(&p3);
1503     mp_init(&p4);
1504     mp_init(&p5);
1505     mp_init(&t1);
1506     mp_init(&t2);
1507     mp_init(&t3);
1508     mp_init(&t4);
1509 
1510     mp_read_radix(&p1, ivp1, 16);
1511     mp_read_radix(&p2, ivp2, 16);
1512     mp_read_radix(&p3, ivp3, 16);
1513     mp_read_radix(&p4, ivp4, 16);
1514     mp_read_radix(&p5, ivp5, 16);
1515 
1516     IFOK(mp_2expt(&t2, 68));  /* t2 = 2**68 */
1517     IFOK(mp_2expt(&t3, 128)); /* t3 = 2**128 */
1518     IFOK(mp_2expt(&t4, 31));  /* t4 = 2**31 */
1519 
1520     /* test 3: Odd modulus - a is odd, relatively prime to m */
1521 
1522     IFOK(mp_mul(&p1, &p2, &a));
1523     IFOK(mp_mul(&p3, &p4, &m));
1524     IFOK(mp_invmod(&a, &m, &t1));
1525     IFOK(mp_invmod_xgcd(&a, &m, &c));
1526 
1527     if (mp_cmp(&t1, &c) != 0) {
1528         mp_toradix(&t1, g_intbuf, 16);
1529         mp_toradix(&c, a_intbuf, 16);
1530         reason("error: invmod test 3 computed %s, expected %s\n",
1531                g_intbuf, a_intbuf);
1532         return 1;
1533     }
1534     mp_clear(&a);
1535     mp_clear(&t1);
1536     mp_clear(&c);
1537     mp_init(&a);
1538     mp_init(&t1);
1539     mp_init(&c);
1540 
1541     /* test 4: Odd modulus - a is odd, NOT relatively prime to m */
1542 
1543     IFOK(mp_mul(&p1, &p3, &a));
1544     /* reuse same m as before */
1545 
1546     res = mp_invmod_xgcd(&a, &m, &c);
1547     if (res != MP_UNDEF)
1548         goto CLEANUP4;
1549 
1550     res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
1551     if (res != MP_UNDEF) {
1552     CLEANUP4:
1553         reason("error: invmod test 4 succeeded, should have failed.\n");
1554         return 1;
1555     }
1556     mp_clear(&a);
1557     mp_clear(&t1);
1558     mp_clear(&c);
1559     mp_init(&a);
1560     mp_init(&t1);
1561     mp_init(&c);
1562 
1563     /* test 5: Odd modulus - a is even, relatively prime to m */
1564 
1565     IFOK(mp_mul(&p1, &t2, &a));
1566     /* reuse m */
1567     IFOK(mp_invmod(&a, &m, &t1));
1568     IFOK(mp_invmod_xgcd(&a, &m, &c));
1569 
1570     if (mp_cmp(&t1, &c) != 0) {
1571         mp_toradix(&t1, g_intbuf, 16);
1572         mp_toradix(&c, a_intbuf, 16);
1573         reason("error: invmod test 5 computed %s, expected %s\n",
1574                g_intbuf, a_intbuf);
1575         return 1;
1576     }
1577     mp_clear(&a);
1578     mp_clear(&t1);
1579     mp_clear(&c);
1580     mp_init(&a);
1581     mp_init(&t1);
1582     mp_init(&c);
1583 
1584     /* test 6: Odd modulus - a is odd, NOT relatively prime to m */
1585 
1586     /* reuse t2 */
1587     IFOK(mp_mul(&t2, &p3, &a));
1588     /* reuse same m as before */
1589 
1590     res = mp_invmod_xgcd(&a, &m, &c);
1591     if (res != MP_UNDEF)
1592         goto CLEANUP6;
1593 
1594     res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
1595     if (res != MP_UNDEF) {
1596     CLEANUP6:
1597         reason("error: invmod test 6 succeeded, should have failed.\n");
1598         return 1;
1599     }
1600     mp_clear(&a);
1601     mp_clear(&m);
1602     mp_clear(&c);
1603     mp_clear(&t1);
1604     mp_init(&a);
1605     mp_init(&m);
1606     mp_init(&c);
1607     mp_init(&t1);
1608 
1609     /* test 7: Even modulus, even a, should fail */
1610 
1611     IFOK(mp_mul(&p3, &t3, &m)); /* even m */
1612     /* reuse t2 */
1613     IFOK(mp_mul(&p1, &t2, &a)); /* even a */
1614 
1615     res = mp_invmod_xgcd(&a, &m, &c);
1616     if (res != MP_UNDEF)
1617         goto CLEANUP7;
1618 
1619     res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
1620     if (res != MP_UNDEF) {
1621     CLEANUP7:
1622         reason("error: invmod test 7 succeeded, should have failed.\n");
1623         return 1;
1624     }
1625     mp_clear(&a);
1626     mp_clear(&c);
1627     mp_clear(&t1);
1628     mp_init(&a);
1629     mp_init(&c);
1630     mp_init(&t1);
1631 
1632     /* test 8: Even modulus    - a is odd,  not relatively prime to m */
1633 
1634     /* reuse m */
1635     IFOK(mp_mul(&p3, &p1, &a)); /* even a */
1636 
1637     res = mp_invmod_xgcd(&a, &m, &c);
1638     if (res != MP_UNDEF)
1639         goto CLEANUP8;
1640 
1641     res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
1642     if (res != MP_UNDEF) {
1643     CLEANUP8:
1644         reason("error: invmod test 8 succeeded, should have failed.\n");
1645         return 1;
1646     }
1647     mp_clear(&a);
1648     mp_clear(&m);
1649     mp_clear(&c);
1650     mp_clear(&t1);
1651     mp_init(&a);
1652     mp_init(&m);
1653     mp_init(&c);
1654     mp_init(&t1);
1655 
1656     /* test 9: Even modulus    - m has factor 2**k, k < 32
1657      *                     - a is odd, relatively prime to m,
1658      */
1659     IFOK(mp_mul(&p3, &t4, &m)); /* even m */
1660     IFOK(mp_mul(&p1, &p2, &a));
1661     IFOK(mp_invmod(&a, &m, &t1));
1662     IFOK(mp_invmod_xgcd(&a, &m, &c));
1663 
1664     if (mp_cmp(&t1, &c) != 0) {
1665         mp_toradix(&t1, g_intbuf, 16);
1666         mp_toradix(&c, a_intbuf, 16);
1667         reason("error: invmod test 9 computed %s, expected %s\n",
1668                g_intbuf, a_intbuf);
1669         return 1;
1670     }
1671     mp_clear(&m);
1672     mp_clear(&t1);
1673     mp_clear(&c);
1674     mp_init(&m);
1675     mp_init(&t1);
1676     mp_init(&c);
1677 
1678     /* test 10: Even modulus    - m has factor 2**k, k > 32
1679      *                      - a is odd, relatively prime to m,
1680      */
1681     IFOK(mp_mul(&p3, &t3, &m)); /* even m */
1682     /* reuse a */
1683     IFOK(mp_invmod(&a, &m, &t1));
1684     IFOK(mp_invmod_xgcd(&a, &m, &c));
1685 
1686     if (mp_cmp(&t1, &c) != 0) {
1687         mp_toradix(&t1, g_intbuf, 16);
1688         mp_toradix(&c, a_intbuf, 16);
1689         reason("error: invmod test 10 computed %s, expected %s\n",
1690                g_intbuf, a_intbuf);
1691         return 1;
1692     }
1693     mp_clear(&t1);
1694     mp_clear(&c);
1695     mp_init(&t1);
1696     mp_init(&c);
1697 
1698     /* test 11: Even modulus    - m is a power of 2, 2**k | k < 32
1699      *                          - a is odd, relatively prime to m,
1700      */
1701     IFOK(mp_invmod(&a, &t4, &t1));
1702     IFOK(mp_invmod_xgcd(&a, &t4, &c));
1703 
1704     if (mp_cmp(&t1, &c) != 0) {
1705         mp_toradix(&t1, g_intbuf, 16);
1706         mp_toradix(&c, a_intbuf, 16);
1707         reason("error: invmod test 11 computed %s, expected %s\n",
1708                g_intbuf, a_intbuf);
1709         return 1;
1710     }
1711     mp_clear(&t1);
1712     mp_clear(&c);
1713     mp_init(&t1);
1714     mp_init(&c);
1715 
1716     /* test 12: Even modulus    - m is a power of 2, 2**k | k > 32
1717      *                          - a is odd, relatively prime to m,
1718      */
1719     IFOK(mp_invmod(&a, &t3, &t1));
1720     IFOK(mp_invmod_xgcd(&a, &t3, &c));
1721 
1722     if (mp_cmp(&t1, &c) != 0) {
1723         mp_toradix(&t1, g_intbuf, 16);
1724         mp_toradix(&c, a_intbuf, 16);
1725         reason("error: invmod test 12 computed %s, expected %s\n",
1726                g_intbuf, a_intbuf);
1727         return 1;
1728     }
1729 
1730     mp_clear(&a);
1731     mp_clear(&m);
1732     mp_clear(&c);
1733     mp_clear(&t1);
1734     mp_clear(&t2);
1735     mp_clear(&t3);
1736     mp_clear(&t4);
1737     mp_clear(&p1);
1738     mp_clear(&p2);
1739     mp_clear(&p3);
1740     mp_clear(&p4);
1741     mp_clear(&p5);
1742 
1743     return 0;
1744 }
1745 
1746 /*------------------------------------------------------------------------*/
1747 
1748 int
test_cmp_d(void)1749 test_cmp_d(void)
1750 {
1751     mp_int a;
1752 
1753     mp_init(&a);
1754     mp_read_radix(&a, mp8, 16);
1755 
1756     if (mp_cmp_d(&a, md8) >= 0) {
1757         reason("error: %s >= " DIGIT_FMT "\n", mp8, md8);
1758         mp_clear(&a);
1759         return 1;
1760     }
1761 
1762     mp_read_radix(&a, mp5, 16);
1763 
1764     if (mp_cmp_d(&a, md8) <= 0) {
1765         reason("error: %s <= " DIGIT_FMT "\n", mp5, md8);
1766         mp_clear(&a);
1767         return 1;
1768     }
1769 
1770     mp_read_radix(&a, mp6, 16);
1771 
1772     if (mp_cmp_d(&a, md1) != 0) {
1773         reason("error: %s != " DIGIT_FMT "\n", mp6, md1);
1774         mp_clear(&a);
1775         return 1;
1776     }
1777 
1778     mp_clear(&a);
1779     return 0;
1780 }
1781 
1782 /*------------------------------------------------------------------------*/
1783 
1784 int
test_cmp_z(void)1785 test_cmp_z(void)
1786 {
1787     mp_int a;
1788 
1789     mp_init(&a);
1790     mp_read_radix(&a, mp6, 16);
1791 
1792     if (mp_cmp_z(&a) != 0) {
1793         reason("error: someone thinks a zero value is non-zero\n");
1794         mp_clear(&a);
1795         return 1;
1796     }
1797 
1798     mp_read_radix(&a, mp1, 16);
1799 
1800     if (mp_cmp_z(&a) <= 0) {
1801         reason("error: someone thinks a positive value is non-positive\n");
1802         mp_clear(&a);
1803         return 1;
1804     }
1805 
1806     mp_read_radix(&a, mp4, 16);
1807 
1808     if (mp_cmp_z(&a) >= 0) {
1809         reason("error: someone thinks a negative value is non-negative\n");
1810         mp_clear(&a);
1811         return 1;
1812     }
1813 
1814     mp_clear(&a);
1815     return 0;
1816 }
1817 
1818 /*------------------------------------------------------------------------*/
1819 
1820 int
test_cmp(void)1821 test_cmp(void)
1822 {
1823     mp_int a, b;
1824 
1825     mp_init(&a);
1826     mp_init(&b);
1827     mp_read_radix(&a, mp3, 16);
1828     mp_read_radix(&b, mp4, 16);
1829 
1830     if (mp_cmp(&a, &b) <= 0) {
1831         reason("error: %s <= %s\n", mp3, mp4);
1832         mp_clear(&a);
1833         mp_clear(&b);
1834         return 1;
1835     }
1836 
1837     mp_read_radix(&b, mp3, 16);
1838     if (mp_cmp(&a, &b) != 0) {
1839         reason("error: %s != %s\n", mp3, mp3);
1840         mp_clear(&a);
1841         mp_clear(&b);
1842         return 1;
1843     }
1844 
1845     mp_read_radix(&a, mp5, 16);
1846     if (mp_cmp(&a, &b) >= 0) {
1847         reason("error: %s >= %s\n", mp5, mp3);
1848         mp_clear(&a);
1849         mp_clear(&b);
1850         return 1;
1851     }
1852 
1853     mp_clear(&a);
1854     mp_clear(&b);
1855     return 0;
1856 }
1857 
1858 /*------------------------------------------------------------------------*/
1859 
1860 int
test_cmp_mag(void)1861 test_cmp_mag(void)
1862 {
1863     mp_int a, b;
1864 
1865     mp_init(&a);
1866     mp_init(&b);
1867     mp_read_radix(&a, mp5, 16);
1868     mp_read_radix(&b, mp4, 16);
1869 
1870     if (mp_cmp_mag(&a, &b) >= 0) {
1871         reason("error: %s >= %s\n", mp5, mp4);
1872         mp_clear(&a);
1873         mp_clear(&b);
1874         return 1;
1875     }
1876 
1877     mp_read_radix(&b, mp5, 16);
1878     if (mp_cmp_mag(&a, &b) != 0) {
1879         reason("error: %s != %s\n", mp5, mp5);
1880         mp_clear(&a);
1881         mp_clear(&b);
1882         return 1;
1883     }
1884 
1885     mp_read_radix(&a, mp1, 16);
1886     if (mp_cmp_mag(&b, &a) >= 0) {
1887         reason("error: %s >= %s\n", mp5, mp1);
1888         mp_clear(&a);
1889         mp_clear(&b);
1890         return 1;
1891     }
1892 
1893     mp_clear(&a);
1894     mp_clear(&b);
1895     return 0;
1896 }
1897 
1898 /*------------------------------------------------------------------------*/
1899 
1900 int
test_parity(void)1901 test_parity(void)
1902 {
1903     mp_int a;
1904 
1905     mp_init(&a);
1906     mp_read_radix(&a, mp1, 16);
1907 
1908     if (!mp_isodd(&a)) {
1909         reason("error: expected operand to be odd, but it isn't\n");
1910         mp_clear(&a);
1911         return 1;
1912     }
1913 
1914     mp_read_radix(&a, mp6, 16);
1915 
1916     if (!mp_iseven(&a)) {
1917         reason("error: expected operand to be even, but it isn't\n");
1918         mp_clear(&a);
1919         return 1;
1920     }
1921 
1922     mp_clear(&a);
1923     return 0;
1924 }
1925 
1926 /*------------------------------------------------------------------------*/
1927 
1928 int
test_gcd(void)1929 test_gcd(void)
1930 {
1931     mp_int a, b;
1932     int out = 0;
1933 
1934     mp_init(&a);
1935     mp_init(&b);
1936     mp_read_radix(&a, mp7, 16);
1937     mp_read_radix(&b, mp1, 16);
1938 
1939     mp_gcd(&a, &b, &a);
1940     mp_toradix(&a, g_intbuf, 16);
1941 
1942     if (strcmp(g_intbuf, g_mp71) != 0) {
1943         reason("error: computed %s, expected %s\n", g_intbuf, g_mp71);
1944         out = 1;
1945     }
1946 
1947     mp_clear(&a);
1948     mp_clear(&b);
1949     return out;
1950 }
1951 
1952 /*------------------------------------------------------------------------*/
1953 
1954 int
test_lcm(void)1955 test_lcm(void)
1956 {
1957     mp_int a, b;
1958     int out = 0;
1959 
1960     mp_init(&a);
1961     mp_init(&b);
1962     mp_read_radix(&a, mp10, 16);
1963     mp_read_radix(&b, mp11, 16);
1964 
1965     mp_lcm(&a, &b, &a);
1966     mp_toradix(&a, g_intbuf, 16);
1967 
1968     if (strcmp(g_intbuf, l_mp1011) != 0) {
1969         reason("error: computed %s, expected%s\n", g_intbuf, l_mp1011);
1970         out = 1;
1971     }
1972 
1973     mp_clear(&a);
1974     mp_clear(&b);
1975 
1976     return out;
1977 }
1978 
1979 /*------------------------------------------------------------------------*/
1980 
1981 int
test_convert(void)1982 test_convert(void)
1983 {
1984     int ix;
1985     mp_int a;
1986 
1987     mp_init(&a);
1988     mp_read_radix(&a, mp9, 16);
1989 
1990     for (ix = LOW_RADIX; ix <= HIGH_RADIX; ix++) {
1991         mp_toradix(&a, g_intbuf, ix);
1992 
1993         if (strcmp(g_intbuf, v_mp9[ix - LOW_RADIX]) != 0) {
1994             reason("error: radix %d, computed %s, expected %s\n",
1995                    ix, g_intbuf, v_mp9[ix - LOW_RADIX]);
1996             mp_clear(&a);
1997             return 1;
1998         }
1999     }
2000 
2001     mp_clear(&a);
2002     return 0;
2003 }
2004 
2005 /*------------------------------------------------------------------------*/
2006 
2007 int
test_raw(void)2008 test_raw(void)
2009 {
2010     int len, out = 0;
2011     mp_int a;
2012     char *buf;
2013 
2014     mp_init(&a);
2015     mp_read_radix(&a, mp4, 16);
2016 
2017     len = mp_raw_size(&a);
2018     if (len != sizeof(b_mp4)) {
2019         reason("error: test_raw: expected length %d, computed %d\n", sizeof(b_mp4),
2020                len);
2021         mp_clear(&a);
2022         return 1;
2023     }
2024 
2025     buf = calloc(len, sizeof(char));
2026     mp_toraw(&a, buf);
2027 
2028     if (memcmp(buf, b_mp4, sizeof(b_mp4)) != 0) {
2029         reason("error: test_raw: binary output does not match test vector\n");
2030         out = 1;
2031     }
2032 
2033     free(buf);
2034     mp_clear(&a);
2035 
2036     return out;
2037 }
2038 
2039 /*------------------------------------------------------------------------*/
2040 
2041 int
test_pprime(void)2042 test_pprime(void)
2043 {
2044     mp_int p;
2045     int err = 0;
2046     mp_err res;
2047 
2048     mp_init(&p);
2049     mp_read_radix(&p, mp7, 16);
2050 
2051     if (mpp_pprime(&p, 5) != MP_YES) {
2052         reason("error: %s failed Rabin-Miller test, but is prime\n", mp7);
2053         err = 1;
2054     }
2055 
2056     IFOK(mp_set_int(&p, 9));
2057     res = mpp_pprime(&p, 50);
2058     if (res == MP_YES) {
2059         reason("error: 9 is composite but passed Rabin-Miller test\n");
2060         err = 1;
2061     } else if (res != MP_NO) {
2062         reason("test mpp_pprime(9, 50) failed: error %d\n", res);
2063         err = 1;
2064     }
2065 
2066     IFOK(mp_set_int(&p, 15));
2067     res = mpp_pprime(&p, 50);
2068     if (res == MP_YES) {
2069         reason("error: 15 is composite but passed Rabin-Miller test\n");
2070         err = 1;
2071     } else if (res != MP_NO) {
2072         reason("test mpp_pprime(15, 50) failed: error %d\n", res);
2073         err = 1;
2074     }
2075 
2076     mp_clear(&p);
2077 
2078     return err;
2079 }
2080 
2081 /*------------------------------------------------------------------------*/
2082 
2083 int
test_fermat(void)2084 test_fermat(void)
2085 {
2086     mp_int p;
2087     mp_err res;
2088     int err = 0;
2089 
2090     mp_init(&p);
2091     mp_read_radix(&p, mp7, 16);
2092 
2093     if ((res = mpp_fermat(&p, 2)) != MP_YES) {
2094         reason("error: %s failed Fermat test on 2: %s\n", mp7,
2095                mp_strerror(res));
2096         ++err;
2097     }
2098 
2099     if ((res = mpp_fermat(&p, 3)) != MP_YES) {
2100         reason("error: %s failed Fermat test on 3: %s\n", mp7,
2101                mp_strerror(res));
2102         ++err;
2103     }
2104 
2105     mp_clear(&p);
2106 
2107     return err;
2108 }
2109 
2110 /*------------------------------------------------------------------------*/
2111 /* Like fprintf(), but only if we are behaving in a verbose manner        */
2112 
2113 void
reason(char * fmt,...)2114 reason(char *fmt, ...)
2115 {
2116     va_list ap;
2117 
2118     if (!g_verbose)
2119         return;
2120 
2121     va_start(ap, fmt);
2122     vfprintf(stderr, fmt, ap);
2123     va_end(ap);
2124 }
2125 
2126 /*------------------------------------------------------------------------*/
2127 /* HERE THERE BE DRAGONS                                                  */
2128