tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mpi-test.c (57522B)


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