Back to index

lightning-sunbird  0.9+nobinonly
mpi-test.c
Go to the documentation of this file.
00001 /*
00002  * mpi-test.c
00003  *
00004  * This is a general test suite for the MPI library, which tests
00005  * all the functions in the library with known values.  The program
00006  * exits with a zero (successful) status if the tests pass, or a 
00007  * nonzero status if the tests fail.
00008  *
00009  * ***** BEGIN LICENSE BLOCK *****
00010  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00011  *
00012  * The contents of this file are subject to the Mozilla Public License Version
00013  * 1.1 (the "License"); you may not use this file except in compliance with
00014  * the License. You may obtain a copy of the License at
00015  * http://www.mozilla.org/MPL/
00016  *
00017  * Software distributed under the License is distributed on an "AS IS" basis,
00018  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00019  * for the specific language governing rights and limitations under the
00020  * License.
00021  *
00022  * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
00023  *
00024  * The Initial Developer of the Original Code is
00025  * Michael J. Fromberger.
00026  * Portions created by the Initial Developer are Copyright (C) 1999
00027  * the Initial Developer. All Rights Reserved.
00028  *
00029  * Contributor(s):
00030  *   Netscape Communications Corporation
00031  *
00032  * Alternatively, the contents of this file may be used under the terms of
00033  * either the GNU General Public License Version 2 or later (the "GPL"), or
00034  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00035  * in which case the provisions of the GPL or the LGPL are applicable instead
00036  * of those above. If you wish to allow use of your version of this file only
00037  * under the terms of either the GPL or the LGPL, and not to allow others to
00038  * use your version of this file under the terms of the MPL, indicate your
00039  * decision by deleting the provisions above and replace them with the notice
00040  * and other provisions required by the GPL or the LGPL. If you do not delete
00041  * the provisions above, a recipient may use your version of this file under
00042  * the terms of any one of the MPL, the GPL or the LGPL.
00043  *
00044  * ***** END LICENSE BLOCK ***** */
00045 /* $Id: mpi-test.c,v 1.13 2005/02/25 04:30:11 julien.pierre.bugs%sun.com Exp $ */
00046 
00047 #include <stdio.h>
00048 #include <stdlib.h>
00049 #include <string.h>
00050 #include <stdarg.h>
00051 #include <limits.h>
00052 #include <time.h>
00053 
00054 #include "mpi.h"
00055 #include "mpprime.h"
00056 
00057 #include "test-info.c"
00058 
00059 /* ZS means Zero Suppressed (no leading zeros) */
00060 #if MP_USE_LONG_DIGIT 
00061 #define ZS_DIGIT_FMT         "%lX"
00062 #elif MP_USE_LONG_LONG_DIGIT
00063 #define ZS_DIGIT_FMT         "%llX"
00064 #elif MP_USE_UINT_DIGIT 
00065 #define ZS_DIGIT_FMT         "%X"
00066 #else
00067 #error "unknown type of digit"
00068 #endif
00069 
00070 /*
00071   Test vectors
00072 
00073   If you intend to change any of these values, you must also recompute
00074   the corresponding solutions below.  Basically, these are just hex
00075   strings (for the big integers) or integer values (for the digits).
00076 
00077   The comparison tests think they know what relationships hold between
00078   these values.  If you change that, you may have to adjust the code
00079   for the comparison tests accordingly.  Most of the other tests
00080   should be fine as long as you re-compute the solutions, though.
00081  */
00082 const char   *mp1  = "639A868CDA0C569861B";
00083 const char   *mp2  = "AAFC0A3FE45E5E09DBE2C29";
00084 const char   *mp3  = "B55AA8DF8A7E83241F38AC7A9E479CAEF2E4D7C5";
00085 const char   *mp4  = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
00086 const char   *mp5  = "F595CB42";
00087 const char   *mp5a = "-4B597E";
00088 const char   *mp6  = "0";
00089 const char   *mp7  = "EBFA7121CD838CE6439CC59DDB4CBEF3";
00090 const char   *mp8  = "5";
00091 const char   *mp9  = "F74A2876A1432698923B0767DA19DCF3D71795EE";
00092 const char   *mp10 = "9184E72A000";
00093 const char   *mp11 = "54D79A3557E8";
00094 const char   *mp12 = "10000000000000000";
00095 const char   *mp13 = 
00096 "34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342BDAB6163963C"
00097 "D5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45F2B050D226E6DA88";
00098 const char   *mp14 =
00099 "AC3FA0EABAAC45724814D798942A1E28E14C81E0DE8055CED630E7689DA648683645DB6E"
00100 "458D9F5338CC3D4E33A5D1C9BF42780133599E60DEE0049AFA8F9489501AE5C9AA2B8C13"
00101 "FD21285A538B2CA87A626BB56E0A654C8707535E637FF4E39174157402BDE3AA30C9F134"
00102 "0C1307BAA864B075A9CC828B6A5E2B2BF1AE406D920CC5E7657D7C0E697DEE5375773AF9"
00103 "E200A1B8FAD7CD141F9EE47ABB55511FEB9A4D99EBA22F3A3FF6792FA7EE9E5DC0EE94F7"
00104 "7A631EDF3D7DD7C2DAAAFDF234D60302AB63D5234CEAE941B9AF0ADDD9E6E3A940A94EE5"
00105 "5DB45A7C66E61EDD0477419BBEFA44C325129601C4F45671C6A0E64665DF341D17FBC71F"
00106 "77418BD9F4375DDB3B9D56126526D8E5E0F35A121FD4F347013DA880020A752324F31DDD"
00107 "9BCDB13A3B86E207A2DE086825E6EEB87B3A64232CFD8205B799BC018634AAE193F19531"
00108 "D6EBC19A75F27CFFAA03EB5974898F53FD569AA5CE60F431B53B0CDE715A5F382405C9C4"
00109 "761A8E24888328F09F7BCE4E8D80C957DF177629C8421ACCD0C268C63C0DD47C3C0D954F"
00110 "D79F7D7297C6788DF4B3E51381759864D880ACA246DF09533739B8BB6085EAF7AE8DC2D9"
00111 "F224E6874926C8D24D34B457FD2C9A586C6B99582DC24F787A39E3942786CF1D494B6EB4"
00112 "A513498CDA0B217C4E80BCE7DA1C704C35E071AC21E0DA9F57C27C3533F46A8D20B04137"
00113 "C1B1384BE4B2EB46";
00114 const char   *mp15 = 
00115 "39849CF7FD65AF2E3C4D87FE5526221103D90BA26A6642FFE3C3ECC0887BBBC57E011BF1"
00116 "05D822A841653509C68F79EBE51C0099B8CBB04DEF31F36F5954208A3209AC122F0E11D8"
00117 "4AE67A494D78336A2066D394D42E27EF6B03DDAF6D69F5112C93E714D27C94F82FC7EF77"
00118 "445768C68EAE1C4A1407BE1B303243391D325090449764AE469CC53EC8012C4C02A72F37"
00119 "07ED7275D2CC8D0A14B5BCC6BF264941520EBA97E3E6BAE4EE8BC87EE0DDA1F5611A6ECB"
00120 "65F8AEF4F184E10CADBDFA5A2FEF828901D18C20785E5CC63473D638762DA80625003711"
00121 "9E984AC43E707915B133543AF9D5522C3E7180DC58E1E5381C1FB7DC6A5F4198F3E88FA6"
00122 "CBB6DFA8B2D1C763226B253E18BCCB79A29EE82D2DE735078C8AE3C3C86D476AAA08434C"
00123 "09C274BDD40A1D8FDE38D6536C22F44E807EB73DE4FB36C9F51E0BC835DDBE3A8EFCF2FE"
00124 "672B525769DC39230EE624D5EEDBD837C82A52E153F37378C3AD68A81A7ADBDF3345DBCE"
00125 "8FA18CA1DE618EF94DF72EAD928D4F45B9E51632ACF158CF8332C51891D1D12C2A7E6684"
00126 "360C4BF177C952579A9F442CFFEC8DAE4821A8E7A31C4861D8464CA9116C60866C5E72F7"
00127 "434ADBED36D54ACDFDFF70A4EFB46E285131FE725F1C637D1C62115EDAD01C4189716327"
00128 "BFAA79618B1656CBFA22C2C965687D0381CC2FE0245913C4D8D96108213680BD8E93E821"
00129 "822AD9DDBFE4BD04";
00130 const char   *mp16 = "4A724340668DB150339A70";
00131 const char   *mp17 = "8ADB90F58";
00132 const char   *mp18 = "C64C230AB20E5";
00133 const char *mp19 = 
00134 "F1C9DACDA287F2E3C88DCE2393B8F53DAAAC1196DC36510962B6B59454CFE64B";
00135 const char *mp20 = 
00136 "D445662C8B6FE394107B867797750C326E0F4A967E135FC430F6CD7207913AC7";
00137 const char* mp21 = "2";
00138 
00139 const mp_digit md1 = 0;
00140 const mp_digit md2 = 0x1;
00141 const mp_digit md3 = 0x80;
00142 const mp_digit md4 = 0x9C97;
00143 const mp_digit md5 = 0xF5BF;
00144 const mp_digit md6 = 0x14A0;
00145 const mp_digit md7 = 0x03E8;
00146 const mp_digit md8 = 0x0101;
00147 const mp_digit md9 = 0xA;
00148 
00149 /* 
00150    Solutions of the form x_mpABC, where:
00151 
00152    x = (p)roduct, (s)um, (d)ifference, (q)uotient, (r)emainder, (g)cd,
00153        (i)nverse, (e)xponent, square roo(t), (g)cd, (l)cm.  A
00154        leading 'm' indicates a modular operation, e.g. ms_mp12 is the
00155        modular sum of operands 1 and 2
00156 
00157    ABC are the operand numbers involved in the computation.  If a 'd'
00158    precedes the number, it is a digit operand; if a 'c' precedes it,
00159    it is a constant; otherwise, it is a full integer.  
00160  */
00161 
00162 const char *p_mp12   = "4286AD72E095C9FE009938750743174ADDD7FD1E53";
00163 const char *p_mp34   = "-46BDBD66CA108C94A8CF46C325F7B6E2F2BA82D35"
00164                        "A1BFD6934C441EE369B60CA29BADC26845E918B";
00165 const char *p_mp57   = "E260C265A0A27C17AD5F4E59D6E0360217A2EBA6";
00166 const char *p_mp22   = "7233B5C1097FFC77CCF55928FDC3A5D31B712FDE7A1E91";
00167 const char *p_mp1d4  = "3CECEA2331F4220BEF68DED";
00168 const char *p_mp8d6  = "6720";
00169 const char *p_mp1113 =
00170 "11590FC3831C8C3C51813142C88E566408DB04F9E27642F6471A1822E0100B12F7F1"
00171 "5699A127C0FA9D26DCBFF458522661F30C6ADA4A07C8C90F9116893F6DBFBF24C3A2"
00172 "4340";
00173 const char *p_mp1415 = 
00174 "26B36540DE8B3586699CCEAE218A2842C7D5A01590E70C4A26E789107FBCDB06AA2C"
00175 "6DDC39E6FA18B16FCB2E934C9A5F844DAD60EE3B1EA82199EC5E9608F67F860FB965"
00176 "736055DF0E8F2540EB28D07F47E309B5F5D7C94FF190AB9C83A6970160CA700B1081"
00177 "F60518132AF28C6CEE6B7C473E461ABAC52C39CED50A08DD4E7EA8BA18DAD545126D"
00178 "A388F6983C29B6BE3F9DCBC15766E8E6D626A92C5296A9C4653CAE5788350C0E2107"
00179 "F57E5E8B6994C4847D727FF1A63A66A6CEF42B9C9E6BD04C92550B85D5527DE8A132"
00180 "E6BE89341A9285C7CE7FB929D871BBCBD0ED2863B6B078B0DBB30FCA66D6C64284D6"
00181 "57F394A0271E15B6EC7A9D530EBAC6CA262EF6F97E1A29FCE7749240E4AECA591ECF"
00182 "272122BC587370F9371B67BB696B3CDC1BC8C5B64B6280994EBA00CDEB8EB0F5D06E"
00183 "18F401D65FDCECF23DD7B9BB5B4C5458AEF2CCC09BA7F70EACB844750ACFD027521E"
00184 "2E047DE8388B35F8512D3DA46FF1A12D4260213602BF7BFFDB6059439B1BD0676449"
00185 "8D98C74F48FB3F548948D5BA0C8ECFCD054465132DC43466D6BBD59FBAF8D6D4E157"
00186 "2D612B40A956C7D3E140F3B8562EF18568B24D335707D5BAC7495014DF2444172426"
00187 "FD099DED560D30D1F945386604AFC85C64BD1E5F531F5C7840475FC0CF0F79810012"
00188 "4572BAF5A9910CDBD02B27FFCC3C7E5E88EF59F3AE152476E33EDA696A4F751E0AE4"
00189 "A3D2792DEA78E25B9110E12A19EFD09EA47FF9D6594DA445478BEB6901EAF8A35B2D"
00190 "FD59BEE9BF7AA8535B7D326EFA5AA2121B5EBE04DD85827A3D43BD04F4AA6D7B62A2"
00191 "B6D7A3077286A511A431E1EF75FCEBA3FAE9D5843A8ED17AA02BBB1B571F904699C5"
00192 "A6073F87DDD012E2322AB3F41F2A61F428636FE86914148E19B8EF8314ED83332F2F"
00193 "8C2ADE95071E792C0A68B903E060DD322A75FD0C2B992059FCCBB58AFA06B50D1634"
00194 "BBD93F187FCE0566609FCC2BABB269C66CEB097598AA17957BB4FDA3E64A1B30402E"
00195 "851CF9208E33D52E459A92C63FBB66435BB018E155E2C7F055E0B7AB82CD58FC4889"
00196 "372ED9EEAC2A07E8E654AB445B9298D2830D6D4DFD117B9C8ABE3968927DC24B3633"
00197 "BAD6E6466DB45DDAE87A0AB00336AC2CCCE176704F7214FCAB55743AB76C2B6CA231"
00198 "7984610B27B5786DE55C184DDF556EDFEA79A3652831940DAD941E243F482DC17E50"
00199 "284BC2FB1AD712A92542C573E55678878F02DFD9E3A863C7DF863227AEDE14B47AD3"
00200 "957190124820ADC19F5353878EDB6BF7D0C77352A6E3BDB53EEB88F5AEF6226D6E68"
00201 "756776A8FB49B77564147A641664C2A54F7E5B680CCC6A4D22D894E464DF20537094"
00202 "548F1732452F9E7F810C0B4B430C073C0FBCE03F0D03F82630654BCE166AA772E1EE"
00203 "DD0C08D3E3EBDF0AF54203B43AFDFC40D8FC79C97A4B0A4E1BEB14D8FCEFDDED8758"
00204 "6ED65B18";
00205 const char *p_mp2121 = "4";
00206 const char *mp_mp345 = "B9B6D3A3";
00207 const char *mp_mp335 = "16609C2D";
00208 
00209 const char *s_mp13   = "B55AA8DF8A7E83241F38B2B446B06A4FB84E5DE0";
00210 const char *s_mp34   = "517EE6B92EF65C965736EB6BF7C325F73504CEB6";
00211 const char *s_mp46   = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
00212 const char *s_mp5d4  = "F59667D9";
00213 const char *s_mp2d5  = "AAFC0A3FE45E5E09DBF21E8";
00214 const char *s_mp1415 = 
00215 "E5C43DE2B811F4A084625F96E9504039E5258D8348E698CEB9F4D4292622042DB446"
00216 "F75F4B65C1FB7A317257FA354BB5A45E789AEC254EAECE11F80A53E3B513822491DB"
00217 "D9399DEC4807A2A3A10360129AC93F4A42388D3BF20B310DD0E9E9F4BE07FC88D53A"
00218 "78A26091E0AB506A70813712CCBFBDD440A69A906E650EE090FDD6A42A95AC1A414D"
00219 "317F1A9F781E6A30E9EE142ECDA45A1E3454A1417A7B9A613DA90831CF88EA1F2E82"
00220 "41AE88CC4053220903C2E05BCDD42F02B8CF8868F84C64C5858BAD356143C5494607"
00221 "EE22E11650148BAF65A985F6FC4CA540A55697F2B5AA95D6B8CF96EF638416DE1DD6"
00222 "3BA9E2C09E22D03E75B60BE456C642F86B82A709253E5E087B507DE3A45F8392423F"
00223 "4DBC284E8DC88C43CA77BC8DCEFB6129A59025F80F90FF978116DEBB9209E306FBB9"
00224 "1B6111F8B8CFACB7C7C9BC12691C22EE88303E1713F1DFCEB622B8EA102F6365678B"
00225 "C580ED87225467AA78E875868BD53B17574BA59305BC1AC666E4B7E9ED72FCFC200E"
00226 "189D98FC8C5C7533739C53F52DDECDDFA5A8668BFBD40DABC9640F8FCAE58F532940"
00227 "8162261320A25589E9FB51B50F80056471F24B7E1AEC35D1356FC2747FFC13A04B34"
00228 "24FCECE10880BD9D97CA8CDEB2F5969BF4F30256EB5ED2BCD1DC64BDC2EE65217848"
00229 "48A37FB13F84ED4FB7ACA18C4639EE64309BDD3D552AEB4AAF44295943DC1229A497"
00230 "A84A";
00231 
00232 const char *ms_mp345 = "1E71E292";
00233 
00234 const char *d_mp12   = "-AAFBA6A55DD183FD854A60E";
00235 const char *d_mp34   = "119366B05E606A9B1E73A6D8944CC1366B0C4E0D4";
00236 const char *d_mp5d4  = "F5952EAB";
00237 const char *d_mp6d2  = "-1";
00238 const char *md_mp345 = "26596B86";
00239 
00240 const char *q_mp42   = "-95825A1FFA1A155D5";
00241 const char *r_mp42   = "-6312E99D7700A3DCB32ADF2";
00242 const char *q_mp45a  = "15344CDA3D841F661D2B61B6EDF7828CE36";
00243 const char *r_mp45a  = "-47C47B";
00244 const char *q_mp7c2  = "75FD3890E6C1C67321CE62CEEDA65F79";
00245 const char *q_mp3d6  = "8CAFD53C272BD6FE8B0847BDC3B539EFAB5C3";
00246 const char *r_mp3d6  = "1E5";
00247 const char *r_mp5d5  = "1257";
00248 const char *r_mp47   = "B3A9018D970281A90FB729A181D95CB8";
00249 const char *q_mp1404 = 
00250 "-1B994D869142D3EF6123A3CBBC3C0114FA071CFCEEF4B7D231D65591D32501AD80F"
00251 "FF49AE4EC80514CC071EF6B42521C2508F4CB2FEAD69A2D2EF3934087DCAF88CC4C4"
00252 "659F1CA8A7F4D36817D802F778F1392337FE36302D6865BF0D4645625DF8BB044E19"
00253 "930635BE2609FAC8D99357D3A9F81F2578DE15A300964188292107DAC980E0A08CD7"
00254 "E938A2135FAD45D50CB1D8C2D4C4E60C27AB98B9FBD7E4DBF752C57D2674520E4BB2"
00255 "7E42324C0EFE84FB3E38CF6950E699E86FD45FE40D428400F2F94EDF7E94FAE10B45"
00256 "89329E1BF61E5A378C7B31C9C6A234F8254D4C24823B84D0BF8D671D8BC9154DFAC9"
00257 "49BD8ACABD6BD32DD4DC587F22C86153CB3954BDF7C2A890D623642492C482CF3E2C"
00258 "776FC019C3BBC61688B485E6FD35D6376089C1E33F880E84C4E51E8ABEACE1B3FB70"
00259 "3EAD0E28D2D44E7F1C0A859C840775E94F8C1369D985A3C5E8114B21D68B3CBB75D2"
00260 "791C586153C85B90CAA483E57A40E2D97950AAB84920A4396C950C87C7FFFE748358"
00261 "42A0BF65445B26D40F05BE164B822CA96321F41D85A289C5F5CD5F438A78704C9683"
00262 "422299D21899A22F853B0C93081CC9925E350132A0717A611DD932A68A0ACC6E4C7F"
00263 "7F685EF8C1F4910AEA5DC00BB5A36FCA07FFEAA490C547F6E14A08FE87041AB803E1"
00264 "BD9E23E4D367A2C35762F209073DFF48F3";
00265 const char *r_mp1404 = "12FF98621ABF63144BFFC3207AC8FC10D8D1A09";
00266 
00267 const char *q_mp13c  = 
00268               "34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342"
00269               "BDAB6163963CD5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45";
00270 const char *r_mp13c  = "F2B050D226E6DA88";
00271 const char *q_mp9c16 = "F74A2876A1432698923B0767DA19DCF3D71795E";
00272 const char *r_mp9c16 = "E";
00273 
00274 const char *e_mp5d9 = "A8FD7145E727A20E52E73D22990D35D158090307A"
00275                     "13A5215AAC4E9AB1E96BD34E531209E03310400";
00276 const char *e_mp78  = "AA5F72C737DFFD8CCD108008BFE7C79ADC01A819B"
00277                     "32B75FB82EC0FB8CA83311DA36D4063F1E57857A2"
00278                     "1AB226563D84A15BB63CE975FF1453BD6750C58D9"
00279                     "D113175764F5D0B3C89B262D4702F4D9640A3";
00280 const char *me_mp817 = "E504493ACB02F7F802B327AB13BF25";
00281 const char *me_mp5d47 = "1D45ED0D78F2778157992C951DD2734C";
00282 const char *me_mp1512 = "FB5B2A28D902B9D9";
00283 const char *me_mp161718 = "423C6AC6DBD74";
00284 const char *me_mp5114 =
00285 "64F0F72807993578BBA3C7C36FFB184028F9EB9A810C92079E1498D8A80FC848E1F0"
00286 "25F1DE43B7F6AC063F5CC29D8A7C2D7A66269D72BF5CDC327AF88AF8EF9E601DCB0A"
00287 "3F35BFF3525FB1B61CE3A25182F17C0A0633B4089EA15BDC47664A43FEF639748AAC"
00288 "19CF58E83D8FA32CD10661D2D4210CC84792937E6F36CB601851356622E63ADD4BD5"
00289 "542412C2E0C4958E51FD2524AABDC7D60CFB5DB332EEC9DC84210F10FAE0BA2018F2"
00290 "14C9D6867C9D6E49CF28C18D06CE009FD4D04BFC8837C3FAAA773F5CCF6DED1C22DE"
00291 "181786AFE188540586F2D74BF312E595244E6936AE52E45742109BAA76C36F2692F5"
00292 "CEF97AD462B138BE92721194B163254CBAAEE9B9864B21CCDD5375BCAD0D24132724"
00293 "113D3374B4BCF9AA49BA5ACBC12288C0BCF46DCE6CB4A241A91BD559B130B6E9CD3D"
00294 "D7A2C8B280C2A278BA9BF5D93244D563015C9484B86D9FEB602501DC16EEBC3EFF19"
00295 "53D7999682BF1A1E3B2E7B21F4BDCA3C355039FEF55B9C0885F98DC355CA7A6D8ECF"
00296 "5F7F1A6E11A764F2343C823B879B44616B56BF6AE3FA2ACF5483660E618882018E3F"
00297 "C8459313BACFE1F93CECC37B2576A5C0B2714BD3EEDEEC22F0E7E3E77B11396B9B99"
00298 "D683F2447A4004BBD4A57F6A616CDDFEC595C4FC19884CC2FC21CF5BF5B0B81E0F83"
00299 "B9DDA0CF4DFF35BB8D31245912BF4497FD0BD95F0C604E26EA5A8EA4F5EAE870A5BD"
00300 "FE8C";
00301 
00302 const char *e_mpc2d3 = "100000000000000000000000000000000";
00303 
00304 const char *t_mp9    = "FB9B6E32FF0452A34746";
00305 const char *i_mp27   = "B6AD8DCCDAF92B6FE57D062FFEE3A99";
00306 const char *i_mp2019 = 
00307 "BDF3D88DC373A63EED92903115B03FC8501910AF68297B4C41870AED3EA9F839";
00308 /* "15E3FE09E8AE5523AABA197BD2D16318D3CA148EDF4AE1C1C52FC96AFAF5680B"; */
00309 
00310 
00311 const char *t_mp15 =
00312 "795853094E59B0008093BCA8DECF68587C64BDCA2F3F7F8963DABC12F1CFFFA9B8C4"
00313 "365232FD4751870A0EF6CA619287C5D8B7F1747D95076AB19645EF309773E9EACEA0"
00314 "975FA4AE16251A8DA5865349C3A903E3B8A2C0DEA3C0720B6020C7FED69AFF62BB72"
00315 "10FAC443F9FFA2950776F949E819260C2AF8D94E8A1431A40F8C23C1973DE5D49AA2"
00316 "0B3FF5DA5C1D5324E712A78FF33A9B1748F83FA529905924A31DF38643B3F693EF9B"
00317 "58D846BB1AEAE4523ECC843FF551C1B300A130B65C1677402778F98C51C10813250E"
00318 "2496882877B069E877B59740DC1226F18A5C0F66F64A5F59A9FAFC5E9FC45AEC0E7A"
00319 "BEE244F7DD3AC268CF512A0E52E4F5BE5B94";
00320 
00321 const char *g_mp71   = "1";
00322 const char *g_mp25   = "7";
00323 const char *l_mp1011 = "C589E3D7D64A6942A000";
00324 
00325 /* mp9 in radices from 5 to 64 inclusive */
00326 #define LOW_RADIX   5
00327 #define HIGH_RADIX  64
00328 const char *v_mp9[] = {
00329   "404041130042310320100141302000203430214122130002340212132414134210033",
00330   "44515230120451152500101352430105520150025145320010504454125502",
00331   "644641136612541136016610100564613624243140151310023515322",
00332   "173512120732412062323044435407317550316717172705712756",
00333   "265785018434285762514442046172754680368422060744852",
00334   "1411774500397290569709059837552310354075408897518",
00335   "184064268501499311A17746095910428222A241708032A",
00336   "47706011B225950B02BB45602AA039893118A85950892",
00337   "1A188C826B982353CB58422563AC602B783101671A86",
00338   "105957B358B89B018958908A9114BC3DDC410B77982",
00339   "CB7B3387E23452178846C55DD9D70C7CA9AEA78E8",
00340   "F74A2876A1432698923B0767DA19DCF3D71795EE",
00341   "17BF7C3673B76D7G7A5GA836277296F806E7453A",
00342   "2EBG8HH3HFA6185D6H0596AH96G24C966DD3HG2",
00343   "6G3HGBFEG8I3F25EAF61B904EIA40CFDH2124F",
00344   "10AHC3D29EBHDF3HD97905CG0JA8061855C3FI",
00345   "3BA5A55J5K699B2D09C38A4B237CH51IHA132",
00346   "EDEA90DJ0B5CB3FGG1C8587FEB99D3C143CA",
00347   "31M26JI1BBD56K3I028MML4EEDMAJK60LGLE",
00348   "GGG5M3142FKKG82EJ28111D70EMHC241E4E",
00349   "4446F4D5H10982023N297BF0DKBBHLLJB0I",
00350   "12E9DEEOBMKAKEP0IM284MIP7FO1O521M46",
00351   "85NN0HD48NN2FDDB1F5BMMKIB8CK20MDPK",
00352   "2D882A7A0O0JPCJ4APDRIB77IABAKDGJP2",
00353   "MFMCI0R7S27AAA3O3L2S8K44HKA7O02CN",
00354   "7IGQS73FFSHC50NNH44B6PTTNLC3M6H78",
00355   "2KLUB3U9850CSN6ANIDNIF1LB29MJ43LH",
00356   "UT52GTL18CJ9H4HR0TJTK6ESUFBHF5FE",
00357   "BTVL87QQBMUGF8PFWU4W3VU7U922QTMW",
00358   "4OG10HW0MSWJBIDEE2PDH24GA7RIHIAA",
00359   "1W8W9AX2DRUX48GXOLMK0PE42H0FEUWN",
00360   "SVWI84VBH069WR15W1U2VTK06USY8Z2",
00361   "CPTPNPDa5TYCPPNLALENT9IMX2GL0W2",
00362   "5QU21UJMRaUYYYYYN6GHSMPOYOXEEUY",
00363   "2O2Q7C6RPPB1SXJ9bR4035SPaQQ3H2W",
00364   "18d994IbT4PHbD7cGIPCRP00bbQO0bc",
00365   "NcDUEEWRO7XT76260WGeBHPVa72RdA",
00366   "BbX2WCF9VfSB5LPdJAdeXKV1fd6LC2",
00367   "60QDKW67P4JSQaTdQg7JE9ISafLaVU",
00368   "33ba9XbDbRdNF4BeDB2XYMhAVDaBdA",
00369   "1RIPZJA8gT5L5H7fTcaRhQ39geMMTc",
00370   "d65j70fBATjcDiidPYXUGcaBVVLME",
00371   "LKA9jhPabDG612TXWkhfT2gMXNIP2",
00372   "BgNaYhjfT0G8PBcYRP8khJCR3C9QE",
00373   "6Wk8RhJTAgDh10fYAiUVB1aM0HacG",
00374   "3dOCjaf78kd5EQNViUZWj3AfFL90I",
00375   "290VWkL3aiJoW4MBbHk0Z0bDo22Ni",
00376   "1DbDZ1hpPZNUDBUp6UigcJllEdC26",
00377   "dFSOLBUM7UZX8Vnc6qokGIOiFo1h",
00378   "NcoUYJOg0HVmKI9fR2ag0S8R2hrK",
00379   "EOpiJ5Te7oDe2pn8ZhAUKkhFHlZh",
00380   "8nXK8rp8neV8LWta1WDgd1QnlWsU",
00381   "5T3d6bcSBtHgrH9bCbu84tblaa7r",
00382   "3PlUDIYUvMqOVCir7AtquK5dWanq",
00383   "2A70gDPX2AtiicvIGGk9poiMtgvu",
00384   "1MjiRxjk10J6SVAxFguv9kZiUnIc",
00385   "rpre2vIDeb4h3sp50r1YBbtEx9L",
00386   "ZHcoip0AglDAfibrsUcJ9M1C8fm",
00387   "NHP18+eoe6uU54W49Kc6ZK7+bT2",
00388   "FTAA7QXGoQOaZi7PzePtFFN5vNk"
00389 };
00390 
00391 const unsigned char b_mp4[] = {
00392   0x01, 
00393 #if MP_DIGIT_MAX > MP_32BIT_MAX
00394   0x00, 0x00, 0x00, 0x00,
00395 #endif
00396   0x63, 0xDB, 0xC2, 0x26, 
00397   0x5B, 0x88, 0x26, 0x8D, 
00398   0xC8, 0x01, 0xC1, 0x0E, 
00399   0xA6, 0x84, 0x76, 0xB7, 
00400   0xBD, 0xE0, 0x09, 0x0F
00401 };
00402 
00403 /* Search for a test suite name in the names table  */
00404 int  find_name(char *name);
00405 void reason(char *fmt, ...);
00406 
00407 /*------------------------------------------------------------------------*/
00408 /*------------------------------------------------------------------------*/
00409 
00410 char g_intbuf[4096];  /* buffer for integer comparison   */
00411 char a_intbuf[4096];  /* buffer for integer comparison   */
00412 int  g_verbose = 1;   /* print out reasons for failure?  */
00413 int  res;
00414 
00415 #define IFOK(x) { if (MP_OKAY > (res = (x))) { \
00416   reason("test %s failed: error %d\n", #x, res); return 1; }}
00417 
00418 int main(int argc, char *argv[])
00419 {
00420   int which, res;
00421 
00422   srand((unsigned int)time(NULL));
00423 
00424   if (argc < 2) {
00425     fprintf(stderr, "Usage: %s <test-suite> | list\n"
00426            "Type '%s help' for assistance\n", argv[0], argv[0]);
00427     return 2;
00428   } else if(argc > 2) {
00429     if(strcmp(argv[2], "quiet") == 0)
00430       g_verbose = 0;
00431   }
00432 
00433   if(strcmp(argv[1], "help") == 0) {
00434     fprintf(stderr, "Help for mpi-test\n\n"
00435            "This program is a test driver for the MPI library, which\n"
00436            "tests all the various functions in the library to make sure\n"
00437            "they are working correctly.  The syntax is:\n"
00438            "    %s <suite-name>\n"
00439            "...where <suite-name> is the name of the test you wish to\n"
00440            "run.  To get a list of the tests, use '%s list'.\n\n"
00441            "The program exits with a status of zero if the test passes,\n"
00442            "or non-zero if it fails.  Ordinarily, failure is accompanied\n"
00443            "by a diagnostic message to standard error.  To suppress this\n"
00444            "add the keyword 'quiet' after the suite-name on the command\n"
00445            "line.\n\n", argv[0], argv[0]);
00446     return 0;
00447   }
00448 
00449   if ((which = find_name(argv[1])) < 0) {
00450     fprintf(stderr, "%s: test suite '%s' is not known\n", argv[0], argv[1]);
00451     return 2;
00452   }
00453 
00454   if((res = (g_tests[which])()) < 0) {
00455     fprintf(stderr, "%s: test suite not implemented yet\n", argv[0]);
00456     return 2;
00457   } else {
00458     return res; 
00459   }
00460 
00461 }
00462 
00463 /*------------------------------------------------------------------------*/
00464 
00465 int find_name(char *name)
00466 {
00467   int ix = 0;
00468   
00469   while(ix < g_count) {
00470     if (strcmp(name, g_names[ix]) == 0)
00471       return ix;
00472     
00473     ++ix;
00474   }
00475   
00476   return -1;
00477 }
00478 
00479 /*------------------------------------------------------------------------*/
00480 
00481 int test_list(void)
00482 {
00483   int ix;
00484   
00485   fprintf(stderr, "There are currently %d test suites available\n",
00486          g_count);
00487   
00488   for(ix = 1; ix < g_count; ix++)
00489     fprintf(stdout, "%-20s %s\n", g_names[ix], g_descs[ix]);
00490   
00491   return 0;
00492 }
00493 
00494 /*------------------------------------------------------------------------*/
00495 
00496 int test_copy(void)
00497 {
00498   mp_int  a, b;
00499   int     ix;
00500 
00501   mp_init(&a); mp_init(&b);
00502 
00503   mp_read_radix(&a, mp3, 16);
00504   mp_copy(&a, &b);
00505 
00506   if(SIGN(&a) != SIGN(&b) || USED(&a) != USED(&b)) {
00507     if(SIGN(&a) != SIGN(&b)) {
00508       reason("error: sign of original is %d, sign of copy is %d\n", 
00509             SIGN(&a), SIGN(&b));
00510     } else {
00511       reason("error: original precision is %d, copy precision is %d\n",
00512             USED(&a), USED(&b));
00513     }
00514     mp_clear(&a); mp_clear(&b);
00515     return 1;
00516   }
00517 
00518   for(ix = 0; ix < USED(&b); ix++) {
00519     if(DIGIT(&a, ix) != DIGIT(&b, ix)) {
00520       reason("error: digit %d " DIGIT_FMT " != " DIGIT_FMT "\n",
00521             ix, DIGIT(&a, ix), DIGIT(&b, ix));
00522       mp_clear(&a); mp_clear(&b);
00523       return 1;
00524     }
00525   }
00526      
00527   mp_clear(&a); mp_clear(&b);
00528   return 0;
00529 }
00530 
00531 /*------------------------------------------------------------------------*/
00532 
00533 int test_exch(void)
00534 {
00535   mp_int  a, b;
00536 
00537   mp_init(&a); mp_init(&b);
00538   mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp1, 16);
00539 
00540   mp_exch(&a, &b);
00541   mp_toradix(&a, g_intbuf, 16);
00542 
00543   mp_clear(&a);
00544   if(strcmp(g_intbuf, mp1) != 0) {
00545     mp_clear(&b);
00546     reason("error: exchange failed\n");
00547     return 1;
00548   }
00549 
00550   mp_toradix(&b, g_intbuf, 16);
00551 
00552   mp_clear(&b);
00553   if(strcmp(g_intbuf, mp7) != 0) {
00554     reason("error: exchange failed\n");
00555     return 1;
00556   }
00557 
00558   return 0;
00559 }
00560 
00561 /*------------------------------------------------------------------------*/
00562 
00563 int test_zero(void)
00564 {
00565   mp_int   a;
00566 
00567   mp_init(&a); mp_read_radix(&a, mp7, 16);
00568   mp_zero(&a);
00569 
00570   if(USED(&a) != 1 || DIGIT(&a, 1) != 0) {
00571     mp_toradix(&a, g_intbuf, 16);
00572     reason("error: result is %s\n", g_intbuf);
00573     mp_clear(&a);
00574     return 1;
00575   }
00576 
00577   mp_clear(&a);
00578   return 0;
00579 }
00580 
00581 /*------------------------------------------------------------------------*/
00582 
00583 int test_set(void)
00584 {
00585   mp_int   a;
00586 
00587   /* Test single digit set */
00588   mp_init(&a); mp_set(&a, 5);
00589   if(DIGIT(&a, 0) != 5) {
00590     mp_toradix(&a, g_intbuf, 16);
00591     reason("error: result is %s, expected 5\n", g_intbuf);
00592     mp_clear(&a);
00593     return 1;
00594   }
00595 
00596   /* Test integer set */
00597   mp_set_int(&a, -4938110);
00598   mp_toradix(&a, g_intbuf, 16);
00599   mp_clear(&a);
00600   if(strcmp(g_intbuf, mp5a) != 0) {
00601     reason("error: result is %s, expected %s\n", g_intbuf, mp5a);
00602     return 1;
00603   }
00604 
00605   return 0;
00606 }
00607 
00608 /*------------------------------------------------------------------------*/
00609 
00610 int test_abs(void)
00611 {
00612   mp_int  a;
00613 
00614   mp_init(&a); mp_read_radix(&a, mp4, 16);
00615   mp_abs(&a, &a);
00616   
00617   if(SIGN(&a) != ZPOS) {
00618     reason("error: sign of result is negative\n");
00619     mp_clear(&a);
00620     return 1;
00621   }
00622 
00623   mp_clear(&a);
00624   return 0;
00625 }
00626 
00627 /*------------------------------------------------------------------------*/
00628 
00629 int test_neg(void)
00630 {
00631   mp_int  a;
00632   mp_sign s;
00633 
00634   mp_init(&a); mp_read_radix(&a, mp4, 16);
00635 
00636   s = SIGN(&a);
00637   mp_neg(&a, &a);
00638   if(SIGN(&a) == s) {
00639     reason("error: sign of result is same as sign of nonzero input\n");
00640     mp_clear(&a);
00641     return 1;
00642   }
00643 
00644   mp_clear(&a);
00645   return 0;
00646 }
00647 
00648 /*------------------------------------------------------------------------*/
00649 
00650 int test_add_d(void)
00651 {
00652   mp_int  a;
00653 
00654   mp_init(&a);
00655   
00656   mp_read_radix(&a, mp5, 16);
00657   mp_add_d(&a, md4, &a);
00658   mp_toradix(&a, g_intbuf, 16);
00659 
00660   if(strcmp(g_intbuf, s_mp5d4) != 0) {
00661     reason("error: computed %s, expected %s\n", g_intbuf, s_mp5d4);
00662     mp_clear(&a);
00663     return 1;
00664   }
00665 
00666   mp_read_radix(&a, mp2, 16);
00667   mp_add_d(&a, md5, &a);
00668   mp_toradix(&a, g_intbuf, 16);
00669 
00670   if(strcmp(g_intbuf, s_mp2d5) != 0) {
00671     reason("error: computed %s, expected %s\n", g_intbuf, s_mp2d5);
00672     mp_clear(&a);
00673     return 1;
00674   }
00675 
00676   mp_clear(&a);
00677   return 0;
00678 }
00679 
00680 /*------------------------------------------------------------------------*/
00681 
00682 int test_add(void)
00683 {
00684   mp_int  a, b;
00685   int     res = 0;
00686 
00687   mp_init(&a); mp_init(&b);
00688 
00689   mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp3, 16);
00690   mp_add(&a, &b, &a);
00691   mp_toradix(&a, g_intbuf, 16);
00692 
00693   if(strcmp(g_intbuf, s_mp13) != 0) {
00694     reason("error: computed %s, expected %s\n", g_intbuf, s_mp13);
00695     res = 1; goto CLEANUP;
00696   }
00697 
00698   mp_read_radix(&a, mp4, 16);
00699   mp_add(&a, &b, &a);
00700   mp_toradix(&a, g_intbuf, 16);
00701 
00702   if(strcmp(g_intbuf, s_mp34) != 0) {
00703     reason("error: computed %s, expected %s\n", g_intbuf, s_mp34);
00704     res = 1; goto CLEANUP;
00705   }
00706 
00707   mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp6, 16);
00708   mp_add(&a, &b, &a);
00709   mp_toradix(&a, g_intbuf, 16);
00710 
00711   if(strcmp(g_intbuf, s_mp46) != 0) {
00712     reason("error: computed %s, expected %s\n", g_intbuf, s_mp46);
00713     res = 1; goto CLEANUP;
00714   }
00715 
00716   mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp15, 16);
00717   mp_add(&a, &b, &a);
00718   mp_toradix(&a, g_intbuf, 16);
00719 
00720   if(strcmp(g_intbuf, s_mp1415) != 0) {
00721     reason("error: computed %s, expected %s\n", g_intbuf, s_mp1415);
00722     res = 1;
00723   }
00724 
00725  CLEANUP:
00726   mp_clear(&a); mp_clear(&b);
00727   return res;
00728 }
00729 
00730 /*------------------------------------------------------------------------*/
00731 
00732 int test_sub_d(void)
00733 {
00734   mp_int   a;
00735 
00736   mp_init(&a);
00737   mp_read_radix(&a, mp5, 16);
00738 
00739   mp_sub_d(&a, md4, &a);
00740   mp_toradix(&a, g_intbuf, 16);
00741 
00742   if(strcmp(g_intbuf, d_mp5d4) != 0) {
00743     reason("error: computed %s, expected %s\n", g_intbuf, d_mp5d4);
00744     mp_clear(&a);
00745     return 1;
00746   }
00747 
00748   mp_read_radix(&a, mp6, 16);
00749   
00750   mp_sub_d(&a, md2, &a);
00751   mp_toradix(&a, g_intbuf, 16);
00752   
00753   mp_clear(&a);
00754   if(strcmp(g_intbuf, d_mp6d2) != 0) {
00755     reason("error: computed %s, expected %s\n", g_intbuf, d_mp6d2);
00756     return 1;
00757   }
00758 
00759   return 0;
00760 }
00761 
00762 /*------------------------------------------------------------------------*/
00763 
00764 int test_sub(void)
00765 {
00766   mp_int  a, b;
00767 
00768   mp_init(&a); mp_init(&b);
00769 
00770   mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp2, 16);
00771   mp_sub(&a, &b, &a);
00772   mp_toradix(&a, g_intbuf, 16);
00773 
00774   if(strcmp(g_intbuf, d_mp12) != 0) {
00775     reason("error: computed %s, expected %s\n", g_intbuf, d_mp12);
00776     mp_clear(&a); mp_clear(&b);
00777     return 1;
00778   }
00779 
00780   mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
00781   mp_sub(&a, &b, &a);
00782   mp_toradix(&a, g_intbuf, 16);
00783 
00784   if(strcmp(g_intbuf, d_mp34) != 0) {
00785     reason("error: computed %s, expected %s\n", g_intbuf, d_mp34);
00786     mp_clear(&a); mp_clear(&b);
00787     return 1;
00788   }
00789 
00790   mp_clear(&a); mp_clear(&b);
00791   return 0;
00792 }
00793 
00794 /*------------------------------------------------------------------------*/
00795 
00796 int test_mul_d(void)
00797 {
00798   mp_int   a;
00799 
00800   mp_init(&a);
00801   mp_read_radix(&a, mp1, 16);
00802 
00803   IFOK( mp_mul_d(&a, md4, &a) );
00804   mp_toradix(&a, g_intbuf, 16);
00805   
00806   if(strcmp(g_intbuf, p_mp1d4) != 0) {
00807     reason("error: computed %s, expected %s\n", g_intbuf, p_mp1d4);    
00808     mp_clear(&a);
00809     return 1;
00810   }
00811 
00812   mp_read_radix(&a, mp8, 16);
00813   IFOK( mp_mul_d(&a, md6, &a) );
00814   mp_toradix(&a, g_intbuf, 16);
00815 
00816   mp_clear(&a);
00817   if(strcmp(g_intbuf, p_mp8d6) != 0) {
00818     reason("error: computed %s, expected %s\n", g_intbuf, p_mp8d6); 
00819     return 1;
00820   }
00821 
00822   return 0;
00823 }
00824 
00825 /*------------------------------------------------------------------------*/
00826 
00827 int test_mul(void)
00828 {
00829   mp_int   a, b;
00830   int      res = 0;
00831 
00832   mp_init(&a); mp_init(&b);
00833   mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp2, 16);
00834 
00835   IFOK( mp_mul(&a, &b, &a) );
00836   mp_toradix(&a, g_intbuf, 16);
00837 
00838   if(strcmp(g_intbuf, p_mp12) != 0) {
00839     reason("error: computed %s, expected %s\n", g_intbuf, p_mp12);
00840     res = 1; goto CLEANUP;
00841   }
00842 
00843   mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
00844   IFOK( mp_mul(&a, &b, &a) );
00845   mp_toradix(&a, g_intbuf, 16);
00846 
00847   if(strcmp(g_intbuf, p_mp34) !=0) {
00848     reason("error: computed %s, expected %s\n", g_intbuf, p_mp34);
00849     res = 1; goto CLEANUP;
00850   }
00851 
00852   mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp7, 16);
00853   IFOK( mp_mul(&a, &b, &a) );
00854   mp_toradix(&a, g_intbuf, 16);
00855 
00856   if(strcmp(g_intbuf, p_mp57) != 0) {
00857     reason("error: computed %s, expected %s\n", g_intbuf, p_mp57);
00858     res = 1; goto CLEANUP;
00859   }
00860 
00861   mp_read_radix(&a, mp11, 16); mp_read_radix(&b, mp13, 16);
00862   IFOK( mp_mul(&a, &b, &a) );
00863   mp_toradix(&a, g_intbuf, 16);
00864 
00865   if(strcmp(g_intbuf, p_mp1113) != 0) {
00866     reason("error: computed %s, expected %s\n", g_intbuf, p_mp1113);
00867     res = 1; goto CLEANUP;
00868   }
00869 
00870   mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp15, 16);
00871   IFOK( mp_mul(&a, &b, &a) );
00872   mp_toradix(&a, g_intbuf, 16);
00873 
00874   if(strcmp(g_intbuf, p_mp1415) != 0) {
00875     reason("error: computed %s, expected %s\n", g_intbuf, p_mp1415);
00876     res = 1;
00877   }
00878   mp_read_radix(&a, mp21, 10); mp_read_radix(&b, mp21, 10);
00879 
00880   IFOK( mp_mul(&a, &b, &a) );
00881   mp_toradix(&a, g_intbuf, 10);
00882 
00883   if(strcmp(g_intbuf, p_mp2121) != 0) {
00884     reason("error: computed %s, expected %s\n", g_intbuf, p_mp2121);
00885     res = 1; goto CLEANUP;
00886   }
00887 
00888  CLEANUP:
00889   mp_clear(&a); mp_clear(&b);
00890   return res;
00891 
00892 }
00893 
00894 /*------------------------------------------------------------------------*/
00895 
00896 int test_sqr(void)
00897 {
00898   mp_int  a;
00899 
00900   mp_init(&a); mp_read_radix(&a, mp2, 16);
00901 
00902   mp_sqr(&a, &a);
00903   mp_toradix(&a, g_intbuf, 16);
00904 
00905   mp_clear(&a);
00906   if(strcmp(g_intbuf, p_mp22) != 0) {
00907     reason("error: computed %s, expected %s\n", g_intbuf, p_mp22);
00908     return 1;
00909   }
00910 
00911   return 0;
00912 }
00913 
00914 /*------------------------------------------------------------------------*/
00915 
00916 int test_div_d(void)
00917 {
00918   mp_int    a, q;
00919   mp_digit  r;
00920   int       err = 0;
00921 
00922   mp_init(&a); mp_init(&q);
00923   mp_read_radix(&a, mp3, 16);
00924 
00925   IFOK( mp_div_d(&a, md6, &q, &r) );
00926   mp_toradix(&q, g_intbuf, 16);
00927 
00928   if(strcmp(g_intbuf, q_mp3d6) != 0) {
00929     reason("error: computed q = %s, expected %s\n", g_intbuf, q_mp3d6);
00930     ++err;
00931   }
00932 
00933   sprintf(g_intbuf, ZS_DIGIT_FMT, r);
00934 
00935   if(strcmp(g_intbuf, r_mp3d6) != 0) {
00936     reason("error: computed r = %s, expected %s\n", g_intbuf, r_mp3d6);
00937     ++err;
00938   }
00939 
00940   mp_read_radix(&a, mp9, 16);
00941   IFOK( mp_div_d(&a, 16, &q, &r) );
00942   mp_toradix(&q, g_intbuf, 16);
00943 
00944   if(strcmp(g_intbuf, q_mp9c16) != 0) {
00945     reason("error: computed q = %s, expected %s\n", g_intbuf, q_mp9c16);
00946     ++err;
00947   }
00948 
00949   sprintf(g_intbuf, ZS_DIGIT_FMT, r);
00950 
00951   if(strcmp(g_intbuf, r_mp9c16) != 0) {
00952     reason("error: computed r = %s, expected %s\n", g_intbuf, r_mp9c16);
00953     ++err;
00954   }
00955 
00956   mp_clear(&a); mp_clear(&q);
00957   return err;
00958 }
00959 
00960 /*------------------------------------------------------------------------*/
00961 
00962 int test_div_2(void)
00963 {
00964   mp_int  a;
00965 
00966   mp_init(&a); mp_read_radix(&a, mp7, 16);
00967   IFOK( mp_div_2(&a, &a) );
00968   mp_toradix(&a, g_intbuf, 16);
00969 
00970   mp_clear(&a);
00971   if(strcmp(g_intbuf, q_mp7c2) != 0) {
00972     reason("error: computed %s, expected %s\n", g_intbuf, q_mp7c2);
00973     return 1;
00974   }
00975     
00976   return 0;
00977 }
00978 
00979 /*------------------------------------------------------------------------*/
00980 
00981 int test_div_2d(void)
00982 {
00983   mp_int  a, q, r;
00984 
00985   mp_init(&q); mp_init(&r);
00986   mp_init(&a); mp_read_radix(&a, mp13, 16);
00987 
00988   IFOK( mp_div_2d(&a, 64, &q, &r) );
00989   mp_clear(&a);
00990 
00991   mp_toradix(&q, g_intbuf, 16);
00992 
00993   if(strcmp(g_intbuf, q_mp13c) != 0) {
00994     reason("error: computed %s, expected %s\n", g_intbuf, q_mp13c);
00995     mp_clear(&q); mp_clear(&r);
00996     return 1;
00997   }
00998 
00999   mp_clear(&q);
01000 
01001   mp_toradix(&r, g_intbuf, 16);
01002   if(strcmp(g_intbuf, r_mp13c) != 0) {
01003     reason("error, computed %s, expected %s\n", g_intbuf, r_mp13c);
01004     mp_clear(&r);
01005     return 1;
01006   }
01007 
01008   mp_clear(&r);
01009   
01010   return 0;
01011 }
01012 
01013 /*------------------------------------------------------------------------*/
01014 
01015 int test_div(void)
01016 {
01017   mp_int  a, b, r;
01018   int     err = 0;
01019 
01020   mp_init(&a); mp_init(&b); mp_init(&r);
01021 
01022   mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp2, 16);
01023   IFOK( mp_div(&a, &b, &a, &r) );
01024   mp_toradix(&a, g_intbuf, 16);
01025 
01026   if(strcmp(g_intbuf, q_mp42) != 0) {
01027     reason("error: test 1 computed quot %s, expected %s\n", g_intbuf, q_mp42);
01028     ++err;
01029   }
01030 
01031   mp_toradix(&r, g_intbuf, 16);
01032 
01033   if(strcmp(g_intbuf, r_mp42) != 0) {
01034     reason("error: test 1 computed rem %s, expected %s\n", g_intbuf, r_mp42);
01035     ++err;
01036   }
01037 
01038   mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp5a, 16);
01039   IFOK( mp_div(&a, &b, &a, &r) );
01040   mp_toradix(&a, g_intbuf, 16);
01041 
01042   if(strcmp(g_intbuf, q_mp45a) != 0) {
01043     reason("error: test 2 computed quot %s, expected %s\n", g_intbuf, q_mp45a);
01044     ++err;
01045   }
01046 
01047   mp_toradix(&r, g_intbuf, 16);
01048 
01049   if(strcmp(g_intbuf, r_mp45a) != 0) {
01050     reason("error: test 2 computed rem %s, expected %s\n", g_intbuf, r_mp45a);
01051     ++err;
01052   }
01053 
01054   mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp4, 16);
01055   IFOK( mp_div(&a, &b, &a, &r) );
01056   mp_toradix(&a, g_intbuf, 16);
01057 
01058   if(strcmp(g_intbuf, q_mp1404) != 0) {
01059     reason("error: test 3 computed quot %s, expected %s\n", g_intbuf, q_mp1404);
01060     ++err;
01061   }
01062 
01063   mp_toradix(&r, g_intbuf, 16);
01064   
01065   if(strcmp(g_intbuf, r_mp1404) != 0) {
01066     reason("error: test 3 computed rem %s, expected %s\n", g_intbuf, r_mp1404);
01067     ++err;
01068   }
01069 
01070   mp_clear(&a); mp_clear(&b); mp_clear(&r);
01071 
01072   return err;
01073 }
01074 
01075 /*------------------------------------------------------------------------*/
01076 
01077 int test_expt_d(void)
01078 {
01079   mp_int   a;
01080 
01081   mp_init(&a); mp_read_radix(&a, mp5, 16);
01082   mp_expt_d(&a, md9, &a);
01083   mp_toradix(&a, g_intbuf, 16);
01084 
01085   mp_clear(&a);
01086   if(strcmp(g_intbuf, e_mp5d9) != 0) {
01087     reason("error: computed %s, expected %s\n", g_intbuf, e_mp5d9);
01088     return 1;
01089   }
01090 
01091   return 0;
01092 }
01093 
01094 /*------------------------------------------------------------------------*/
01095 
01096 int test_expt(void)
01097 {
01098   mp_int   a, b;
01099 
01100   mp_init(&a); mp_init(&b);
01101   mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp8, 16);
01102 
01103   mp_expt(&a, &b, &a);
01104   mp_toradix(&a, g_intbuf, 16);
01105   mp_clear(&a); mp_clear(&b);
01106 
01107   if(strcmp(g_intbuf, e_mp78) != 0) {
01108     reason("error: computed %s, expected %s\n", g_intbuf, e_mp78);
01109     return 1;
01110   }
01111 
01112   return 0;
01113 }
01114 
01115 /*------------------------------------------------------------------------*/
01116 
01117 int test_2expt(void)
01118 {
01119   mp_int   a;
01120 
01121   mp_init(&a);
01122   mp_2expt(&a, md3);
01123   mp_toradix(&a, g_intbuf, 16);
01124   mp_clear(&a);
01125 
01126   if(strcmp(g_intbuf, e_mpc2d3) != 0) {
01127     reason("error: computed %s, expected %s\n", g_intbuf, e_mpc2d3);
01128     return 1;
01129   }
01130 
01131   return 0;
01132 }
01133 
01134 /*------------------------------------------------------------------------*/
01135 
01136 int test_sqrt(void)
01137 {
01138   mp_int  a;
01139   int     res = 0;
01140 
01141   mp_init(&a); mp_read_radix(&a, mp9, 16);
01142   mp_sqrt(&a, &a);
01143   mp_toradix(&a, g_intbuf, 16);
01144 
01145   if(strcmp(g_intbuf, t_mp9) != 0) {
01146     reason("error: computed %s, expected %s\n", g_intbuf, t_mp9);
01147     res = 1; goto CLEANUP;
01148   }
01149 
01150   mp_read_radix(&a, mp15, 16);
01151   mp_sqrt(&a, &a);
01152   mp_toradix(&a, g_intbuf, 16);
01153 
01154   if(strcmp(g_intbuf, t_mp15) != 0) {
01155     reason("error: computed %s, expected %s\n", g_intbuf, t_mp15);
01156     res = 1;
01157   }
01158 
01159  CLEANUP:
01160   mp_clear(&a);
01161   return res;
01162 }
01163 
01164 /*------------------------------------------------------------------------*/
01165 
01166 int test_mod_d(void)
01167 {
01168   mp_int     a;
01169   mp_digit   r;
01170 
01171   mp_init(&a); mp_read_radix(&a, mp5, 16);
01172   IFOK( mp_mod_d(&a, md5, &r) );
01173   sprintf(g_intbuf, ZS_DIGIT_FMT, r);
01174   mp_clear(&a);
01175 
01176   if(strcmp(g_intbuf, r_mp5d5) != 0) {
01177     reason("error: computed %s, expected %s\n", g_intbuf, r_mp5d5);
01178     return 1;
01179   }
01180 
01181   return 0;
01182 }
01183 
01184 /*------------------------------------------------------------------------*/
01185 
01186 int test_mod(void)
01187 {
01188   mp_int  a, m;
01189 
01190   mp_init(&a); mp_init(&m);
01191   mp_read_radix(&a, mp4, 16); mp_read_radix(&m, mp7, 16);
01192   IFOK( mp_mod(&a, &m, &a) );
01193   mp_toradix(&a, g_intbuf, 16);
01194   mp_clear(&a); mp_clear(&m);
01195 
01196   if(strcmp(g_intbuf, r_mp47) != 0) {
01197     reason("error: computed %s, expected %s\n", g_intbuf, r_mp47);
01198     return 1;
01199   }
01200 
01201   return 0;
01202 }
01203 
01204 /*------------------------------------------------------------------------*/
01205 
01206 int test_addmod(void)
01207 {
01208   mp_int a, b, m;
01209 
01210   mp_init(&a); mp_init(&b); mp_init(&m);
01211   mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
01212   mp_read_radix(&m, mp5, 16);
01213 
01214   IFOK( mp_addmod(&a, &b, &m, &a) );
01215   mp_toradix(&a, g_intbuf, 16);
01216   mp_clear(&a); mp_clear(&b); mp_clear(&m);
01217 
01218   if(strcmp(g_intbuf, ms_mp345) != 0) {
01219     reason("error: computed %s, expected %s\n", g_intbuf, ms_mp345);
01220     return 1;
01221   }
01222 
01223   return 0;
01224 }
01225 
01226 /*------------------------------------------------------------------------*/
01227 
01228 int test_submod(void)
01229 {
01230   mp_int a, b, m;
01231 
01232   mp_init(&a); mp_init(&b); mp_init(&m);
01233   mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
01234   mp_read_radix(&m, mp5, 16);
01235 
01236   IFOK( mp_submod(&a, &b, &m, &a) );
01237   mp_toradix(&a, g_intbuf, 16);
01238   mp_clear(&a); mp_clear(&b); mp_clear(&m);
01239 
01240   if(strcmp(g_intbuf, md_mp345) != 0) {
01241     reason("error: computed %s, expected %s\n", g_intbuf, md_mp345);
01242     return 1;
01243   }
01244 
01245   return 0;
01246 }
01247 
01248 /*------------------------------------------------------------------------*/
01249 
01250 int test_mulmod(void)
01251 {
01252   mp_int a, b, m;
01253 
01254   mp_init(&a); mp_init(&b); mp_init(&m);
01255   mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
01256   mp_read_radix(&m, mp5, 16);
01257 
01258   IFOK( mp_mulmod(&a, &b, &m, &a) );
01259   mp_toradix(&a, g_intbuf, 16);
01260   mp_clear(&a); mp_clear(&b); mp_clear(&m);
01261 
01262   if(strcmp(g_intbuf, mp_mp345) != 0) {
01263     reason("error: computed %s, expected %s\n", g_intbuf, mp_mp345);
01264     return 1;
01265   }
01266 
01267   return 0;
01268 }
01269 
01270 /*------------------------------------------------------------------------*/
01271 
01272 int test_sqrmod(void)
01273 {
01274   mp_int a, m;
01275 
01276   mp_init(&a); mp_init(&m);
01277   mp_read_radix(&a, mp3, 16); mp_read_radix(&m, mp5, 16);
01278 
01279   IFOK( mp_sqrmod(&a, &m, &a) );
01280   mp_toradix(&a, g_intbuf, 16);
01281   mp_clear(&a); mp_clear(&m);
01282 
01283   if(strcmp(g_intbuf, mp_mp335) != 0) {
01284     reason("error: computed %s, expected %s\n", g_intbuf, mp_mp335);
01285     return 1;
01286   }
01287 
01288   return 0;
01289 }
01290 
01291 /*------------------------------------------------------------------------*/
01292 
01293 int test_exptmod(void)
01294 {
01295   mp_int  a, b, m;
01296   int     res = 0;
01297 
01298   mp_init(&a); mp_init(&b); mp_init(&m);
01299   mp_read_radix(&a, mp8, 16); mp_read_radix(&b, mp1, 16);
01300   mp_read_radix(&m, mp7, 16);
01301 
01302   IFOK( mp_exptmod(&a, &b, &m, &a) );
01303   mp_toradix(&a, g_intbuf, 16);
01304 
01305   if(strcmp(g_intbuf, me_mp817) != 0) {
01306     reason("case 1: error: computed %s, expected %s\n", g_intbuf, me_mp817);
01307     res = 1; goto CLEANUP;
01308   }
01309 
01310   mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp5, 16);
01311   mp_read_radix(&m, mp12, 16);
01312 
01313   IFOK( mp_exptmod(&a, &b, &m, &a) );
01314   mp_toradix(&a, g_intbuf, 16);
01315 
01316   if(strcmp(g_intbuf, me_mp1512) != 0) {
01317     reason("case 2: error: computed %s, expected %s\n", g_intbuf, me_mp1512);
01318     res = 1; goto CLEANUP;
01319   }
01320 
01321   mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp1, 16);
01322   mp_read_radix(&m, mp14, 16);
01323 
01324   IFOK( mp_exptmod(&a, &b, &m, &a) );
01325   mp_toradix(&a, g_intbuf, 16);
01326 
01327   if(strcmp(g_intbuf, me_mp5114) != 0) {
01328     reason("case 3: error: computed %s, expected %s\n", g_intbuf, me_mp5114);
01329     res = 1;
01330   }
01331 
01332   mp_read_radix(&a, mp16, 16); mp_read_radix(&b, mp17, 16);
01333   mp_read_radix(&m, mp18, 16);
01334 
01335   IFOK( mp_exptmod(&a, &b, &m, &a) );
01336   mp_toradix(&a, g_intbuf, 16);
01337 
01338   if(strcmp(g_intbuf, me_mp161718) != 0) {
01339     reason("case 4: error: computed %s, expected %s\n", g_intbuf, me_mp161718);
01340     res = 1;
01341   }
01342 
01343  CLEANUP:
01344   mp_clear(&a); mp_clear(&b); mp_clear(&m);
01345   return res;
01346 }
01347 
01348 /*------------------------------------------------------------------------*/
01349 
01350 int test_exptmod_d(void)
01351 {
01352   mp_int  a, m;
01353 
01354   mp_init(&a); mp_init(&m);
01355   mp_read_radix(&a, mp5, 16); mp_read_radix(&m, mp7, 16);
01356 
01357   IFOK( mp_exptmod_d(&a, md4, &m, &a) );
01358   mp_toradix(&a, g_intbuf, 16);
01359   mp_clear(&a); mp_clear(&m);
01360 
01361   if(strcmp(g_intbuf, me_mp5d47) != 0) {
01362     reason("error: computed %s, expected %s\n", g_intbuf, me_mp5d47);
01363     return 1;
01364   }
01365 
01366   return 0;
01367 }
01368 
01369 /*------------------------------------------------------------------------*/
01370 
01371 int test_invmod(void)
01372 {
01373   mp_int  a, m, c;
01374   mp_int  p1, p2, p3, p4, p5;
01375   mp_int  t1, t2, t3, t4;
01376   mp_err  res;
01377 
01378   /* 5 128-bit primes. */
01379   static const char ivp1[] = { "AAD8A5A2A2BEF644BAEE7DB0CA643719" };
01380   static const char ivp2[] = { "CB371AD2B79A90BCC88D0430663E40B9" };
01381   static const char ivp3[] = { "C6C818D4DF2618406CA09280C0400099" };
01382   static const char ivp4[] = { "CE949C04512E68918006B1F0D7E93F27" };
01383   static const char ivp5[] = { "F8EE999B6416645040687440E0B89F51" };
01384 
01385   mp_init(&a); mp_init(&m);
01386   mp_read_radix(&a, mp2, 16); mp_read_radix(&m, mp7, 16);
01387 
01388   IFOK( mp_invmod(&a, &m, &a) );
01389 
01390   mp_toradix(&a, g_intbuf, 16);
01391   mp_clear(&a); mp_clear(&m);
01392 
01393   if(strcmp(g_intbuf, i_mp27) != 0) {
01394     reason("error: invmod test 1 computed %s, expected %s\n", g_intbuf, i_mp27);
01395     return 1;
01396   }
01397 
01398   mp_init(&a); mp_init(&m);
01399   mp_read_radix(&a, mp20, 16); mp_read_radix(&m, mp19, 16);
01400 
01401   IFOK( mp_invmod(&a, &m, &a) );
01402 
01403   mp_toradix(&a, g_intbuf, 16);
01404   mp_clear(&a); mp_clear(&m);
01405 
01406   if(strcmp(g_intbuf, i_mp2019) != 0) {
01407     reason("error: invmod test 2 computed %s, expected %s\n", g_intbuf, i_mp2019);
01408     return 1;
01409   }
01410 
01411 /* Need the following test cases:
01412   Odd modulus
01413     - a is odd,      relatively prime to m
01414     - a is odd,  not relatively prime to m
01415     - a is even,     relatively prime to m
01416     - a is even, not relatively prime to m
01417   Even modulus
01418     - a is even  (should fail)
01419     - a is odd,  not relatively prime to m
01420     - a is odd,      relatively prime to m,
01421       m is not a power of 2
01422        - m has factor 2**k, k < 32
01423        - m has factor 2**k, k > 32
01424       m is a power of 2, 2**k
01425        - k < 32
01426        - k > 32
01427 */
01428 
01429   mp_init(&a);  mp_init(&m);  mp_init(&c);  
01430   mp_init(&p1); mp_init(&p2); mp_init(&p3); mp_init(&p4); mp_init(&p5); 
01431   mp_init(&t1); mp_init(&t2); mp_init(&t3); mp_init(&t4); 
01432 
01433   mp_read_radix(&p1, ivp1, 16);
01434   mp_read_radix(&p2, ivp2, 16);
01435   mp_read_radix(&p3, ivp3, 16);
01436   mp_read_radix(&p4, ivp4, 16);
01437   mp_read_radix(&p5, ivp5, 16);
01438 
01439   IFOK( mp_2expt(&t2, 68) );       /* t2 = 2**68 */
01440   IFOK( mp_2expt(&t3, 128) );      /* t3 = 2**128 */
01441   IFOK( mp_2expt(&t4, 31) );       /* t4 = 2**31 */
01442 
01443 /* test 3: Odd modulus - a is odd, relatively prime to m */
01444 
01445   IFOK( mp_mul(&p1, &p2, &a) );
01446   IFOK( mp_mul(&p3, &p4, &m) );
01447   IFOK( mp_invmod(&a, &m, &t1) );
01448   IFOK( mp_invmod_xgcd(&a, &m, &c) );
01449 
01450   if (mp_cmp(&t1, &c) != 0) {
01451     mp_toradix(&t1, g_intbuf, 16);
01452     mp_toradix(&c,  a_intbuf, 16);
01453     reason("error: invmod test 3 computed %s, expected %s\n", 
01454            g_intbuf, a_intbuf);
01455     return 1;
01456   }
01457   mp_clear(&a);  mp_clear(&t1); mp_clear(&c);  
01458   mp_init(&a);   mp_init(&t1);  mp_init(&c);   
01459 
01460 /* test 4: Odd modulus - a is odd, NOT relatively prime to m */
01461 
01462   IFOK( mp_mul(&p1, &p3, &a) );
01463   /* reuse same m as before */
01464 
01465   res = mp_invmod_xgcd(&a, &m, &c);
01466   if (res != MP_UNDEF) 
01467     goto CLEANUP4;
01468 
01469   res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
01470   if (res != MP_UNDEF) {
01471 CLEANUP4:
01472     reason("error: invmod test 4 succeeded, should have failed.\n");
01473     return 1;
01474   }
01475   mp_clear(&a);  mp_clear(&t1); mp_clear(&c);  
01476   mp_init(&a);   mp_init(&t1);  mp_init(&c);   
01477 
01478 /* test 5: Odd modulus - a is even, relatively prime to m */
01479 
01480   IFOK( mp_mul(&p1, &t2, &a) );
01481   /* reuse m */
01482   IFOK( mp_invmod(&a, &m, &t1) );
01483   IFOK( mp_invmod_xgcd(&a, &m, &c) );
01484 
01485   if (mp_cmp(&t1, &c) != 0) {
01486     mp_toradix(&t1, g_intbuf, 16);
01487     mp_toradix(&c,  a_intbuf, 16);
01488     reason("error: invmod test 5 computed %s, expected %s\n", 
01489            g_intbuf, a_intbuf);
01490     return 1;
01491   }
01492   mp_clear(&a);  mp_clear(&t1); mp_clear(&c);  
01493   mp_init(&a);   mp_init(&t1);  mp_init(&c);   
01494 
01495 /* test 6: Odd modulus - a is odd, NOT relatively prime to m */
01496 
01497   /* reuse t2 */
01498   IFOK( mp_mul(&t2, &p3, &a) );
01499   /* reuse same m as before */
01500 
01501   res = mp_invmod_xgcd(&a, &m, &c);
01502   if (res != MP_UNDEF) 
01503     goto CLEANUP6;
01504 
01505   res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
01506   if (res != MP_UNDEF) {
01507 CLEANUP6:
01508     reason("error: invmod test 6 succeeded, should have failed.\n");
01509     return 1;
01510   }
01511   mp_clear(&a);  mp_clear(&m); mp_clear(&c);  mp_clear(&t1); 
01512   mp_init(&a);   mp_init(&m);  mp_init(&c);   mp_init(&t1); 
01513 
01514 /* test 7: Even modulus, even a, should fail */
01515 
01516   IFOK( mp_mul(&p3, &t3, &m) ); /* even m */
01517   /* reuse t2 */
01518   IFOK( mp_mul(&p1, &t2, &a) ); /* even a */
01519 
01520   res = mp_invmod_xgcd(&a, &m, &c);
01521   if (res != MP_UNDEF) 
01522     goto CLEANUP7;
01523 
01524   res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
01525   if (res != MP_UNDEF) {
01526 CLEANUP7:
01527     reason("error: invmod test 7 succeeded, should have failed.\n");
01528     return 1;
01529   }
01530   mp_clear(&a);  mp_clear(&c);  mp_clear(&t1); 
01531   mp_init(&a);   mp_init(&c);   mp_init(&t1); 
01532 
01533 /* test 8: Even modulus    - a is odd,  not relatively prime to m */
01534 
01535   /* reuse m */
01536   IFOK( mp_mul(&p3, &p1, &a) ); /* even a */
01537 
01538   res = mp_invmod_xgcd(&a, &m, &c);
01539   if (res != MP_UNDEF) 
01540     goto CLEANUP8;
01541 
01542   res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
01543   if (res != MP_UNDEF) {
01544 CLEANUP8:
01545     reason("error: invmod test 8 succeeded, should have failed.\n");
01546     return 1;
01547   }
01548   mp_clear(&a);  mp_clear(&m); mp_clear(&c);  mp_clear(&t1); 
01549   mp_init(&a);   mp_init(&m);  mp_init(&c);   mp_init(&t1); 
01550 
01551 /* test 9: Even modulus    - m has factor 2**k, k < 32
01552  *                        - a is odd, relatively prime to m,
01553  */
01554   IFOK( mp_mul(&p3, &t4, &m) ); /* even m */
01555   IFOK( mp_mul(&p1, &p2, &a) );
01556   IFOK( mp_invmod(&a, &m, &t1) );
01557   IFOK( mp_invmod_xgcd(&a, &m, &c) );
01558 
01559   if (mp_cmp(&t1, &c) != 0) {
01560     mp_toradix(&t1, g_intbuf, 16);
01561     mp_toradix(&c,  a_intbuf, 16);
01562     reason("error: invmod test 9 computed %s, expected %s\n", 
01563            g_intbuf, a_intbuf);
01564     return 1;
01565   }
01566   mp_clear(&m);  mp_clear(&t1); mp_clear(&c);  
01567   mp_init(&m);   mp_init(&t1);  mp_init(&c);   
01568 
01569 /* test 10: Even modulus    - m has factor 2**k, k > 32
01570  *                         - a is odd, relatively prime to m,
01571  */
01572   IFOK( mp_mul(&p3, &t3, &m) ); /* even m */
01573   /* reuse a */
01574   IFOK( mp_invmod(&a, &m, &t1) );
01575   IFOK( mp_invmod_xgcd(&a, &m, &c) );
01576 
01577   if (mp_cmp(&t1, &c) != 0) {
01578     mp_toradix(&t1, g_intbuf, 16);
01579     mp_toradix(&c,  a_intbuf, 16);
01580     reason("error: invmod test 10 computed %s, expected %s\n", 
01581            g_intbuf, a_intbuf);
01582     return 1;
01583   }
01584   mp_clear(&t1); mp_clear(&c);  
01585   mp_init(&t1);  mp_init(&c);   
01586 
01587 /* test 11: Even modulus    - m is a power of 2, 2**k | k < 32
01588  *                          - a is odd, relatively prime to m,
01589  */
01590   IFOK( mp_invmod(&a, &t4, &t1) );
01591   IFOK( mp_invmod_xgcd(&a, &t4, &c) );
01592 
01593   if (mp_cmp(&t1, &c) != 0) {
01594     mp_toradix(&t1, g_intbuf, 16);
01595     mp_toradix(&c,  a_intbuf, 16);
01596     reason("error: invmod test 11 computed %s, expected %s\n", 
01597            g_intbuf, a_intbuf);
01598     return 1;
01599   }
01600   mp_clear(&t1); mp_clear(&c);  
01601   mp_init(&t1);  mp_init(&c);   
01602 
01603 /* test 12: Even modulus    - m is a power of 2, 2**k | k > 32
01604  *                          - a is odd, relatively prime to m,
01605  */
01606   IFOK( mp_invmod(&a, &t3, &t1) );
01607   IFOK( mp_invmod_xgcd(&a, &t3, &c) );
01608 
01609   if (mp_cmp(&t1, &c) != 0) {
01610     mp_toradix(&t1, g_intbuf, 16);
01611     mp_toradix(&c,  a_intbuf, 16);
01612     reason("error: invmod test 12 computed %s, expected %s\n", 
01613            g_intbuf, a_intbuf);
01614     return 1;
01615   }
01616 
01617   mp_clear(&a);  mp_clear(&m);  mp_clear(&c);  
01618   mp_clear(&t1); mp_clear(&t2); mp_clear(&t3); mp_clear(&t4); 
01619   mp_clear(&p1); mp_clear(&p2); mp_clear(&p3); mp_clear(&p4); mp_clear(&p5); 
01620 
01621   return 0;
01622 }
01623 
01624 /*------------------------------------------------------------------------*/
01625 
01626 int test_cmp_d(void)
01627 {
01628   mp_int  a;
01629 
01630   mp_init(&a); mp_read_radix(&a, mp8, 16);
01631 
01632   if(mp_cmp_d(&a, md8) >= 0) {
01633     reason("error: %s >= " DIGIT_FMT "\n", mp8, md8);
01634     mp_clear(&a);
01635     return 1;
01636   }
01637 
01638   mp_read_radix(&a, mp5, 16);
01639 
01640   if(mp_cmp_d(&a, md8) <= 0) {
01641     reason("error: %s <= " DIGIT_FMT "\n", mp5, md8);
01642     mp_clear(&a);
01643     return 1;
01644   }
01645 
01646   mp_read_radix(&a, mp6, 16);
01647 
01648   if(mp_cmp_d(&a, md1) != 0) {
01649     reason("error: %s != " DIGIT_FMT "\n", mp6, md1);
01650     mp_clear(&a);
01651     return 1;
01652   }
01653 
01654   mp_clear(&a);
01655   return 0;
01656 
01657 }
01658 
01659 /*------------------------------------------------------------------------*/
01660 
01661 int test_cmp_z(void)
01662 {
01663   mp_int  a;
01664 
01665   mp_init(&a); mp_read_radix(&a, mp6, 16);
01666 
01667   if(mp_cmp_z(&a) != 0) {
01668     reason("error: someone thinks a zero value is non-zero\n");
01669     mp_clear(&a);
01670     return 1;
01671   }
01672 
01673   mp_read_radix(&a, mp1, 16);
01674   
01675   if(mp_cmp_z(&a) <= 0) {
01676     reason("error: someone thinks a positive value is non-positive\n");
01677     mp_clear(&a);
01678     return 1;
01679   }
01680 
01681   mp_read_radix(&a, mp4, 16);
01682 
01683   if(mp_cmp_z(&a) >= 0) {
01684     reason("error: someone thinks a negative value is non-negative\n");
01685     mp_clear(&a);
01686     return 1;
01687   }
01688 
01689   mp_clear(&a);
01690   return 0;
01691 }
01692 
01693 /*------------------------------------------------------------------------*/
01694 
01695 int test_cmp(void)
01696 {
01697   mp_int  a, b;
01698 
01699   mp_init(&a); mp_init(&b);
01700   mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
01701 
01702   if(mp_cmp(&a, &b) <= 0) {
01703     reason("error: %s <= %s\n", mp3, mp4);
01704     mp_clear(&a); mp_clear(&b);
01705     return 1;
01706   }
01707 
01708   mp_read_radix(&b, mp3, 16);
01709   if(mp_cmp(&a, &b) != 0) {
01710     reason("error: %s != %s\n", mp3, mp3);
01711     mp_clear(&a); mp_clear(&b);
01712     return 1;
01713   }
01714 
01715   mp_read_radix(&a, mp5, 16);
01716   if(mp_cmp(&a, &b) >= 0) {
01717     reason("error: %s >= %s\n", mp5, mp3);
01718     mp_clear(&a); mp_clear(&b);
01719     return 1;
01720   }
01721 
01722   mp_read_radix(&a, mp5a, 16);
01723   if(mp_cmp_int(&a, 1000000) >= 0 ||
01724      (mp_cmp_int(&a, -5000000) <= 0) ||
01725      (mp_cmp_int(&a, -4938110) != 0)) {
01726     reason("error: long integer comparison failed (%s)", mp5a);
01727     mp_clear(&a); mp_clear(&b);
01728     return 1;
01729   }
01730 
01731   mp_clear(&a); mp_clear(&b);
01732   return 0;
01733 }
01734 
01735 /*------------------------------------------------------------------------*/
01736 
01737 int test_cmp_mag(void)
01738 {
01739   mp_int  a, b;
01740 
01741   mp_init(&a); mp_init(&b);
01742   mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp4, 16);
01743 
01744   if(mp_cmp_mag(&a, &b) >= 0) {
01745     reason("error: %s >= %s\n", mp5, mp4);
01746     mp_clear(&a); mp_clear(&b);
01747     return 1;
01748   }
01749 
01750   mp_read_radix(&b, mp5, 16);
01751   if(mp_cmp_mag(&a, &b) != 0) {
01752     reason("error: %s != %s\n", mp5, mp5);
01753     mp_clear(&a); mp_clear(&b);
01754     return 1;
01755   }
01756 
01757   mp_read_radix(&a, mp1, 16);
01758   if(mp_cmp_mag(&b, &a) >= 0) {
01759     reason("error: %s >= %s\n", mp5, mp1);
01760     mp_clear(&a); mp_clear(&b);
01761     return 1;
01762   }
01763 
01764   mp_clear(&a); mp_clear(&b);
01765   return 0;
01766 
01767 }
01768 
01769 /*------------------------------------------------------------------------*/
01770 
01771 int test_parity(void)
01772 {
01773   mp_int  a;
01774 
01775   mp_init(&a); mp_read_radix(&a, mp1, 16);
01776 
01777   if(!mp_isodd(&a)) {
01778     reason("error: expected operand to be odd, but it isn't\n");
01779     mp_clear(&a);
01780     return 1;
01781   }
01782 
01783   mp_read_radix(&a, mp6, 16);
01784   
01785   if(!mp_iseven(&a)) {
01786     reason("error: expected operand to be even, but it isn't\n");
01787     mp_clear(&a);
01788     return 1;
01789   }
01790 
01791   mp_clear(&a);
01792   return 0;
01793 }
01794 
01795 /*------------------------------------------------------------------------*/
01796 
01797 int test_gcd(void)
01798 {
01799   mp_int  a, b;
01800   int     out = 0;
01801 
01802   mp_init(&a); mp_init(&b);
01803   mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp1, 16);
01804 
01805   mp_gcd(&a, &b, &a);
01806   mp_toradix(&a, g_intbuf, 16);
01807 
01808   if(strcmp(g_intbuf, g_mp71) != 0) {
01809     reason("error: computed %s, expected %s\n", g_intbuf, g_mp71);
01810     out = 1;
01811   }
01812 
01813   mp_clear(&a); mp_clear(&b);
01814   return out;
01815 
01816 }
01817 
01818 /*------------------------------------------------------------------------*/
01819 
01820 int test_lcm(void)
01821 {
01822   mp_int  a, b;
01823   int     out = 0;
01824 
01825   mp_init(&a); mp_init(&b);
01826   mp_read_radix(&a, mp10, 16); mp_read_radix(&b, mp11, 16);
01827 
01828   mp_lcm(&a, &b, &a);
01829   mp_toradix(&a, g_intbuf, 16);
01830 
01831   if(strcmp(g_intbuf, l_mp1011) != 0) {
01832     reason("error: computed %s, expected%s\n", g_intbuf, l_mp1011);
01833     out = 1;
01834   }
01835 
01836   mp_clear(&a); mp_clear(&b);
01837 
01838   return out;
01839 
01840 }
01841 
01842 /*------------------------------------------------------------------------*/
01843 
01844 int test_convert(void)
01845 {
01846   int    ix;
01847   mp_int a;
01848 
01849   mp_init(&a); mp_read_radix(&a, mp9, 16);
01850 
01851   for(ix = LOW_RADIX; ix <= HIGH_RADIX; ix++) {
01852     mp_toradix(&a, g_intbuf, ix);
01853 
01854     if(strcmp(g_intbuf, v_mp9[ix - LOW_RADIX]) != 0) {
01855       reason("error: radix %d, computed %s, expected %s\n",
01856             ix, g_intbuf, v_mp9[ix - LOW_RADIX]);
01857       mp_clear(&a);
01858       return 1;
01859     }
01860   }
01861 
01862   mp_clear(&a);
01863   return 0;
01864 }
01865 
01866 /*------------------------------------------------------------------------*/
01867 
01868 int test_raw(void)
01869 {
01870   int    len, out = 0;
01871   mp_int a;
01872   char   *buf;
01873 
01874   mp_init(&a); mp_read_radix(&a, mp4, 16);
01875 
01876   len = mp_raw_size(&a);
01877   if(len != sizeof(b_mp4)) {
01878     reason("error: test_raw: expected length %d, computed %d\n", sizeof(b_mp4),
01879           len);
01880     mp_clear(&a);
01881     return 1;
01882   }
01883 
01884   buf = calloc(len, sizeof(char));
01885   mp_toraw(&a, buf);
01886 
01887   if(memcmp(buf, b_mp4, sizeof(b_mp4)) != 0) {
01888     reason("error: test_raw: binary output does not match test vector\n");
01889     out = 1;
01890   }
01891 
01892   free(buf);
01893   mp_clear(&a);
01894 
01895   return out;
01896 
01897 }
01898 
01899 /*------------------------------------------------------------------------*/
01900 
01901 int test_pprime(void)
01902 {
01903   mp_int   p;
01904   int      err = 0;
01905   mp_err   res;
01906 
01907   mp_init(&p);
01908   mp_read_radix(&p, mp7, 16);
01909 
01910   if(mpp_pprime(&p, 5) != MP_YES) {
01911     reason("error: %s failed Rabin-Miller test, but is prime\n", mp7);
01912     err = 1;
01913   }
01914 
01915   IFOK( mp_set_int(&p, 9) );
01916   res = mpp_pprime(&p, 50);
01917   if (res == MP_YES) {
01918     reason("error: 9 is composite but passed Rabin-Miller test\n");
01919     err = 1;
01920   } else if (res != MP_NO) {
01921     reason("test mpp_pprime(9, 50) failed: error %d\n", res); 
01922     err = 1;
01923   }
01924 
01925   IFOK( mp_set_int(&p, 15) );
01926   res = mpp_pprime(&p, 50);
01927   if (res == MP_YES) {
01928     reason("error: 15 is composite but passed Rabin-Miller test\n");
01929     err = 1;
01930   } else if (res != MP_NO) {
01931     reason("test mpp_pprime(15, 50) failed: error %d\n", res); 
01932     err = 1;
01933   }
01934 
01935   mp_clear(&p);
01936 
01937   return err;
01938 
01939 }
01940 
01941 /*------------------------------------------------------------------------*/
01942 
01943 int test_fermat(void)
01944 {
01945   mp_int p;
01946   mp_err res;
01947   int    err = 0;
01948 
01949   mp_init(&p);
01950   mp_read_radix(&p, mp7, 16);
01951   
01952   if((res = mpp_fermat(&p, 2)) != MP_YES) {
01953     reason("error: %s failed Fermat test on 2: %s\n", mp7, 
01954           mp_strerror(res));
01955     ++err;
01956   }
01957 
01958   if((res = mpp_fermat(&p, 3)) != MP_YES) {
01959     reason("error: %s failed Fermat test on 3: %s\n", mp7, 
01960           mp_strerror(res));
01961     ++err;
01962   }
01963 
01964   mp_clear(&p);
01965 
01966   return err;
01967 
01968 }
01969 
01970 /*------------------------------------------------------------------------*/
01971 /* Like fprintf(), but only if we are behaving in a verbose manner        */
01972 
01973 void reason(char *fmt, ...)
01974 {
01975   va_list    ap;
01976 
01977   if(!g_verbose)
01978     return;
01979 
01980   va_start(ap, fmt);
01981   vfprintf(stderr, fmt, ap);
01982   va_end(ap);
01983 }
01984 
01985 /*------------------------------------------------------------------------*/
01986 /* HERE THERE BE DRAGONS                                                  */