From: Mark Wooding Date: Sat, 29 Apr 2017 12:55:40 +0000 (+0100) Subject: Hack on the newly imported X25519 and X448 code. X-Git-Url: https://git.distorted.org.uk/~mdw/secnet/commitdiff_plain/0bcb8184cfce875a4dde57621139dd44c433f3a5 Hack on the newly imported X25519 and X448 code. I've tried to touch the code as little as possible to integrate it with the rest of Secnet. I've limited myself to: * adding Secnet notices and GPL-mandated notices; * removing definitions which obviously won't work; * removing code which is unnecessary given Secnet's less ambitious portability objectives; and * providing substitutes for some of the support types and macros assumed by the original implementation, in particular a fake version of . I've also written a new test driver for the field and curve arithmetic, and reformatted the test vectors, though the data remains the same. The code builds and passes the tests. Signed-off-by: Mark Wooding --- diff --git a/Makefile.in b/Makefile.in index 6bc02ef..d31d44e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -62,13 +62,14 @@ OBJECTS:=secnet.o util.o conffile.yy.o conffile.tab.o conffile.o modules.o \ resolver.o random.o udp.o site.o transform-cbcmac.o transform-eax.o \ comm-common.o polypath.o \ netlink.o rsa.o dh.o serpent.o serpentbe.o \ + f25519.o x25519.o fgoldi.o x448.o \ md5.o sha512.o tun.o slip.o sha1.o ipaddr.o log.o \ process.o @LIBOBJS@ \ hackypar.o # version.o is handled specially below and in the link rule for secnet. TEST_OBJECTS:=eax-aes-test.o eax-serpent-test.o eax-serpentbe-test.o \ - eax-test.o aes.o + eax-test.o aes.o x25519-test.o x448-test.o ifeq (version.o,$(MAKECMDGOALS)) OBJECTS:=version.o @@ -145,7 +146,7 @@ endif check: eax-aes-test.confirm eax-serpent-test.confirm \ eax-serpentbe-test.confirm check-ipaddrset \ - msgcode-test.confirm + msgcode-test.confirm x25519-test.confirm x448-test.confirm version.c: Makefile echo "#include \"secnet.h\"" >$@.new @@ -172,6 +173,24 @@ msgcode-test.confirm: msgcode-test ./msgcode-test touch $@ +XDH_FUNCS = x25519 x448 +x25519_FIELD = f25519 +x448_FIELD = fgoldi + +$(addsuffix -test, $(XDH_FUNCS)): %-test: %-test.o %.o + $(CC) $(LDFLAGS) $(ALL_CFLAGS) -o $@ $^ +x25519-test: f25519.o +x448-test: fgoldi.o + +$(addsuffix -test.o, $(XDH_FUNCS)): %-test.o: xdh-test.c + $(CC) $(CPPFLAGS) $(ALL_CFLAGS) -c \ + -DXDH=$* -DFIELD=$($*_FIELD) \ + $< -o $@ + +$(addsuffix -test.confirm, $(XDH_FUNCS)): %-test.confirm: %-test %-tests.in + ./$*-test <$(srcdir)/$*-tests.in + touch $@ + check-ipaddrset: ipaddrset-test.py ipaddrset.py ipaddrset-test.expected $(srcdir)/ipaddrset-test.py >ipaddrset-test.new diff -u $(srcdir)/ipaddrset-test.expected ipaddrset-test.new @@ -207,6 +226,8 @@ clean: $(RM) -f *.o *.yy.[ch] *.tab.[ch] $(TARGETS) core version.c $(RM) -f *.d *.pyc *~ eax-*-test.confirm eax-*-test $(RM) -f msgcode-test.confirm msgcode-test + $(RM) -f $(addsuffix -test, $(XDH_FUNCS)) + $(RM) -f $(addsuffix -test.confirm, $(XDH_FUNCS)) realclean: clean $(RM) -f *~ Makefile config.h *.d \ diff --git a/f25519-tests.in b/f25519-tests.in deleted file mode 100644 index 96d4ac7..0000000 --- a/f25519-tests.in +++ /dev/null @@ -1,1235 +0,0 @@ -### Test cases for arithmetic mod 2^255 - 19. - -add { - ## Some load and store tests. - 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 - 0000000000000000000000000000000000000000000000000000000000000000 - 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20; - ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f - 0000000000000000000000000000000000000000000000000000000000000000 - ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f; - edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f - 00000000000000000000000000000000000000000000000000000000000000 - 00; - - ## Random tests. - bb8cd45b6185ee8ca34c4d7560425fd5c2fc22871113c6427198e8f9439a8523 - 98f16cc5e44b7228b7f3b6ed91930d68bba5071157d19259c48034d2817e30d5 - 667e412146d160b55a400463f2d56c3d7ea22a9868e4589c35191dccc518b678; - 8ef938a7b07a668c234c2c5bb65115b8e2e22a3703cda51c70e7a56a075d4f34 - 1f3cd4bf4f768058c4de1aa5aeb90e227338e308c7a0a199050ca1c38d1e034c - c0350d6700f1e6e4e72a4700650b24da551b0e40ca6d47b675f3462e957b5200; - 8b2c4678fd4f8b7254eea925e4da8d472db7f97d349d1b2134ced884b747ea7d - 58dca7954f843b7e4dc56b048903e7728df66ef6824f29932b2f568c995ddf2c - f608ee0d4dd4c6f0a1b3152a6dde74babaad6874b7ec44b45ffd2e1151a5c92a; - 9cd64f0cf439bccd224f7a789396b9f888998d1ba9759c93a5d6a27f45db0e67 - 12f724a127052612081e27e3915db9a540de9b64c566edc313914ad94424464e - c1cd74ad1b3fe2df2a6da15b25f4729ec97729806edc8957b967ed588aff5435; - 82e59fa9703b2557303665fe24e3d46259da974d78155f05c6b8891f92fc808d - 98a073ec62baf1354b681a3c78d62df1698ed5077dbe2bd68ba4a6e0233e3447 - 2d861396d3f5168d7b9e7f3a9db90254c3686d55f5d38adb515d3000b63ab554; - 686ceca221d0f4c6d98287e97c506085064e7b172672b88ee555dd0308bfd309 - 60adc3675be5e6c2921a74b5b8b24b0a26341a19567dae713a720786bc72df16 - c819b00a7db5db896c9dfb9e3503ac8f2c8295307cef660020c8e489c431b320; - a50a5b82d2451ed9a5844585712202a6dc0e0230501d57b8c00f4bd4771aed9e - 98d71b8b140aea02ad47d9b19e47d2a03257adc1d5c47611adc667652b78c87c - 63e2760de74f08dc52cc1e37106ad4460f66aff125e2cdc96dd6b239a392b51b; - 1637e3eb4c5d173b8cba29bdb13b930f48ae0599e354819f8ae0cf70f0f7b61b - ffeef1767df70de7a4a75864c03935d7934c6cf5228b9c3000813ed0e55447e2 - 2826d562ca542522316282217275c8e6dbfa718e06e01dd08a610e41d64cfe7d; - 9e8bf571c45bc5f37c9126e70498698978903b94d9c6712baef91894ab924fda - 480f68f8ee644bfb64e3fa514eaf16aea6368da6813802c4c3e6ce8f6540dfa3 - 0c9b5d6ab3c010efe1742139534780371fc7c83a5bff73ef71e0e72311d32e7e; - df9bdbd478bd1ec1ff078cdc76f2a5fcdc52f0198ba412e0b5a10e664b175dad - 080bc47bd2fb2ba3be6a07a02162f76020479f2cc6469c6766df23acf9517896 - 0da79f504bb94a64be72937c98549d5dfd998f4651ebae471c8132124569d543; - b6dd223f5d8a3dc5dd6f7a0679173ff656303017a17f17f4086fd4ecd3a23020 - 560d827aad23c26fddbfd16c3514a9b518a4586d6e3c5739860743662b14f4b4 - 1feba4b90aaeff34bb2f4c73ae2be8ab6fd488840fbc6e2d8f761753ffb62455; - 1d59691a670c40143ca7f7e693389ab64a911b17a2fe4368fba9097b40864162 - cb42d3ba12a8b90ef1622ea09241d3157c515043040914356d6d99b95089fa07 - e89b3cd579b4f9222d0a2687267a6dccc6e26b5aa607589d6817a334910f3c6a; - 82b48877e9c8c18edb52db3e1417d894e572a8edd84335d93c642158f2a926e0 - 93c6a39c1ef97f318c3b13bf8e77bea653b2eb130bdf43b00a0e0e40a362e819 - 287b2c1408c241c0678eeefda28e963b39259401e422798947722f98950c0f7a; - a6137481c5b9b8bcb3c87f3868c5f812da71aeb21c5ce18a508773120ea4f659 - 812eacdc5a8eb2e8fde0c23a19c2e33466d754ab3109d28ff48fb41dab8066e2 - 4d42205e20486ba5b1a942738187dc474049035e4e65b31a45172830b9245d3c; - 598fb4096a7054e317e66bc9633d56dfcaeabc31a7bbc9da13074b242edeca09 - 929b1bddd55c99b06b99a3ffbac5adc1d28823cb8354adcfea60b7a87fe32039 - eb2ad0e63fcded93837f0fc91e0304a19d73e0fc2a1077aafe6702cdadc1eb42; - c42183d915267e655409326b1b77a042d8918feefd75dd3d18551f398ef426e7 - e3729a6110686ffa57d1c69284a60fb36173148a89b1810d04614f03c8f90084 - cd941d3b268eed5facdaf8fd9f1db0f53905a47887275f4b1cb66e3c56ee276b; - 67b8b7ea7e7f9f52d686f906589c919b293bff6d3127e7ac581dc1630af7bcc1 - 99d18d2190ef0da148b843c014fea3efea59f9adbb28fa38407191fcc24e029c - 268a450c0f6fadf31e3f3dc76c9a358b1495f81bed4fe1e5988e5260cd45bf5d; - bc3422b79e01234fefd3637a19bfb2dd0a83bf2071b27bf5389918a50e579294 - b665dffe064aceffaabba94697cf27054d016427ebaf68858c5250cc5c1b770f - 859a01b6a54bf14e9a8f0dc1b08edae2578423485c62e47ac5eb68716b720924; - d419cbfd5514d9cffa1765b9f273fd7492000a3d110586ed0b8137760a2e808e - bcb52f423917c074464b2078d1c3f883fb793b02411b8b13c08266d17658a499 - b6cffa3f8f2b994441638531c437f6f88d7a453f52201101cc039e4781862428; - 2f7eb8051d16a52b797e2618881bd0857eb205bf97e581e09680f86308f7e082 - 9ceda63b29c3bfedbb6f3f0be2f3f2bd285bb9d21620c3edde69629b00b1c3cd - f16b5f4146d9641935ee65236a0fc343a70dbf91ae0545ce75ea5aff08a8a450; -} - -sub { - dfb53b4ff67c742728c564d50ae20e3e3617804478a95e511d37ff4dcf04fa3f - 9bc2006bb07dcf7bf0b461e7599e3c3cbfcdf6b6f41fc1db2219767ce9c43bcd - 1ef33ae445ffa4ab371003eeb043d2017749898d83899d75fa1d89d1e53fbe72; - 432ec65076c94af41e054a43f64fe4eecb23f50a303fd38e0172e4e846e67394 - 3642c84c5f5fcd5a0f3f2e37114beb8e7b614c39d354f1b32fe7e9cc918da5c8 - faebfd03176a7d990fc61b0ce504f95f50c2a8d15ceae1dad18afa1bb558ce4b; - 1725a986c03d9d53346ab2064545ba90ab38191e19ded9ecc2f44d422ab04150 - 11a20caef0239e4ffb5ab2f7d3576633a0d4a08c78a02f35765fafff5398c48b - f3829cd8cf19ff03390f000f71ed535d0b647891a03daab74c959e42d6177d44; - ec5d5cdfc8183f9aa3d47634d16427c3a399e2166bfa4ddfecbc911e5f33ceba - 649f8e29c483765c4232c369fd0e50a0026eac306eb4bd6924e7b4d7d3f73e26 - 9bbecdb50495c83d61a2b3cad355d722a12b36e6fc459075c8d5dc468b3b8f14; - cc9927c331884612d8fab9a2262ad0db38f55e0cc587e45b972ea8b1f504450d - 30c5c9f8d5491a350051bbc6bb78e568d98061b43cb1797cd3d7454e8a7aa1bf - 76d45dca5b3e2cddd7a9fedb6ab1ea725f74fd5788d66adfc35662636b8aa34d; - 662bc96da214e50f13e07a15b8e0b78f512c744a66975b2170ba28079ca7d03b - 84b072295dca0abef806ec5c1e594179dc5e9eb172c178af1902a42ea7a3728e - cf7a5644454ada511ad98eb89987761675cdd598f3d5e27156b884d8f4035e2d; - ed6f947157492eccc5fb1d0542593d58a47e2d87355dc0378e65376163fcf457 - cb27e06c5ebf42a61caadd4fb222799772aaef31487bf61ac84c15f58af265d3 - 0f48b404f989eb25a95140b58f36c4c031d43d55ede1c91cc618226cd8098f04; - 33c2fc57d8ffc29e6d670cfc4e25b695320055cf443ade53f49f6c23c452f644 - 3814860ccbb4391894c107961170d3af1594988a7972b97d0fb2169631b216fa - d5ad764b0d4b8986d9a504663db5e2e51c6cbc44cbc724d6e4ed558d92a0df4a; - d0fd0d5e73be5c534aa37645aecc49b202fadb30733f16d0de719a70bec2c751 - 910c7b4d317397cff70c91e5bf8ec42ba1700b0866adbbfe99b7fbb2c46c7093 - 2cf19210424bc5835296e55fee3d85866189d0280d925ad144ba9ebdf955573e; - e0f8130d6b0125e824b254ed57edc59455a8a4704a3f14a4ae8dbf8721595468 - 4e4f69af6f85742068ad70225e8850c85aef3d3fb3ba3b52c2be979db4eb979d - 7fa9aa5dfb7bb0c7bc04e4caf96475ccfab866319784d851ecce27ea6c6dbc4a; - 204d5f69ebab4597d2aa9295ecc2959480a2ab0b225674cc8a147cf7c1e59717 - 3abdd29c94819ec7507673bd5cc4fb267fcb17c1509abd5e462b46b012f815a8 - c08f8ccc562aa7cf81341fd88ffe996d01d7934ad1bbb66d44e93547afed816f; - e2d75c74060aee615b6cfc815c8618f826b07c4987e10f20d27ff74eab3ac7d0 - 7a06b32d284b5faedb91dac8e94cb7f76c678bad81ed78ac4e75eb9edd8d11e9 - 55d1a946debe8eb37fda21b972396100ba48f19b05f49673830a0cb0cdacb567; - 8d50b0573b0bb945bf128e1a9a37c151e991581673cf6295db5a6223d428ac9d - 47ca477794fdf378f3486355b5348960ee957470b8c74d62199ac48b4478c4ca - 338668e0a60dc5cccbc92ac5e40238f1fafbe3a5ba071533c2c09d978fb0e752; - b66b49190a99456aaac5c33beaec423a3fa79a84df0f00122aed29151185ceef - 13c06f7941743bfa261845d99772fd0d5f1a8258aeda53b161505ed8bdca1bc8 - a3abd99fc8240a7083ad7e62527a452ce08c182c3135ac60c89ccb3c53bab227; - 44ac89bb8d4de1a8756b00401236ea4e316a2fe637f6e5f052576da70c29c4ea - 05dd39ac32768d899b80ed10279aa10d6316d60ab2d061e877dc5f21ce8e1140 - 52cf4f0f5bd7531fdaea122feb9b4841ce5359db85258408db7a0d863e9ab22a; - ef0f6c7f56ff22260c66d583f79c7f581181d3a0f3167c93786bb6c89de4372c - be934afeffaf5e6755a92e6606ffd054627dbe1b18ad6ae543363a01da605512 - 317c2181564fc4beb6bca61df19dae03af031585db6911ae34357cc7c383e219; - 773e0db8f86c5182b5f51d10376f42cde275dac6a646ab1cab065760e045107e - 3f92ddafdfe67d357b4f9b61807bcb8b0f1f6c2dacba27902f48fc15a31db606 - 38ac2f081986d34c3aa682aeb6f37641d3566e99fa8b838c7bbe5a4a3d285a77; - 34860a848d0afb20e43f4a36b3c8941f5821864216da9cb3ce1a11f056565a3d - 9dfed86048acd45ec0009c1ba3b20a1ba645ec141070fd8ae41d25e159bbce9f - 84873123455e26c2233fae1a10168a04b2db992d066a9f28eafceb0efd9a8b1d; - 854ba91672ae1b8f6c29395dcfa4f3514ed97dc2c9e1e419f926825619fac55b - 7a700653ad355caf17f89045ecfb3ee821194b54048e55d8eed41fea2b0a22ab - f8daa2c3c478bfdf5431a817e3a8b4692cc0326ec5538f410a52626cedefa330; - 0c66b3d8c3916940b70d381d232ba8aecfe27e3ae63fa6cbb287216708f224f0 - 477186656245c4083dff93a95c6e5deb707916e52cd74abbd522743c24c53088 - c5f42c73614ca5377a0ea473c6bc4ac35e696855b9685b10dd64ad2ae42cf467; -} - -neg { - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000; - 23d767107e23d5ce14189cce939c4b5334d6736da3da40a715236b9d8319efc1 - b72898ef81dc2a31ebe763316c63b4accb298c925c25bf58eadc94627ce6103e; - 9bb944cfb58b186cc551e0a0eca74528c7618ff47485bf6a723f43d990f69f6e - 5246bb304a74e7933aae1f5f1358bad7389e700b8b7a40958dc0bc266f096011; - bff36d2aa923d5a9af5398e2cfcba4acdf3c3181a8ff00b8a1099cd97a4e8542 - 2e0c92d556dc2a5650ac671d30345b5320c3ce7e5700ff475ef6632685b17a3d; - 1b65a51746eabb7c0d8d9844dda03bde7128407e94661db2d5fd9c0f3790d120 - d29a5ae8b9154483f27267bb225fc4218ed7bf816b99e24d2a0263f0c86f2e5f; - 88f4cf29a610c4465f63a272fde2f19a4874a70a0829885014379b637ab0e82d - 650b30d659ef3bb9a09c5d8d021d0e65b78b58f5f7d677afebc8649c854f1752; - 94ca4d567efcf088e6bf1cb3698f6b8bf2164db4f523e28781aebfcbb501ec63 - 5935b2a981030f771940e34c967094740de9b24b0adc1d787e5140344afe131c; - 3f8d7ae4f1698921524e49ccb2ce4459e4c048f76f04c5e60179f5417d2d52db - 9b72851b0e9676deadb1b6334d31bba61b3fb70890fb3a19fe860abe82d2ad24; - 1eaa0c45af0d8f85d865cc66ff3d0dc3355f1ac36821cdd95a6b9232a27f9044 - cf55f3ba50f2707a279a339900c2f23ccaa0e53c97de3226a5946dcd5d806f3b; - 33e142c78ee87a7980ade6c796e7ff949cee6d3af0415bf5b6901f84c2db910a - ba1ebd38711785867f5219386918006b631192c50fbea40a496fe07b3d246e75; - 24a0c185c47787caf1a666a62002a503f2a3e591e5f2946e148a47b9b114a884 - b65f3e7a3b8878350e599959dffd5afc0d5c1a6e1a0d6b91eb75b8464eeb577b; - a8bd0c1c3f219a97de87b22e8cb3eb5daea33b5646589b6925ec4ec83ca37455 - 4542f3e3c0de656821784dd1734c14a2515cc4a9b9a76496da13b137c35c8b2a; - 1a340d2679ca205f6b198cff4bffadcde1afeeed124ef0c574655dbe8732b681 - c0cbf2d98635dfa094e67300b40052321e501112edb10f3a8b9aa24178cd497e; - da43c139a1f92ba1b5fc996befe5218368eac3c46b42e98a9cca8b8f6f1540f5 - 00bc3ec65e06d45e4a036694101ade7c97153c3b94bd16756335747090eabf0a; - 81aad864a31e5f4afa32c29eb97f22c103dfe5b1323db05fc9b1545312aa6c0d - 6c55279b5ce1a0b505cd3d614680dd3efc201a4ecdc24fa0364eabaced559372; - 28231ad38d214f1421df7005eddb4f4c12e522b10d1cbcd10ee26dfcc222a62c - c5dce52c72deb0ebde208ffa1224b0b3ed1add4ef2e3432ef11d92033ddd5953; - c1facefef35c1ed00db767ed0281ebfad1f3c915c6649f5e1c26a6f3f9478b43 - 2c0531010ca3e12ff2489812fd7e14052e0c36ea399b60a1e3d9590c06b8743c; - c2e4046e7200386ca2afea8ecc9c98c105fbf6e31b598e21e482796a69956040 - 2b1bfb918dffc7935d5015713363673efa04091ce4a671de1b7d8695966a9f3f; - a42fedea4eac90580a0bbcb0491a7e8cc82de7a99aa74ed35f705c536afa0236 - 49d01215b1536fa7f5f4434fb6e5817337d218566558b12ca08fa3ac9505fd49; - d1ab8c50d54279ceac870d0ce4a2af56bf8c03e87482dcb7775183a4908ac739 - 1c5473af2abd86315378f2f31b5d50a94073fc178b7d234888ae7c5b6f753846; - 1ffd85fa5ead53ff509756fc28051ef65eca040303b65f7b5b7e1d1a8508e030 - ce027a05a152ac00af68a903d7fae109a135fbfcfc49a084a481e2e57af71f4f; -} - -condneg { - 5330763b29dff20501a1d6c64025c36279083473721f5cacf89168189ff9810d - 0x00000000 - 5330763b29dff20501a1d6c64025c36279083473721f5cacf89168189ff9810d; - 9d9c36e2126d911a503e1cc1a8489ee74949ae2a8408dc7d72ed0d75e4350545 - 0x00000000 - 9d9c36e2126d911a503e1cc1a8489ee74949ae2a8408dc7d72ed0d75e4350545; - 47da10abec2cb54c5890e5945999deb1d89ffd268bbbe2eafc86f1acc8bf5f7e - 0x00000000 - 47da10abec2cb54c5890e5945999deb1d89ffd268bbbe2eafc86f1acc8bf5f7e; - 3e6ec07de86be6ffab2dfa1deb9ed67844645be92bdbb22b7ba91379babcdfed - 0x00000000 - 516ec07de86be6ffab2dfa1deb9ed67844645be92bdbb22b7ba91379babcdf6d; - 5f5c0730649586b5c0b60a14d3b669b3649eb6725d71d834e78ff2aa0e5450e5 - 0xffffffff - 7ba3f8cf9b6a794a3f49f5eb2c49964c9b61498da28e27cb18700d55f1abaf1a; - c357befcc6836d89387915e368e5e6162252b433eb58d94eb3cc4b783e98c226 - 0xffffffff - 2aa84103397c9276c786ea1c971a19e9ddad4bcc14a726b14c33b487c1673d59; - 713ad0f656a8fcd75fdee2c4ac248ee7ad09a5f357c565daa94ae46d8590d2c8 - 0x00000000 - 843ad0f656a8fcd75fdee2c4ac248ee7ad09a5f357c565daa94ae46d8590d248; - 909d669185e98b4a88a6531b830193b23035d64665929e34e86d53c4a9eef30a - 0xffffffff - 5d62996e7a1674b57759ace47cfe6c4dcfca29b99a6d61cb1792ac3b56110c75; - 8f23ec139f93258e6d57fa278339f1cb5da193c5d1ad7183fb2b151111262285 - 0x00000000 - a223ec139f93258e6d57fa278339f1cb5da193c5d1ad7183fb2b151111262205; - a9a5480c72157f389be80ae7ad63502434c380ccd1cef813dc9bd2e9a85e2f22 - 0xffffffff - 445ab7f38dea80c76417f518529cafdbcb3c7f332e3107ec23642d1657a1d05d; - 316f98b6697e7daa8775d3aa91dee8fbbae4e935a2f62cd2975e2d552f0c9846 - 0xffffffff - bc90674996818255788a2c556e211704451b16ca5d09d32d68a1d2aad0f36739; - 70128d6dd5fb42f287fba3533c71cb5dc2361b6d91c3d9626c58849e27f7d349 - 0xffffffff - 7ded72922a04bd0d78045cacc38e34a23dc9e4926e3c269d93a77b61d8082c36; - 66a6f3dc6274e4122dc401ef23529175d71d96b660a52cdcd64556073b5430b2 - 0x00000000 - 79a6f3dc6274e4122dc401ef23529175d71d96b660a52cdcd64556073b543032; - 3909505812b228e6ca5cc6c0b17824ef765923eded6105e6eb0f176781624c5a - 0xffffffff - b4f6afa7ed4dd71935a3393f4e87db1089a6dc12129efa1914f0e8987e9db325; - b7febd7d63efae3bcc60c1c344f2f6166b272eed785a9e541d3ff4f12e82a5f3 - 0xffffffff - 230142829c1051c4339f3e3cbb0d09e994d8d11287a561abe2c00b0ed17d5a0c; - d1cacc1db40de13351224046975319d7546ae9e88e1909c2a8f46792a140d279 - 0xffffffff - 1c3533e24bf21eccaeddbfb968ace628ab95161771e6f63d570b986d5ebf2d06; - 4c449a50fc1e145be1463e4c171b3c51c9683c41c45005d8aeca607911c9b3be - 0xffffffff - 8ebb65af03e1eba41eb9c1b3e8e4c3ae3697c3be3baffa2751359f86ee364c41; - c929c50eedbad6ceacdefb00bd58a32820c874c906741e9d93cd0f668819edcc - 0x00000000 - dc29c50eedbad6ceacdefb00bd58a32820c874c906741e9d93cd0f668819ed4c; - 1c57449dcfc7e8f9fab77d226d4b50d7dee06c29d08d3d4f4ae7c8ad238a0a82 - 0xffffffff - bea8bb6230381706054882dd92b4af28211f93d62f72c2b0b5183752dc75f57d; - 396a2ddc48f158e73c95dc289da3f0d3b2128875e20c401cb50fd6cc7a28dd18 - 0xffffffff - b495d223b70ea718c36a23d7625c0f2c4ded778a1df3bfe34af0293385d72267; -} - -pick2 { - e6f52222f35081896f3d9ecc0ffb27fa3e75c8ad1c98e161878d2c3cffd72c78 - a24cd71f7acb653466b7d67bb41efb5a29503d2627d2ce28fe19680ccd939be5 - 0x00000000 - b54cd71f7acb653466b7d67bb41efb5a29503d2627d2ce28fe19680ccd939b65; - 4e51fe2dac96a664d0675962116b7af4e605194a1c9fb774c621a3107994c9ed - 508934be10ce5e11e6940d56e84b148e20f48369e748536846763c80bab9af49 - 0x00000000 - 508934be10ce5e11e6940d56e84b148e20f48369e748536846763c80bab9af49; - 530175217081c3fb3ecd17702ad334ad48f05affd5ab3754ef10be5b0eb5375d - 8aebc7e01e2bb2829f21311462175948d85cd3e65d676eec893e3df13f639d07 - 0xffffffff - 530175217081c3fb3ecd17702ad334ad48f05affd5ab3754ef10be5b0eb5375d; - 0e53c5141d72c8c81d80b1a1283b0267b278f98e28ce08ccac7b010022e5adae - 2215cc15e950d6abfffa26113f269628f50f9ac37ad3260ae9189958d75080b6 - 0xffffffff - 2153c5141d72c8c81d80b1a1283b0267b278f98e28ce08ccac7b010022e5ad2e; - 3dc16434679d30686d5023fda4cc574563841caf1d588e965fe1ec1c4ba54398 - 4ca50330751d33ebba981277926a3fb801d216474cb183f90947680f5ea383a2 - 0xffffffff - 50c16434679d30686d5023fda4cc574563841caf1d588e965fe1ec1c4ba54318; - 09e68cb66b5ae2f3160a71738d1e9a042b9b76335eddc4b9466d0c6b8100eeb6 - 270eb833ae635bed17df9218a53a91b7afeb74f0df3bfffb8334c04773cf716d - 0xffffffff - 1ce68cb66b5ae2f3160a71738d1e9a042b9b76335eddc4b9466d0c6b8100ee36; - 831b8a99e3b44bf21cdd4f3c06da7c16a95e98f3dc42cf2ac282edec67d9b2ca - 482840e31c7620de6d290d747afc63ca199c60169f8eb62d28ca1142c5336990 - 0xffffffff - 961b8a99e3b44bf21cdd4f3c06da7c16a95e98f3dc42cf2ac282edec67d9b24a; - a022ace6772d82d30832328c7cbfedb622b710d1fe9313a77dc4cc5ca577a7bb - 39c86c57bf581c16d8c03b4ef0fe813815b5da1281f03bb3f2cdb0ddf19868d0 - 0xffffffff - b322ace6772d82d30832328c7cbfedb622b710d1fe9313a77dc4cc5ca577a73b; - 719d3f13c38b915873bcb14308bfd9bb6f4a6cfd249a745bceb55787ce480caa - c72de6e206ed24555d091763644d4405f2ee5dbd846a036d6a21442a6c40e0c6 - 0x00000000 - da2de6e206ed24555d091763644d4405f2ee5dbd846a036d6a21442a6c40e046; - 07cdd3cd677a3c1783bcf7855bf1dbb453809b66c66c7bbbb67690cea33ca581 - c9d889281ac117390875739e4b62df6dc3cca6c65439c46bb907c81d3a961fa3 - 0x00000000 - dcd889281ac117390875739e4b62df6dc3cca6c65439c46bb907c81d3a961f23; - a69a728035cc69d5d3f96dd4a8081864333e53e434820dd569deb9e58393d4b7 - 3f4ef71dfa1eccd817d3192dbe2e08466e4a66b4d836b0892b3636dc523098ed - 0x00000000 - 524ef71dfa1eccd817d3192dbe2e08466e4a66b4d836b0892b3636dc5230986d; - d249414415ac4960e934d29e08c75ff1b18431a6e18f7404e638293d3d8e81d5 - 33cd02e07762f74976834d1b6dd3b8eb7e2ad7a5d04ba90bbe747476071f10cb - 0x00000000 - 46cd02e07762f74976834d1b6dd3b8eb7e2ad7a5d04ba90bbe747476071f104b; - efb782aba4dca351a5c9279b370073840b977b2458c6c84c9c9046dc92cc5507 - 6d9f50eb56b84989aab77c54987f05c715b74185417863f2c275635d2d6f2eeb - 0x00000000 - 809f50eb56b84989aab77c54987f05c715b74185417863f2c275635d2d6f2e6b; - 10c4381ed467e27d756ff7a260a6ffd282ad757b10c9956c518a43117699ee91 - 9b9a70c67be3296ef9d65fdd8014c4b263c28fd31f3299f4461c688c469ff704 - 0x00000000 - 9b9a70c67be3296ef9d65fdd8014c4b263c28fd31f3299f4461c688c469ff704; - 5a30428bee407ee673ec7d2cb4854efd80b9761df5dec906463f888f60be7152 - fc2e139be53203eb73041e9335253534c420208164682c2e02f31f084f5582f0 - 0xffffffff - 5a30428bee407ee673ec7d2cb4854efd80b9761df5dec906463f888f60be7152; - 43c7cd903c7dd7cdab85c6b5585955163e0da7dd0c5b5882ac620246619af342 - 0eb52162c69425ad75b778c39746014789f7929119d4e122d4b98bf64784fcde - 0xffffffff - 43c7cd903c7dd7cdab85c6b5585955163e0da7dd0c5b5882ac620246619af342; - f37f3707e4609d389096c1fea551b572a6b4644fd6af2e9e7a0fa93a91ae38e5 - d10dd4d911346a5952e3123d4f156a7e40807d142c4afb4bc314ac6f9346dfa8 - 0xffffffff - 06803707e4609d389096c1fea551b572a6b4644fd6af2e9e7a0fa93a91ae3865; - a4f4c203cb892691a6d6e9dff8a10ac1a8d9470b13ba24e1bddac05d6d7f9c0e - b88145fabdeaa9fa108bb04a4d283ac034b4c8d8ffe1b2174de9a80254762c54 - 0xffffffff - a4f4c203cb892691a6d6e9dff8a10ac1a8d9470b13ba24e1bddac05d6d7f9c0e; - 649d8ce64f623228553de99b823c5f5c5ef37f00e2ddf658fc9bc2405afde715 - 0f24ace92223d2db75e2d82e8a5bc8b0e7981478216b999d2bdde9c72732d58f - 0xffffffff - 649d8ce64f623228553de99b823c5f5c5ef37f00e2ddf658fc9bc2405afde715; - 3f466e24ed4169ca3df624d747f054f97422d5eee3fade2fa3c4eba488694a6c - 37e3171c9aa56d07ffcde4f1fd0fdcc41e2086ecf93c9e53f3f6a4c3e4db587c - 0xffffffff - 3f466e24ed4169ca3df624d747f054f97422d5eee3fade2fa3c4eba488694a6c; -} - -pickn { - "91aaaaf3ff9e58f299c0f6d0a4a3851d100423e4b7380d5a32a86cde6cb19562 - e586b4ab140cd20bfc70aa5ae1c389941a8c631ce033f54793d77c91b5e3d50b - 911122291921aced748e1346261ce8dc0e50704bf59495c3d7c1a9806ae58b5e - dac7c42fc0253029c78310ea1508b2464db2c44689fa7d485fb5863b7c136f15" - 0 - 91aaaaf3ff9e58f299c0f6d0a4a3851d100423e4b7380d5a32a86cde6cb19562; - "e8864778a3aecd6f35f8afa097072e94c4e50680baf91a6036f4f24fb0dcf111 - 5dec44933a517f5a8bf6d858920e1200c74e65132baf0d08ca033e36e15a1c46 - 4fca88e6d122c0a460b5dd502281d80616edd30bede891226b4b3c4b3eb9eea0 - 5fbf4e034d45326d89ffe92bf4738a7120c63ea42568c25acacf4dd7915b9e8f - 343001277d416dd31dc770232fc47c7d02884fef3fc10eaddf6f8b42fbb00b26" - 1 - 5dec44933a517f5a8bf6d858920e1200c74e65132baf0d08ca033e36e15a1c46; - "f0cfc16fe0cb8910c26f6f46e69954dd34277d171044140c2dc448b6f63e053c - d54feccab8d55297eb24f622818aaa2ac5b7fcafee5efe872bb600cbdce85a3a - 5f1cb6c6b4e8eedb566150a99a7c92228e7f737efa1810b9d40f9a4ea020e56d - c762a32a3f3a6f8cd956412eacdaa75ee56b347b952a7c18dd19c0ee2e50b8fc - b6e76d1d2cdf04692036f26515ca6b92d57b1bba625f07553d2d4adf89de9611 - 874c9e94d425fe9590aa1cde396ec56531342207a0e3b42ef0ae710bc9b68418 - 872ebc0bbd45d07727887aa8116a5743880093c73b3048c3b46920c04e0f64e2 - 9cde037629d20a4481ba7050546eca2dfd293b0953aa708764531bd8d0fba387 - e9f7cb8ed4af14ac61722de66406e97ee9a87d9362dfa87e489a9c98f8b891b6 - 6c5bb4410d83505ad34d10409d02fc005a47ef802b5d9130f3b5d385ff78957e - ff40983b47e7263665a03e4396421fc34209afaf52d7d69012833b4a228e6c40 - 4588ed141f6401c460ff6ad4888172c9d19f15f214d96bedd59f818d7c03b720 - 99ede977304bc4e8f5edc44463b48fc13c001f5c584f2b100c791ae472fdddba - 8ba76d6aa98a062e1091ca60e05ecf21208657bf287f20c6cacaaeff41a537ff - a18760b118187f5b392637dd5c5f97ccce583b5b84b69f8e37d8caf77c616db0 - 7e921cc5caa3b3884358cb0ffd2d9d160ed54256049fa1540d861dbb6dd1631d - aa8102188fbba89c45259c52080b3969c234d070411bc4b91870a8b482eedfbf - d98da58b248507edf310beb9fb522dd23d88bc0412ef3b5bd7a13b7a15070647 - 0626183221836da09c9bb5a1dd07df570883af17a9a8fed1c4bc7e8770e348fe - 16b01a5593b3eaf0902d0ade7e00da7b7a57556c2e7169e8b6ba5df5c5fb02a5 - e40715b07034e109d79a95a8b031eebc6c59dd0bb77de6cb960fe65a6d1be59e" - 20 - f70715b07034e109d79a95a8b031eebc6c59dd0bb77de6cb960fe65a6d1be51e; - "e30f85631b4ea4aadb9487c76cbec40ab63101a482e5aa2e3ee329fc21071bf4 - 8bc9fdd41fe1ecf5c2cc2075c72e4ceab370b099ddc672ee16bbd7a7de19dbb4 - ede086a76fedddb463d9f0fb44b39ac7fb64665061eb96015d4ed39eb33cd772 - a7cd74dc0c94aa8bfa480a88396b7f293f1ac329e4ce79e04507be4edbf4fef1 - 45f5c114a46bf0b2c8be1ecb8fc7c81e7fef668a2e4e9769f2f2dfecf405af92 - 123d101a02348f81088beeb6fafb7f720b49631736829d2f19e95b8d833684a3 - ba936ae1b5555b05601c2e59bf9585846ac01b5b7f6fe4bbd45e0653e961deaf - 51c0c307d99e34a617ead92dd37e1a0f36ebe2e45ef5b3690fd114099d483dc6 - af94cee7979c057995680c3a5adfe26e7dea759e2640b0b09aff383fa355d289 - 6ddb6908532c513f463473e449747f88d47766460ad316734c2cca87963b3060 - 88192953b60710667d47633be71d87214d2dc8be882ceb6928daf311499d2e83 - 37da1b76c2c16025f0644b6451027c8bc9768379c3aa7ab8410d34d8c8222706 - 1a46c0531cc13f546e001a67721931f4f6bf8eeeadaaab667ee651db0b272509" - 7 - 64c0c307d99e34a617ead92dd37e1a0f36ebe2e45ef5b3690fd114099d483d46; - "9929839bce983fe53c4f8f9d07a462f82e8eebabba2c0daee1378abf585bb53d - 4e47d3997d6562c7b0347acc96925bd1907bf3a9c57d51b099c4a574d7bf8fc7 - a0de02656ba18dd1cfdb2938fbb864f9f59001110391ee1818f5c1dfee64f61a - 9c4153154f5b827bb847edfa04ce754e442f2e96ea001fc27f6d94ea8b06fc00 - 7ba90562980966abd857be3a84c1bffeabbb589415e722e51225f8317e829777 - ac4657b264ccfad4f5ba3f7a470458101d5c6025c45d00191ddd4bf85ca48705 - 8b11cfc6ceb02c5d4b3e19c19f1ae745fd0cdfd9da1a80e9df1be8f7bb99ace3 - 1202bae1f86d05ed8fca09965bb1cfa3fb696a3f2b7089ee10589394639da2bd - 143f799fc9ebec77aa444eb5ec95f64029cf61b875a2f94e228323844cb8eff9 - dcf99568b397db79bd2e8ae49778e1e49865e91525f932a1813d1c395420a43c - 84fdfee8137558f0b9f2441c375fce466e3212c0d0de3179919fb130e61b711a - 602454ffaf59610f76863a7456146f866539740d6dae63a3628d408e34db8e76 - 86ae4475d41ea312a97c821ac78b815e459dc6bb4d52c236a39e5e53ff17f5fb - 0fd56e878b74a2daebc2acc30c31c279f3dab146d748e7aa9b17eda7ac039c8f - e559e8bbd51113f84ebbe35ab16bfd46cf610a5c61307b986111ddbee3037f7a - bac90f3afdf4f4828368090958aef5e49aa83d25fc5dc15d9b8a354a30961e75 - 253eee8f614306e59a31d9fab5423ea269b67babd54c52243b86b8af1372f3ab - 69828b787af1831f772a3bb9a410dac8bc47909ac6bddc94a5c600a3167ce780 - 1903e9ca239847045875b0bd4e1575a724d9f729e3cbfc377de17ad29839a121 - 57bc65c0fd8495014f31e3be740967f3fd1884bee743b20b947339923530d63d - cf7427ebf6088e6f3385275f993b5c06ee14f738b59d49ecc327521ddced2a4a - 74c2a4122225e97b646d6a38584626a6ed811506ee7cd00b48ba563b7a776380 - 604f163d7d7f4987c8aaf2e7a946cec1597ebeb59aaeaad0dbd0737527b9350a - 30e7ae69cd5fb42ec00ca840988a59bf5688aa0b810bb2e9ea24fb5b322891a0 - 68caff542deb61b055bf65127a94d8ab107f5d2496764f97351dbbfbf34928e4 - c0d307ece7f18150d958bd88bf11912dc818fac7cae06ca9ec3fafd15d452af8 - 731b9ae286f29660fd0814568351bd6da114f3ee8b87c217cfe531746faa8c90" - 8 - 273f799fc9ebec77aa444eb5ec95f64029cf61b875a2f94e228323844cb8ef79; - "85b3448d0292edc0b14cfae9225989a16a61ee8441166d5b97faf876b0ab6c7d - 88b0f7c78f8390b6cc1de0afda111326dbb41e7603b82033902eb56ea542c2dc - daf45d38b24294648a7b203758ff0654d42507e958bbd98c72229aae0a9e5757 - 98b44fbbf6e45c81c2473b626307506881a9fa609c546741b3637b731ff62adb - c0779c0f0a35658998ee9cb6b0cb6b7e089b7f288ea171c18bd2664ca5c3fc1d - 8da42494a2c1e2034d2009fd486cc230085fcc8af171e2bc2cf428bbf9b4bc86 - 6dfb99cec539941c9e7d26e5640641e4ef2c3f1a732f9c85759858a95c346ea1 - 471a369f8d1d3341ac707f1c41e5f0655cae51d8a170037ee349b3c14e01be2d - c1b75b02941ae0c2e398a2c8871955c8306f6ab88cdc6d751e11b35605d10829 - ea508e41e33ca0b03b5d93a54ec359e01a5a00a98a80f7e6d998641a6cb7ef58 - bb009a72b5d5be344a3ba9509b6e8eafbafdab4b0ec9202c8d29983935c6937a - fdce2ff0df8548fd7df3b8a087aa30c819af0eff3b8931e5ddedfdb0f4450919 - eea3990f7f4045a3b6cdae27e4dc8a8062049ac4423ce46108ab464d866b80f3 - a18000f37c8c4a30195e71864b14f170a3f5c427f4769c736fbdc18b3fe68887 - ba9aa19e99a69b34f357f92d95a6c409f1bb331d1d27b693164cd0dbb552c771 - b5863e0215351b2f9b6f661ab94c833016bdef73a34b100b6db79ea8d4b22ec3 - 983eb31be6cd1cd4cb53e489e4535683e21c00e6c52f685e84bd3cfc98f9ab2b - c31c18c6c12feb3be4e51a1671fa6001c1dfadc0ebb35349766d9d07d5a70025 - 6f81695294071c711947499c2c3d96969a70948c29ea9506ff675d25052f0950 - 3b42ffd7fb054072e7fb93bfa63d24511e6c93455cdd5b9be3c8382a3cdbfba4 - 6d7463ce0227e29a2706b8ad6be0d6cefa173c261697520b23edb87a189d31eb - f6cea0722a490515f48632f42f167a911ba00fd9883604e52d713210f3d9475c - 6281bf17cc14876c75e9620d8bb9bfd6e4dceae1ad3cb675769f94623ab3a955 - 2c943465a6d4484c71b2c5ae26e1d738059667093450cff54e6b45f12a7588f4 - 3d9ba6aad36754c5c767a0f288b6dbfcd2f1e21bd14094f4ddfb7c4bb79ef882 - 052e95ca0672218808e36c18e1fdee412a945ad735ea883abd527dfe8343a51d - 3f8ec0ccd82005e01ffd1fd7413a2a1dce1a177cf53474904cc46abdffd22a22 - 2030168387fa230e7a77eae5f051b4e0f1cbc53a78a5df640479c9fc373b9d78 - 3abd6a4fb5a585bb1b4609cebbbd1035392c7565654331a173092c098e1583a2 - 6bceb64086f3874854b4c89d31d20d8772b2f48be6a5fa1fe572be9927345103" - 2 - daf45d38b24294648a7b203758ff0654d42507e958bbd98c72229aae0a9e5757; - "8a9e76766b2eeda9b4de923344005a825bd2475bc4d529b033de3510cd405b73 - 5206880a0e1c282a10e03253c787e005bc9a18613b6e238f1eb72c604844a2ab - acd4fe99d1df199ca20c743238a2bf9562ea4de7b82061d1a6861d77146bdfb8 - 6dccfdff241fd837508913d7e0b1ca3e7a426be578c2e82612f7d2b2491f08f1 - 76aa8f5fb4b3592ff58785ea27d287fa5f250fb84fc9838fad8d6a2cfc223dad - 71019d81508491afb6a33d8c99aba13d59c63bb88a2ba1182c144f171ed5a815 - f6ab8f0b95fcaad29def12e05f348a9a35449c7ef5e2859748e69c517f4f3f65 - 237b33cbba9ebcae93f8a4fd863f62a03651be2e936ddb5a62dd3b6a68734b2a - 4bbe3113be34a9f7fa26dd96258d1776797b8ea454a2f596ae076bdc0f5d0ff0 - 19ae0acbd7ba59869b51caa13e1041bcffed633235a858f39d0d583575a64123 - cc5e18fdfedf9a416727f81b24a227c0c0771565fff69fc3e19399a254d8c9c5 - 50765357fa421d9153c1f02adcc98f188d2aac6a39fc8d522c5e81fbb775bdbe - 10e3e53b7605240cadc28c4d3aeb1afe40b7d1d547f4ad60c8d03006b42fb499 - aec6bfd729a6e2898890c9ee15338aec209c94141dad7b7884f7be481a2f0d6d - 8f9620a5b985a3a1dc4825f1f4c683457a98f799118691bc57b17ab42713b593 - 92c24c6920edb4f37e73dd795ac9bbfcd8035dba28421fce290109c222bfbc86 - 45bdcd99b590e64aeb5173c7538e77a7cd10a9d786338c43e3a0946b33a9c822 - e0b86e6b4752ea2cae053b1bd897c6d749c7fa46308be876b8006c3ffa2d6479 - 6cb53b7769f0da52c697c8640c029099d84afb55c20c9ac84b959ff36c339e92 - a21436f9a4c876375d16c41bd3780f024b867f6fe6394c5c64b4ea5a6f306c7e - 93b40e751d291e90ec3adf902935285a5746781bfc1c594d520dc5828ba53d3f - 6dc080d82251557b9804deeaae90bb1a45d9895c5067f3b04dbfcbb5ab0be3e2 - 22783694c9ab9d652dc216306ea4fc09734e90bd08625e688b9bc1b8c73e3366 - 078b0d30cc5fbb248a5e84a416a3d849772ef6eadf20f73eeb82125f68a216e6 - 83dd79bd150e5f7bf7a357236ed41ca06b8c40bcce840e118f6cf457ff151654 - 72169420815aa9a38719072be9c824d68a0cc5d6b4251ff9180938def3dcb0ac - 63f1febc1579b537b71e1fd12687ec49885dbcf93db68f44660bca4780ca9aa8 - dc337f8a3699ff549dfa26c1a5ddab43cdac7062d90fc2a779ff528c414035f7" - 16 - 45bdcd99b590e64aeb5173c7538e77a7cd10a9d786338c43e3a0946b33a9c822; - "aa199ae7d7c298e11aa74e5bcff2f206fe6b53962f3bb39767ad6df19c58d93d - 4b95d1e296609760e06e7e476af7182db41712d73be94a3533b7332a7dbb780d - b72f91cbf1117db1982b035f0e76e51bf4cd8e968b932606450bdae0d588906b - a1de9fc4d0e579aad319de0280fb45b5fed6c9d38dab5216ff8401376fce0230 - fc216489a815b0c98969118c9ada3f7152c4eb07217abe54fae4fd4d63e96811 - b660cb7ac499821dc872c3400fb2590527659ecd72df16c7ec5376075fca7d7e - 3bbbd9dbbc9263d289de49b1648fd64751d8b0e6d5d506a356fee0ed6452ce89 - d17efdc8cff826d28ab55b51211209a27054f2d33f108f34ce7bdc5c71b918e1 - 21da90e37be817920404ff5015346dd05ef32e018632e09b7cea35d42eb1de1d - 66da40ef6fae8df49b5aca9a2400ea4fba527a9513c821e00985625615e71416 - 61e5b60766ca457b36aeca26a62e6f4831691ef79bdc72158c2a2b85fe3b5cb2 - 9a0917795f936a5384c4a504b2ba3d7056906ea4e34474c310b873f88890bd37 - af65ade7e8f0022420932d50d0a8587c43ac4436bc511248358886e2c7072c1f - fadd2a9fa72f438f147964180ffba490beaa55baf6275d8ca347ce5f5f94fd05 - debd9beec2527f284790a9ca8fbc074ec359f4a89974c2ff49780fcb21c5ea91 - f6a57794ba1265d9974e52f856acd3dddd0f6a50844172466c82f0d49eef676d - 97cbe03e723431b6c14bf1681e845d530e083ddaa26f055d3e162615f57c113f - b89054ac8b7135c1e6d215e4e5dcf679298fdcf6ef35301002be560389f8cd08 - 8ba6a9d5ee4bf15d87170e7c050699e858c6316bc92d5f4e19eeb3ed82e012b0 - bf0f272aabf63cd98397f4da2fd3c5742373529c91ab455fdf394fb6d0b8272d - 7a2a4980dec077abbd6a06f8b90219b818d4990b8f62b9dfc50bc4feec31eaf6 - f1d55b4e207cf5b7bdff5f59a63b55fbce6704b5ace5c5183f6be8e4770c567c - d55b23bebc2f16fc9adddf06ece363add71c4cfd73ab228461cfb926addee0cd - 76ac92ee62c2bb928bb5ec11673b51c2f1fec44ca27741a647cadfe55733eb41 - 1544a9b6c6cf77fec3e83bb08056bf18f3eb440611249f60cc97b58b5a93d364 - 702a0023d8ff6a108a2eadb777569f54df2c3b85634bb872611ccd8cf74e2807 - 8dc8889dae004e88a94f3c3beb4d39da7c074a038ff8899c5798f7a26fd17ec9" - 19 - bf0f272aabf63cd98397f4da2fd3c5742373529c91ab455fdf394fb6d0b8272d; - "63eca008f74f57babb34dde1fbaa5264656007f7479d8df3ba5cccadbe83925f - 001a67bf61d077528bf9b386694a99d7293d6b49f368ad54767a2829643621b0 - 4c124850c332a4e2a6a335e5f5676f803ede7958719b083f648137cfccb82f50 - 39f293fdd5b28c882b824d1cfef38a327334776139bc2d814834a86d6b2d93bf - 114df0c93aebb6a764740e43a67c6b582b49f6d0c393a23db42611023c044d9a - cd9e11bd49d7ee82e52f89d7100fd64c4474695054cd22442ed2bf17991cebe8 - 56931f05328bd38dea431af6537fe4a4f1e419a24c5181974e61b64367a65a5b - 2bec95a108b7a500937b5a3f3c54ae9b2cc7b11629ac581f7d8663b9c910af96 - 380777fd3ab97d140a142d3d37c7786264ea00b63083219652376d7fd56ea846 - f0fb2846d9cb0b88751db963f9360ff2bda25052eba9edd2ec561807c1f0fc27 - 34294c58ff5ff91f1472dc3d7b3099c81ef434126c58de3751c788a71f2a78de - 05c5a1c0bf29c1bef5da9298450b8ce6c5856b3f7e2037133734a03959573927 - 7fd9db5b2418267e94db49ea0534ec8d397f32f90981448c944a4ff3cb6d9c3f - 7015d096ddd557e669fcedd9b3b2624b910505f756e8ea160c5436bab604669b - 46858fe7612b43ba805a6c7999a3be02b1e635963792d228f1414fbdf13e175b - 70422706d36540ece562d1c36bfc5b178d1cf47c1ed87bea38be5a9f95010521 - 250e48d385aefbc10776582e71e4139148c99d6f9ea8c46a8e57194986eb2ef8 - 44accaac045de3183f7a45f89d4bdb5534594c90296ea664061f3f8a142f2d7e" - 9 - f0fb2846d9cb0b88751db963f9360ff2bda25052eba9edd2ec561807c1f0fc27; - "3fca772e14531611cf82782ecff97358f710763698b73e84479056a97d7d352f" - 0 - 3fca772e14531611cf82782ecff97358f710763698b73e84479056a97d7d352f; - "fd8d6560ef50712fb5f0707c342f618cbbe5697d261d249ad4887dc5ebac4f07 - 89c98bc89a81402e218e377257bd1532d524dd33a3b8c0458b2e5211d4d7b305 - e48938f9271a8861d46fa6063563b92c0a6fd59634151b075316faad9c87008e - 332fb871bf280cb18dc5d444a565ab1e505d274e52c231808af7d52cc28990de - 9073abe824ac2d30ec9562a5a67836af5cf9c038aee85ae1f7d387da64f558d5 - 04c3ffe8e6ed014162fbe6f3b8467114afdb6d5d51ad878c4462d8a926d9966a - 5864d08abd45dd3d4b6e59762a8feb76cdbcbab01a66e512d40bc070e2754ce9 - 0a780e6ecd9b4ed16cb4fd1b4b060c74d97a4268733855102b036f89cb4d5bac - 34bddd4d2ac8a920864e6b9cff04ab70f9978a16d0ceb06aee33aaa78e49328e - b65e8424be6a9247ad08f01a28e887bca33b3f5c28ef3adebf37798972eb99fc - ebd2aa397fc49104dc1c3f82f275bf625984c8c84a6f699e801b736c667a8cb8 - 8a704e508538e1d8a64c4c9052f46a07151c79dcf95e6359a8e5f41370ba40e2" - 4 - a373abe824ac2d30ec9562a5a67836af5cf9c038aee85ae1f7d387da64f55855; - "fb1b4c61b9b2fbe2faa5c0e3227e3c2fd4c8277aa629fc88fc18a4a29df3d6f0 - 3431d240f65ae76dcca41df165a4eb4c5af155027844d80a0c7f0d07ca4b5761 - 67e879347f3adcd41cac36e8c80a0f4c2ea80eb08ae9ee2b21e528769eb4c7bb - ce843b0190451928f2e637449b5ed95580645a0e0440ab017026631c619d2bcb - cc85641974b86dfa780e3edeafc0d6730da6f579826ba8f9bb8ab065b1e149b7 - 2f0c812e2c9114bef4810a01d108ff001fe328d575cff750e30133b464e2648b - 407a5a8964f840ca90aa4cf79a18f5760f7a8ff23bd6bf2d6dfc88c980728aaf - 26c2b3f4075ede77023b2de230edf8ce5e75a0cb9f1d81a0d154ba5d79de83f6 - cd98878185983eebc6f188559d9bbf8dc422eca6598a7df35449d0b39106c706 - 42aea74be96565c44c08df95a6aa58603085152d4f7fcf38375283859d17a46c - 31383c1609e8be3dc7279916eb5bb5d3e95e745a96f55ed3d69f296bfda19a28 - dc140f380ac16ab63124f9f7a02aa458ceeffbed4a9b8e31f45c67ce6ce1c394 - 81bb67da90b02b5b19ce9863902f12f33a85795994d7d22b914f0e82a44a4f11 - fd76e39b1d68f07e538353c0ffeb0c1225f5de64166ccd419c10134329f954de - e9f40437c324cacfc6974bee082cdb82c432a86d8465a0229a1e05fb19dec82d" - 0 - 0e1c4c61b9b2fbe2faa5c0e3227e3c2fd4c8277aa629fc88fc18a4a29df3d670; - "c2b1fe3853bbed5be05536475b2f1bb818eb5ed0111f3be6c6b3bb8ede2d0beb - a692dee2a40878814b9ded7ba7ba47a391585ac93af04a0addec3904ed912ec6 - 015e98f69b98f157f559f8282bfbd20e07cc4a9e2929feab5a8c246011d1098f - 76761cf13e45886da2b747f0de3a238be8aaf5868eca88c4de6b614ff3902e12 - b6b06a046fa5f2e43e698fc96818cc7bf888d5c4f4f2f0bda86cc35c1b48679c - d7ecabc614122bb6908ebabcf7bcfa9a4fae88bb8450d559297c778dd35279f8 - cdd96bbd24cc00b4fa5c8b20efa66a3db1d62e76f001dbd87800fc59f4a29a1d - 9c16ca817b43101672fd1cb3583a6b44bfe2ab5956794280a3a32bd2aa651656 - 4d7ba5f8240527b3c9de386b00dafc163314b3f1311bc30b8434993b50e08d67 - c4ab9766eee58337a92412440f12083a0205c39ba27e0877613b4288dfce9899 - 71ca275f3f7df242b5770d37c92425bde86184ab23c06c6b6bec799c47651433 - 49da5429ec1ade01eba828ad21d230cced84c8a28f239a69194cc0b5de9a0f20 - fc17ee1656b6f0de36158fe2db82ad3f63c196c54002728bde4c5e27e6c0d7db - ece944bcc82f520e8171aefe728863b99a9772cc48b714d82426224b302b7be2 - d2ea262ae062bc1167e79a7bd8abc2b6c7cbbdc03622495d1ff3a56e23c03f72 - 9be5176e8e873f9c320cff256e7b8801cdc1cee0b32ddd715d71abeaf909e0bd - 0e666632a0ea9c9c5cc3fa519a42c34313ed2f64057106e38dddec87d68146b0 - dc48385d46bcedbdf17f43e7b2de274556b411a0ac4b7e89a2f5f71a1d1ea5ba - 76919d83ecc757cfcd916e23e5cadbdda21793a322c0fadad4e581819ebc0b18 - 84830e7a1b4b50e6ba90fd5f8b1198aa60b0c8987c962e9eb12adc2cc389ee1d" - 11 - 49da5429ec1ade01eba828ad21d230cced84c8a28f239a69194cc0b5de9a0f20; - "99f065bb53134babd50f3f46adb63c64f7600acb39487718bc0a39fd3a5f4ebd - f70702612b9b45f7833232a7267492299c23caeffdc4f8a494653cde777861ab - 16c9b6b125cb9cbb201cd0a558fd58cc29f2d197b9b160a0cff88ac890b9e429 - ff87c5e3356c8fb8dbeb739aaedd0df3da2ec3072e5a806569a5847fcbcb4267 - 01d23260fa58bc7c077e05cac9e1359a9f4f2c9f2bc8312e0832376e3c3cc554 - b7b5071166d68c704410d4e9123a261631822060c336b8cf0f5685a7df6ae6ea - 621633e25b1ba392baaa31fc2d6a57e8286f6bf6e5edd5a0268a895af91d61c8 - a29ab1d52fde5e7026124c3cec2be1fa674d37692165f46d1d91bb9f41156a55 - 26d8eb53078f2e515bdee3adc377a16b54ae575343888c27c6d72e07dd7ded04 - ba5d57dae01659afb41b3b4712f0ccfa3b6b2a0d8a99fa5f1078203925897618 - 8cf51cab05199e2154a5bf655e6a9e9498c20cd08b564936b164b0a7f49a1e30 - c5b3977228539a7f573c88800633f1da39a3f1bff9e1018af48f94f211a812b3 - 149a93a1ded07e398fe248962a7656f9b0f15ce62c4aa0bba4a3c6f00cc362f7 - 234974b4054622b0672626f111ea5b44afd81dcb15f29974585c9b77476d9290 - 4be4b2338d92909e6a138d4d2e53e72707a4af62acc8cf2a121c8105ec4ebf32 - 1e6192c030263e3847898afaf5003000552b9ccba7caf6361c1f34fa0890b086 - ba698e634085f7dd38da012c8c97efb97a9b3c08c829d660e72e46d12eba79ea - 712198efd6734fb564278f1bd0dde082482078548dcf4681e65e6dce39328c1e - 8cff8caee2ed08e384331fc0509c1ab44b291d840d19ee991c9978bb7642b4c7 - 98a539cf588938c8ee31d80ff0254e13460f50d7907885f2debf7b68be91edf0 - f0cc67c038324ed37948dfd94ab50dc6fd07ea8b441009ea2c4e185f0d800b85 - 09ae723e872da1687e02c883a254e033e8c67e784ed33e3a28eb8cc92be37d32" - 6 - 751633e25b1ba392baaa31fc2d6a57e8286f6bf6e5edd5a0268a895af91d6148; - "97379391993ac07a0b019c4b6d2d08d4555e5761b4faa7bea8eac269844c6106 - a2aff4f6141eedf254a8f7122ee37a1403b97fddc2805ce4ad010829aee1575e - a54665a1ac19c8ab83dad06bb5ce855b45246a9ad338516c5d67948f86eb1aa7 - b8fa1fa064f6bd0af94d427686a09472b6a841576754500464ac3310cc147d40 - dbb4cd734b211f5ad48452a193489fa25b0c82a594105a96ad627c5cd5328596 - 5396b8de36ade038e4424344fb2083226410f771c8ec979e916f37710b56cffe - 039b59e759c9a380200b129e08d77ef53d703689b60ba5f117111ddd27f1674a - b3456d7bfa566b925ef014c6538c89251b7c0fa9fea89fd1806f97bcbfc3cdb7 - 4ab7a386cbc720b5676de0e76d584d6fa538a0015debe30c37e1839165763d5c - f7f55c12c67c1ca28b3947fb7bd7c4ed9a5240f962425b9b4810191d448af7c5 - 8dc0a95877c2ea17052b55c9f93440319ec38bbf80b375177e84ad14bab558dd - 246d97123750b41e5bf2d96f10b3c9e66e92759373999bd94191a65f25a864f3 - 5bfa2905cb0b0aef125fb39deb2cd392b3cfe3f3ec58f8361e8cd5f12bd2db98 - 192413efd53bb958417f65a818d48d6bbf94dcc77210d9623adbca15633bd7ad - ee95faf7a7f31c7afd13d393ff2ff4e448799c87c62092e9e646efa4c635d1f4 - 77c00984400bbdcc81aeb42085c44be70137db5a0464f6081aa9c8e646e96e1c - 743cd93d6f6a48161881d2224b7d7c0ce96d56d54adff0b719955cde417b35a6 - 92b99335dcf6b33de126d05329d8884802cc3afd0f93e9dea7db5f6dbdc6c623 - 584ccd19fe7395f9f2dc53f2a9da292e0cccfabe82bc46aa64c29581fc570deb - f9321c751abb9df278fbc2054e3fa368734cc852589891b49580332a52b6bf72 - debc2bf3cedb7c897924936aac0b485bc05eb89530c886299e8d1ccad277355a - 472d49f8ccc249b8271fd0630ab575721852e98015ea27732915ed06775b444e - 7b29b054a2347baeda4dbd1b739072e6d144aae3547adc8287c3af84285057d1 - d7a79b1f1ca757e17729436fe744ea7d99a64d13bf85737b6a71d41ab13343e4 - a957b6345193173a231d9db8acb3a6c09bb411d210e0e52c94e75a4d68602aba - 6277d818cbecae95f1aea85481ee631ff1e7c77c6693e6349d1804db784238f2 - 27e1d5a11dd9025508168d9d11cce0b8f0768b6846105161eca53abfa4aeeff6 - 1823372e2c7cb9fdcdc97ca64ffa06564907b09015472cfa73bf0a45d7c90bec - 08cfef24b9eb875598779315de4fcfc918931e05f49b374113c25cb5b23a4944 - 3a5d9db56bac2f413a3d33b6d7a2f54053aa3a641d6554d6f008779939f2682f - 22d0256cb1a53aaefd5d2fde14b63e5adce607ee5a22e8498f29982f88088938" - 18 - 6b4ccd19fe7395f9f2dc53f2a9da292e0cccfabe82bc46aa64c29581fc570d6b; - "91a76b64122a404fbf873d65089a7613bd3d93c4227a4b05817223640ec20ee9 - ab46f7649122de1d73278608e02d44a1367f4f5a7c01d1c17f2a50fb3148dfcf" - 0 - a4a76b64122a404fbf873d65089a7613bd3d93c4227a4b05817223640ec20e69; - "1c12d157172079be7ecc31716fac8946f5517a3da6612bf4a0db65707e72764b - 9d9ec126bd404e82448a16c187152307ab6319fdd5d4280f070275cedf1cced2 - 25be86a2abbf7619f7b92855cc50572af4fcf6ee071078d24baa24d623ebe4e5 - 9b3a13dd1b67a284a9ed869de2663d82035342bc0cad65484da1c7b60b82a55b - fb82840bfd348ccaa0d3d362c1123096a5103a09f979e2f4acdf7aa600e55a84 - c64642a4946ed50924eb1a4c6ab73b53942c5a17cc868f8c6c5ef92ce5986830 - 8e7aaf58bc15be92a31af4f0b092969a250222e7ccbdb638aa846f8253c33d50 - 375bb009118659c831591bd6861e9c9eaec85c0fd9a1facd5f2767ff27e3d36f - f5b4b72840ef438fb8f7fd1419aa5248dc38126cfc29099cffe68aa94b215b31 - 3b0cf55a0dc7856788375bfa1390fe4c628c271c99ea76ac78517ad5f36f61ac - 82cf74084903490f30152c730970f8b622de5414e1a60e1efafc6aa57ff2fba3 - 9d476226e3c4f844f392e7efea7726b02bea64c9aa1e78513efb28a000cf9624" - 11 - 9d476226e3c4f844f392e7efea7726b02bea64c9aa1e78513efb28a000cf9624; - "4f8b3919461d4408a4d4375688f8985332745cb5253671dd7fea3c58b8e33e5b - ecd4f6bf71be54fa88e51fd9d98f60c009fa1b4f15ccacdfa7b26a5ba52b1794 - b0bc276ac01ed6b25fb569ec8c614f4a9299faadcb93bdee4dc637c888381d29 - 2fbc1564ecd906f5d56838c9ceb3ba5b5f13925cadd653008f1ee9f54c18ea37 - 66e9f3ed35f45675f9601181ddcff688229371c6428c1d9dc67699821e3130b6 - 6b08a213ca51403db7e08bf6945b23ccb62465f582248661b901b6e550345516 - abdb83672459dad5b11c3cf9e4d21235ff92c01ab00b2d44aa6f10bfe9b274d0 - f609191b4efb288359af7170acd0904c57d45c7c658c0d670e0fb22f9ebc0044 - e4056ab4b8afad5e6951c8168477f15ee3e11fe3f236a1d19ea201f78b8898a5 - f3b253fd18515ee3dcfd4a14409838a3d993a5274bd77a1e5a7088d20ba6c592 - 710b8819a202ab80bcf308aa94d3305944dc739e33648df045bba215160f8ee9 - 1b63314e9fbd605ac063546ee4249bf9f37da0b6b78d99848f487c6880f70c3e - fb04f3e49a44c4eea104c213446b0e6b81da047a0862604f488e0c6128238d3c - 43b1624809a253f46b12d97aa08dc3f16b25613022483b8044cb01b6d23cfb28 - 0796291d8916b0b70ebdab0f42b8cc55c14734cf7a398d48f94b48d9871ff0c2 - c55cc772bb71392f13258339eaa1d8b01c402e8f6c9b6061f0e1c564feb98234 - 882ad3994d999ac7243ebe9955468a52b2242564a295a9740af8980043f9ef0a - 201f86fc5826d74580c3bd3fe04cda2a823c2a4d1ace3e862a9bf6873ba25055 - 5c39347c213f6e1b5ded1de9f92ed21d99721c4e4216d5abe207321caa426971 - 38ba53a577809f2d2c3cc33016e6141f4a87b6f57b75be70b9cd3d287f07ab00 - 7b9e12c5293fd99ed3fb50a2eac4587bca4aa8bb97c147626dcb9688593ad2e9 - 4852c30283c1ffa109aade1353d11e9712d8c4e6d416926f231a2b89b78fbdbd - 80d25270ef8002232cd0e35433ecefc135cbcaa06511ba3ac14484b6e41c953a - 6159366a1aee4692a9986a12234728c685cf766ad3e2c4cc842f1142c0fb856e - 95d34152d18b9942bb13c6bec8e533c259adfd69dbeb06da63c351997463cee9 - dd5890be52cd0207fecd0f93dbd3a6819aa2c5a592ca0975a419104e7ff4c284 - d9c3f02b7644b3580d190f03bfc9accc8abf9546463a2171d9cb19b3783e0c92 - e59449e7a9d07631450d85d108f3cfec2d67d63ad65a7311b310bb10137fcdbc" - 27 - f89449e7a9d07631450d85d108f3cfec2d67d63ad65a7311b310bb10137fcd3c; - "e5d98efcc2879f32793efa8f96dda9c87b70834fc9d468dc464b0940a7dc160b - 04d4bc5cd4690a0c6561feae82c6be57195c7553276f12aa16fb930ac47e315f" - 0 - e5d98efcc2879f32793efa8f96dda9c87b70834fc9d468dc464b0940a7dc160b; - "bfbed3f0a31b886bd96a817e0b65be1b1e374fddb237514e89fee7ce34a08c45 - eedd85cd817fc74938e60c366445e6bd5383dedd290db3633d5ed2ff320139a2 - 006b1e62b3aa1830de71c0ae063fbf090e536304d601e6c851800ff1d501d249 - a4a63dcc680646b69c8e651dd9c3e043bad07eb9bd6b55bc5bc854d82bbc6b00 - ffa2e97c95ef5efb87b78e89f35e95f89c1c1b2591673fd2166fcc9765abb4b8 - 030984d84d3d9667e436996578a3ae58853d44e111990221cd15795167475426 - da8350e83ac6d67029c24a8d386c6352a27bd22fd6a207474a952742790e4be9 - 0618b6f82b936b5eca87e9ab8dcd9a2e3744586bae01a75cfabb23b1b64f7aab - 5a3e077d0d0d28ba3b6d6fefecc6c2f7ca530fa63bf414976ac8b26ed6596a3b - 381e56750672340b18b60612bd462ade52d3b0d5b487f1af8438140740df484a - 65275cc865fc4b5d94023fdcb929dd27dcd64870773c79f015d4a5f30751ef2f - 724f96fe61888b5a885713d0c52e759726b877031b3f4f80ad24bcf417a3dbba - 17f55299b7cd1d851091052401612078978bf2b09fca8c9e2189474e9d24b81f - 14b82eebd7325586c1ed8be9353fe5ad9375290a92e76d13947c6405febb2f52 - eb5a5c7771ccf698a2e803a3a4e6db056ceb0da4d808db5758f2cb28ccc44bee - 96db7bfd64b7d41430ca6fd0714487926d02dc71571161f8deea0f6a3b52ba80" - 6 - ed8350e83ac6d67029c24a8d386c6352a27bd22fd6a207474a952742790e4b69; -} - -condswap { - 14e55571df646a69a8280bf8dbf8e9afc15bf5558bb8b8236ebcaa19a96053bd - 8bef5021598a8175565e1f2b522ed1c4306fef4e0e973b50d3a03db1fcf11a43 - 0xffffffff - 8bef5021598a8175565e1f2b522ed1c4306fef4e0e973b50d3a03db1fcf11a43 - 27e55571df646a69a8280bf8dbf8e9afc15bf5558bb8b8236ebcaa19a960533d; - 53d8c54864e18f8fc742b2cb996f1d7595122ca9c90de9f49485cf5a5ef05058 - 9aa95be655b6704a3dd482e8424f82d17443ae26ab41092fad95df9cac678787 - 0x00000000 - 53d8c54864e18f8fc742b2cb996f1d7595122ca9c90de9f49485cf5a5ef05058 - ada95be655b6704a3dd482e8424f82d17443ae26ab41092fad95df9cac678707; - 8c7b4ffbf50edf7edcf8d69b67796de38b56a5d4e3a9fb2201354cca0b1b7c57 - 856e707988c37e59fc6689d024b98bc01b71034484ba194ec7f45106267cb7f6 - 0xffffffff - 986e707988c37e59fc6689d024b98bc01b71034484ba194ec7f45106267cb776 - 8c7b4ffbf50edf7edcf8d69b67796de38b56a5d4e3a9fb2201354cca0b1b7c57; - c8cb24a636f6d8f2c045c8441b21314884a71d55c73d4ef7ad65620ac0d86616 - 02b47be53df7c8521d57589256e69b8bbeb1e838d84c090287c04a25d5c08e1a - 0x00000000 - c8cb24a636f6d8f2c045c8441b21314884a71d55c73d4ef7ad65620ac0d86616 - 02b47be53df7c8521d57589256e69b8bbeb1e838d84c090287c04a25d5c08e1a; - 7d96f47612fb7135edfa71dd4526d8b4c944d74ddf004e1653d3af52485168b4 - a4e83162602d20cf71a279c1071038ecf94f38be11ad1191927b3f480d393e1d - 0x00000000 - 9096f47612fb7135edfa71dd4526d8b4c944d74ddf004e1653d3af5248516834 - a4e83162602d20cf71a279c1071038ecf94f38be11ad1191927b3f480d393e1d; - c3a3d4462091b36bd6fd494e70c3166478be0a65bca7f7361246c52dda402981 - 62d0ae1abbe5cb909328f59e71330269e4f2b1d3c664e7f1f0780e0a4774c262 - 0xffffffff - 62d0ae1abbe5cb909328f59e71330269e4f2b1d3c664e7f1f0780e0a4774c262 - d6a3d4462091b36bd6fd494e70c3166478be0a65bca7f7361246c52dda402901; - 38c9b0d92be50270e29cc3181952e745cbf21c8d145ae0c0a6e59f25394ea59c - caf4896a2d3666200741d817ee1dac661652b9a1741ea966d5ed7cbc4c76217a - 0x00000000 - 4bc9b0d92be50270e29cc3181952e745cbf21c8d145ae0c0a6e59f25394ea51c - caf4896a2d3666200741d817ee1dac661652b9a1741ea966d5ed7cbc4c76217a; - d637a72affa4112bbccd2878208ce34fae442e97175e1b39f43c00b14d312a2b - 76209f8b1f152ba7e1e6294f707831021eb2ac03872ed3774ab8fc5e6a0e864f - 0x00000000 - d637a72affa4112bbccd2878208ce34fae442e97175e1b39f43c00b14d312a2b - 76209f8b1f152ba7e1e6294f707831021eb2ac03872ed3774ab8fc5e6a0e864f; - 12f3bd417fb3860b2a4fd04eb1c51c558a4c5a3dcc1ac457654a45a3cd45b0d4 - 46f802836c7bde099775f3fb4f5f6345364a7e158bae9e16c4c99aee0cfa5e42 - 0xffffffff - 46f802836c7bde099775f3fb4f5f6345364a7e158bae9e16c4c99aee0cfa5e42 - 25f3bd417fb3860b2a4fd04eb1c51c558a4c5a3dcc1ac457654a45a3cd45b054; - bf1809201f83a34cb07aa2e2372516631ba0513e600956e6702903e9084770c4 - 414bbc77d13d7b4e706acc07406e8d624f2485463f9948d81b72268c1e086a14 - 0xffffffff - 414bbc77d13d7b4e706acc07406e8d624f2485463f9948d81b72268c1e086a14 - d21809201f83a34cb07aa2e2372516631ba0513e600956e6702903e908477044; - bb8703f2ddaaaaa6ad19219684b1bde576b38bbe9065178b24c1bc55563fe525 - 1cb3ca7846a3c584b1bc05b25ee91d4779ab9ac64ecef0fcbaea8d311b55d618 - 0xffffffff - 1cb3ca7846a3c584b1bc05b25ee91d4779ab9ac64ecef0fcbaea8d311b55d618 - bb8703f2ddaaaaa6ad19219684b1bde576b38bbe9065178b24c1bc55563fe525; - a07c7110c32e362864a42cd2f371ff420bfd442d291cc15ec079d642b5c85bdf - 497fa7867fcd0617c4cd765aa6f46b89390744b5b57d11ab732153e075fcb607 - 0xffffffff - 497fa7867fcd0617c4cd765aa6f46b89390744b5b57d11ab732153e075fcb607 - b37c7110c32e362864a42cd2f371ff420bfd442d291cc15ec079d642b5c85b5f; - 10fddb7f48015b394512257da026938b67f65dd0a84dace51417d68da003a913 - ebd6706b7cd2ee2d97848ee1adaa990d8ddbfad48e43f51d7ef843fa7597410c - 0xffffffff - ebd6706b7cd2ee2d97848ee1adaa990d8ddbfad48e43f51d7ef843fa7597410c - 10fddb7f48015b394512257da026938b67f65dd0a84dace51417d68da003a913; - 1dd835e2173b936a91da37b3aa11e848e4497964a9a78ea929a19105eb981a24 - 3e6f1ab7d5c460dfb7ad1926c60b64a8dd48ed0115b0655a6d8619666b8c8dde - 0xffffffff - 516f1ab7d5c460dfb7ad1926c60b64a8dd48ed0115b0655a6d8619666b8c8d5e - 1dd835e2173b936a91da37b3aa11e848e4497964a9a78ea929a19105eb981a24; - c4541b1380e796a333d88affdccb4d2bc68bc5a1b3890ef2fc1a2c38dbcac725 - 6f6338ad8dc0562bc02e307743b81013ffff6c135fdf8603f9956b7f94eb55fa - 0xffffffff - 826338ad8dc0562bc02e307743b81013ffff6c135fdf8603f9956b7f94eb557a - c4541b1380e796a333d88affdccb4d2bc68bc5a1b3890ef2fc1a2c38dbcac725; - d71f16494f041d1547e5dd9ed539e6b9c1506cebb66f6424e6c7aaf6d0ace080 - 78c1e6cc0b6f64e161def3b2ede7465f21f6afe61299e9a3c52b1a7a080b9b26 - 0x00000000 - ea1f16494f041d1547e5dd9ed539e6b9c1506cebb66f6424e6c7aaf6d0ace000 - 78c1e6cc0b6f64e161def3b2ede7465f21f6afe61299e9a3c52b1a7a080b9b26; - 4d90838ab9cc0a79f4e2aa6a860bf8cfbce5f834aab428d4a06f8ef4a2da582a - 53124b302e7675ea5784e2e7d9fdecb38d9c8be158312dd81c51757bafb79b42 - 0x00000000 - 4d90838ab9cc0a79f4e2aa6a860bf8cfbce5f834aab428d4a06f8ef4a2da582a - 53124b302e7675ea5784e2e7d9fdecb38d9c8be158312dd81c51757bafb79b42; - c8e764092ea695b0dd8f0ecbca5a4e02096c821b0f5cd57de8e3e50d8b2a40db - db7fb38dfede5259a584dbcc697f259ce380110636e301acb308bf687449110e - 0x00000000 - dbe764092ea695b0dd8f0ecbca5a4e02096c821b0f5cd57de8e3e50d8b2a405b - db7fb38dfede5259a584dbcc697f259ce380110636e301acb308bf687449110e; - 34cf8e55b3d2494362a87a24907fbdab61cb4f452ef5a889a1aa40a22be6d976 - 679c6d6f6dca1b71bb098e3854c63ffb8ddb76f1a1cb246ce956fd71d6477c20 - 0x00000000 - 34cf8e55b3d2494362a87a24907fbdab61cb4f452ef5a889a1aa40a22be6d976 - 679c6d6f6dca1b71bb098e3854c63ffb8ddb76f1a1cb246ce956fd71d6477c20; - 9638ab322ced065068f98597cc61fc2bd846b5849dc39a881209b8efcbc95eec - 32922ff2b62e968417225b765f2787387c8a42fcab1dbec3815298f53813a8cd - 0xffffffff - 45922ff2b62e968417225b765f2787387c8a42fcab1dbec3815298f53813a84d - a938ab322ced065068f98597cc61fc2bd846b5849dc39a881209b8efcbc95e6c; -} - -mulconst { - 8d517a8804d934ae93388e1d59748c3c22866d7be6cec58a357ec43f6dd029db -319312 - 3f2fea85c9195f2246f4f6fd2e8d5de95c5065edbea45a174bc0d1ef3db4aa54; - 1b5d6a6c9cdd0dabd126e5f5ee2513f3d27c56dd3aad89c882fe9fd2d38a93b9 499342 - dd310555966ebe7f409dcce2933f91af8e14c8909f78e4f113606789dd7f504b; - 9e03b44e93743e0cf5768f65bd3c0f255e001de330d5e1a863d6e4dbb11748a9 -284189 - 6e8c7f8d0f1476cf2603f5702fe8e8bba5c01e86b6e008ac72987fdd6721183c; - 9cc65e302736aab9bf02dd451c216ac3dd2066af299d7f6bb361eb3b36777f74 -15738 - 8c067e5dccdafaf56301050be17b8895c07e7f13572bbc5ce1af8b5be043d91b; - 7f36ff91ed165c6ee44aca261dc09e3e124c2ed8167064c20d9b84fa226e2555 423857 - dc7415db1ab5e5a5658d089ced49bf97718bccc55e2f15b83a28157cbe47e559; - e8852c80db69c7e55d476ed00ca7c0735052f7f72f81198a57236feb89a5903c -140934 - 4923ee40bb01314c2fe9f2f87d0743823311b2d9265219eb7a6de5fdfd09a308; - 505ef65d294b77e260757bc867199c4b0922b5022dfd6a1fe7478ea27ec102c5 -307893 - b14d72c991a0bfc22b1b95934bbe589b6a4a1f9c76a89d7012f8cb03379a8844; - e410c260dc8c1838f3e9658ae586425039b373ee2ab88c750a51853b012af0af 471420 - 42ae337a920ee1b83768cbf0750f524cf1f9e98b99f195e869785f90a2356756; - e2d181914b54175190462d11402717f42efa37967b2fe0bc4433fd4c862fd646 492178 - 4c6e1ba6896d2d661fbf99b77f63e3095d3341f04bf258dc3e4f51e39c68f576; - 9cdda0d7da106ef5cfb34774f48308b64953e92869dab0ba804927080509d8a2 -312149 - 4e75e56793563268480efaf6232ad702bc5aef6246bd44e3499ff437810b523b; - 9dac4442858b8dcc324464911e6f23ed046e42612e8105dc3aa2b9eccea15dc8 -88818 - ce52a0897600a05383df0a0b99a451f0d5568146b4323392fc164153715ecb0a; - c9f92ceffa7027ffa71e64b714c36b28a6a18c3608f8170d11d51acbee3c62ba -259755 - 89582517069925572219b2eec2a25029e8e1c78772ca8c50bf23220d02740763; - 8f8bcf28f4920465680c8e15befba4ebd23c1e27b71c224c98461f69caf76eb1 -430350 - e96b93f0aab6ca70f7d2c1121110efc320aff34e1ec693d7bf17bce1a756d622; - 6f4d413a27388fe84a2585e809927bd470ba1b0dc749ae6e2dfa100617a5a7db 11486 - 1cf1f5bd0770d949ee36df858e5842805d121722de30d2ef6bc2b82d021fc14b; - e1d05a072d1ab70d895969271f44b7c9d1654171836cf234724d2f90434c04e6 8057 - e32b3c792cd3b6a770eaa2627ff8de8895873d73d734b961646fbce0643a443d; - d8564ee3ff02c80f0bf3e9cdfce42cd8ac1012ad8ea74f8c0f5754b5775a8de5 -304373 - 884266ea43a6a9b72d113b437dae63c664ef53884c893212fd864412f4e5e457; - bf66769ee0cf873764524e760ee654e8d5090aa774f2e96144d945f8da37af19 -159091 - d7438999b3bdb99a46e2f3dc8492cbaf52b0a19c651cc382c384940861bccb6b; - 72b7d02b1fe23adea87696864c0a9f0466db85e39db397f0eb428a50e277aa2a -521654 - a611bd153336e178a7f3d912adc2fb39b342132458faeedbdb0a35973efae23e; - ff5c39d4b7fff86810a7a3b14a58bc01e6ecf062116adaa78dac0d1bd3f6039b -140759 - eb9e32bf7d027cda198048da50aa79a11bc99f3b37a219a2104c78f4affb584f; - a6f1f7f30e3f9e5467f180f92d2c94165fd9427d0c7d383b9077ca9a7e50dac5 -317637 - 56a32847c50bc9609db9796e1650fbe97524aacea746d3cf285f0f2fced01a49; -} - -mul { - ## Easy multiplication. - 0500000c00003800006000004000000009000006000048000090000040000000 - 070000180000200000e00000800200000400000c000030000090000080020000 - de200094610090df0020fe0180270700650d00dc2a00f84100e0340040570000; - - ## Random tests. - adcc6f10734dae2273304a6aa493ee8f96e05f2402341c0d997dce58ea57ff6f - df3c8d5bb6380fa278d4ff2994c7865bcc146596d3c3126242f0dc3509b57449 - 5ee2615b75a40367ced4ed4bf1578d13e7afa4d415f38f802b7e7b374365b627; - 054bc4d5e9b78b068fd20645eeb1f03aef2e89a1f56cb50e5f1170a86529526a - f976ffa1d1b4a33d0fd866528897cea3eaffdc75e31aa65450a62ff765fe7985 - 0210280745f6c29a04433f07f880bfd2eddd758d82996e79c65de817c30e7309; - e361c6fedbbe081b7cd683d23a2bf0ac889806be7230b56d9398959713a300ec - c8121e53d78c2e9ba2ba7f51b7cb15cec970a63b4a642ac470aa1f2145f07bd0 - b48bb1c7ddd26cd9e5a2cb73bb3885dbe4a47e03886d4dfd59e5729d544d566a; - 463158a2077f931567d45e19deb4454a2ae77045db70a2c078e160ebdb74fd94 - 3f311e3f8d225016448fbce3fbfbe84002736e3b0d5a90f57d705ede8706008f - 44cd97e25c20ae2fe2ef4f2630981a1fe54c79ebd904bc40e39d9fa615ffa76c; - 1c73fca52556e01204d4b957a01d1049f2247c8666d90c1d3703cff16a38c8bf - e9afa0cc85577ec7eb1ac66d87260d5f3659936ff88cde8bd1c3fa1d499e8bcb - 0979a8baf734c86a4f57ae400b7790c4985fba3088cb1b265dfc7a66c794121b; - 6e2bab74e427b1a44f0cb181f9dedd6fed43cfd395d3708c4ae8fd2137215eb6 - ef400834f2dad8763a1a5a58a37d1b36a78873860e4dac808d3166f13724942c - 0d481adbce7bd82ebc5a3e5ed7a492e78a032ebf211a5bd2371c528c77954936; - cb3575b41d9521da5c85c6438af14903a8d6d9c3857aa8e101e5295fb277de7b - 9f76715d2ae3c8ca182406553d3481fc36d67727ca2d51f5db37940aa3208d8d - 0b2fa619265bd424b9e20d38bf4552ad63de8ab552166080d099edea5fbadf7f; - abd66cf3b20dc4c5a866f1a3b965f794a726f96dd00f576d16ead66eea3a1177 - 97f70fc92e0cda0e010f2a9d7608c33db954af18bc18ad55bf66e7d91ae31abd - dcbb2cf34274971ef030827865b093a00761de3da90e46f00e18d0fd934a2b7f; - 3b3c96ff9be8e17e0a0d3979ea5e5623fff5fa18914151abf79fe66639beef06 - 1d29c361677805f1dd2b839e025e56208a10c0b8d9f2a8c490b0a892c0e27080 - 0050873016bc67023d0c479fffa56a5a70512f9864d00b0a3e951f1e85c8b412; - b263d4a71b6d963e0a972819e5e5805b9522f142d3c0ff2738c51cce31e9f0d5 - 64f3fbcff2195c297292df3e1cf900aae457e09864c5a6248ea21ef8efd557d9 - 7e6f6f511cbf2743c0fc1c6431243908606cb257d20f8a8a0885e6ecd000e811; - 0df0497e1e01dbcc4a48d4865127d9cc31a9a0a56e90cc31619e65c1521b2369 - 9277f0c6a5bcd7c7ed8dcf7182795f67a12e856b126d09966689834c43aada47 - 798d270ae34aa2452694b4ff74049a6a5169d71c85bd1a9ac59625e9298cdf1b; - 1dc64bef2189eb5349f5a8983c1854a40141a5390ea4bf8535a15aa71d0289b7 - fb59dc9b08f9163881b10020ce040da296ed8c1a9a935c27ca0047a4d7f6342b - 9fc23104cefd3014a469e6d3a0631338eaf91e24994ecd50bfc0b4547317317e; - 975b108909e87803af98af9425d2a982865b6cc9c144985b32fe5bb842702e24 - a69e9130dc40be50e827dc50dac05bf900946cf67ec35f1bb1705001314e4fcb - 12d042e50d0cff7b43a5ede61ce827a99619bf84995d488fe9eb56a8de769164; - 39c0db5a4b161c368b0f71c7e8ef97dddc444e4a33181e0743519f2a879ae04f - d3cc45ff509ed45998bd5f218408ad51f7457b35e8ad69d5431f174047d7c6e5 - 96b877604f52782ff2a5b1a12d7db642371ca993b648c4971cbf593213503219; - f8c6715e4a327cbbdbb08d74121619abc73dc421d7267029e39b50c1510d2045 - 63870a83cad4c1c64195ae7b92f3b19c830f35f1a3186815565d846c787c7ffc - 286a0b8c6681a7b79a5f85426fb60819b7bd349e93c1e11943c41c8dfd57d00f; - 49c9bcaf5434b8205a348df290a96da27df084f34047efbf91cf544057a50bde - 54269f8b23c05b94c9c1cd74eae88d9227af12a6fb337548eb93c2a88a75a8a5 - 1e3dcab5d7361f00e70198b52e8fb6d1fba74abd79d99480527f6711b21b833b; - c7212b43ff0d10fc52d3a2a7e15bb9cf53856f7ce33b79df89e1d13f95a94511 - 5213ec20bd054491a5485f665075835da609ad4f3dc005744f061480862ee602 - e136339fa01067c6c0823a7ebe2f84d917600e244a9883191900bb95a3b59764; - a15d62c6308448f1f70602f43be1825696d228eb170bed55322a21d2b1afa915 - 58afe65bc8adbe22807026aa1b0d68af330bca268fdc054406aa41c820960e71 - 996c597e0a024c2ff0ffe289d8c7270e4ea1d38e294d7210eddeb2c0725a1305; - ea233ae033ca93034bc8fd8ea3c0625bbb15b00265264fdd61f62cc808b505fe - 09e12ef9b3426991f7119c2e8349278342ed0072317c4ec7ab24561b61396b39 - 1fd72191fe9f00b0cca6a635d14904bd0c1e0ccd1275e84ad0b7bde134866e2a; - fe1fd3da05524af4ccd538f1d2ede09582101fc2a47c2e63758a546bed6cc5ec - 523346406ef3df6ac9a455d0d2e7f732ad01c88245b07a888cc21c40fce11a76 - de6cac8fdc878d9c4eda6b78f8b629ecf776980e49fed56bab936fc03924f44e; -} - -sqr { - 4dc87ad85abe8938634492ce2ea10bf48dc4aa2fa37a6a0fde3e5a01e90dde2b - 346297c756d77b8ea312ddc455223f4577aea2a2e8d944cb24adb487de143b46; - a33aed91165d7fd13a543760d3915c1b5d411a21895cde81b2f3640b87550cc9 - f923e49da9d5f45e23a782f911fac1a6c2e67cbbc7b03ee4675a0c5fbec03641; - a1406e453db6c92ef808295d1919c5bb2491c0ce6d5326d276c57e57943e0acc - 18425bbd92149991c4545e65495af0e6372289e9a32649c127122243204bdd73; - 70a56b8484234ed002a68c8d535a4e527a61c360f7d4ee5b4970c8ace1e12de0 - bed1c435139f151d0650577e03c32428f63cdb7bc1920110b5fdbb27f08cb200; - 86c3236a6194f1585b4dbeb09d0247fb7d3ae08063ccf9fc4fde70fc23735710 - 9b6509acadd5d31c4c843e91cec78be00aec4fdf7d86132965bd6f62f078f711; - 0e5e83c51a8c091673425c38785e0aa1d74c7261a035a891bf734cca8c8a3db3 - 4efe5029e99438835a8a45d0180b8de357eac82ba9dd8e127baac0d758dfca1d; - 31c39a5afc33f8a8d3c570b9dc5389bea6fdaaeeb44cd7524f6c445b9583a34c - 359b7c8791cc87aa8b3c799c9d4d7e1f4062a4f64436d8c01071597e8c262127; - 5a06203c15d6c1db6ea0fcf468a1e3f09d68c4a0f64c3d7e30e70290545e708e - 07f8b435ea322bedf613458b1eb420f1d6bc96741d69695899bd40f7eca6f72a; - b1973433646474167b791b326827641260fb33d6a2c96d4e963a6b091f824505 - 52a62396dbbceead62912f8adfed2707fc25edb51aac19b2a274c246f1209f26; - 96b157d71e107168fac206dd63007f10f4ae1225b0761c470ee18ecdb4fff20b - 84ba2a84b156437cdcc39ecc8b1ad01bba934d8dfb7d504b9f2442db0ad01167; - 6167d77675e19785960c28df551b458e41dfd0dfe5e56e785b7367997d5eb0a6 - 79a558436af4310d3eaee93f9a7cab72bd817fdf59d267e2c530ba8d667a005c; - fb4b2ab08db932ce10dd62639aabbb266f9ce775fb5a5e0875864f18a3ee506c - a6013661f2f0ab875739836039bff6bff4c993aefdda43dccecf4c404b9a612a; - ea26bcf0bfc3e15d4df7ddbcac8b5b9e9a7215d74196d77c9e0524e861c6aeb4 - 113e06861e3d338618695f4713464cea536c8019da77ff0dd9946f3b860df062; - b67b1ffffec757ef147e86cf60898c5dac515f080f43f4e120017caab4eee5ee - 7d9748a1ff6ca9cdebeb3dd6668522767afb9ebf1c680fe7fb3f5848f7222036; - c122016f17f12e53f9ac031719fe428c826217b2b757ae44f2f33d1b8b1bb553 - dc068d032b97c98eea6dd6c8bc42e9a0a6250c81a36a8f64615489e191287c72; - 1266ff0654c08e6183cd6c3cc760cc5c88d1f49b918f2f8f587b3edd4adea513 - f07f17fadb2e2dbd282d296fe5a15cc5c2baf6b45f5fd5dc4692f252039bc862; - 4c4dd9c6e46fb2c096388583f2a0c969245452b23f16ea43e15064c45357ccef - 5127fd4415a84115997b8b3ebe88a590efde9f8b53a43e86b1a4d60782c91025; - 095d149c2616212e5f770f133e719d285a8bc888414271296684e732feb5473f - d8038bee551cac14d1c610bbc0960d943b01526072c589bc913ab51fd47bc848; - ad55f9f916d62bb13ceb1461b99e82d76b860c084ca408dd4a18f154b907754a - e5c86ee6350c9ab736229f3f53e2ab852641bb8a62fdda609444df377e9ca04a; - 2e4976f45acc671e38add93aa6a89669cdc9874975879b3134dd37c633c9eb14 - c6513f1a11346d33b05ad65eca13f11125cf70bdcdd6e666a8a7b9c5b6098429; -} - -inv { - 344ff33a2bc801f861bd13575797da35352c8164808d27f51ea7ca46931b2b1f - 07f678dfeef071b038d692bf825cb4e75bc1934bd3a6e3dfea99e78bdaeecf3a; - 670097e2fbbecf6516e949d98f6d722d3f732c33bfb4e62512f9d28d94546b64 - b2f5cbcd7d8c996ed33a813b1aa39c36f5826b436867bd89b4ce43a156c1e96b; - 234f3bd8760cdc8ae7fac9457da418cd082e42906ffe59a13e52185a7845e61c - 7488ff9231e4819684148e16ebc25440732ffe7d211eb3d3263db1af9f1d0513; - 22a39a35b1cabc6dfecd1b898593070f0c81bbd04b4b20f43a9c7c14b5dfe967 - 892024fdbc8937b9b3aef794f57b8ed8517510b6de3f6088987b1310c1dc7932; - d850c118c69198268826d05650958c6bed55b181090cf1c96493ecc4635a913f - 7aeae1b0dc5211f374872e78da8f225325f3f33f9c42bfdeff25d425dff7710f; - 33ccdc0e39f7cd0a61782c87ac089eb7bbcabce4dd222f05088d3d6332efe959 - 668f87e23239e965c80740d4daa9c913609388f291c11f950684f45e689a061d; - 7c06f93b2f66001c74073b8ba7536049738e89b0a0d859a8a73710de3fadcf79 - 52df0aa24bb4a7474e6ed9852ba542c1f4c5219372a7b5d60988890e2955491e; - 9a0ce9ff4026bd58abcf8a128dbc55a19c446005834a143634452821d5f9f0ee - 79eaa93b6287705c0ba564c31bab1854c7f4354845be065c4bf94d38a7a8b421; - a13a127490bd3443fdba99baf61d113f3aadd6966c9732cd16348f9fbed32e0e - 67290b25e6bd7328dd804309a6203c02a75657f593c7e66e48c9192524e5b87b; - 35f7ac3eaa36c4ed338388fe7eda61cf237eff6ddc0847cb0c95255bbaef8ddc - 4950601d2cfe75eb9c4524e2f40f404fe82d0014c916dc43d9416cd2e274992d; - 8a058593035986da3a19e63dacaf40fb3db4cf382205fc4e4802e0ff0c61c8d6 - 6a23b743dc2fa4a4132780cf6edfed4c219760f3b31343b08710ea18d2c0fc43; - a10d03234e700ec92270b6105fdb787d8edd3f960fdd78ea2e169f49dc708d45 - 101dad1720604d0b093831baaa97fd0701ce773b9c1be1db0403533ad4376c0a; - 52d3b9e030a5ed574f7f9489c47e73f78ef88a39b570045f9ef73c9a3e65f425 - 83da3e088dbc9a3cbe06496c5a52edc8d7abcbb8a0f839361762137b119d961a; - 9928b5f14ec80a036479d7b08c128e601db880daebef36adde6fbd1f50f82629 - 8dcaa9a2439b77cbe44928ac2877e09755c505f58df4d0ffb9b23fc256b12779; - 5a956523956f8ace6166ea6cb3c7421f8d1142d26084a81d615f00d578e03448 - 658a3ee24ec5b5f1d2d12614e535247c9f2f259131b00f654e09b4517c63ea09; - 157492cd38a07802351ca0d1a5615d5c5f254692acce930fb6be351e9a52f088 - 32fec1eab85ddf8d27a437876e7f5a07f012b02e7971869811c3c31230204164; - 2d07c109c332847567621ef4338e149b99c5bc3bf6e50943695da7fed5d8141e - a81472d28a8235bff43ad5cc012d52e95ece3dbc5ba2962dc54cf9e7f81bee04; - 7e172f6c03415e83d4671e0191151d49e5257651ba73848254e68fad0a095c50 - 1a8efdc57ae9d39ffa64afbc5d2dc1f25a29d365ac3dee0d8529977c14aa4415; - 1934546e37b0bac80319fa7f2f86c18e83de8da830b9d0b5019c26768974eda4 - ffe55479771f20518d8fc6491055368b5dcce9b4e193d19897f1e116b9cdf946; - 90324ccfe0e34e9b08db1862be3bc17798a8581ee097be76545e3bf9d586a2e6 - 0f5ccf4920d617c9b4f7fe6e2c9e95e89b5516555d5e3f5f9900485451d7425f; -} - -quosqrt { - 18798551568191dbfe6bcacf95bf4bf00290de4c773a1d4233d1eae272b3085b - 2ee52110807ab6e31e0ed7b4de818d6474b514c63c99206e58a6df38e149123f - 3819accb91d97a3f4dbca732f19723fc772a19b3eb4d307acad706cc7c7e1c1f - b5e653346e2685c0b24358cd0e68dc0388d5e64c14b2cf853528f9338381e360; - 8671a0ecb7344f2e44fc9066aeb42661e848417e8c51b353680573830857d90f - 9c4cfb1aa650924ceaf3e23b260d02b7d8b7dd4445360cad0bd4270428f55292 - "" ""; - bb0d27e1743f444e2f612c2ff575c6c6663f01869eaa8666774b8baa59b2a714 - 2fecb156c393d27d7b9a5e4cc2b57cb5524d5b945e92c5b4bdccdd6d00e684c6 - "" ""; - 59af963f7245901807a46a59d4e49bab5b1fdf3001f63ef4e600ef8150d0e13a - b5ac3372ca5435577c416ba46a57879b0ca1df29057c540cac4edacc507b5e23 - "" ""; - a7b8659775a53e1fa315066be6a37a3f645d782cb69ec6b4f27fcf4daed3d82e - 4550c4697a5d29d1a97b50ea65e98ec839567a3fc556ec3790b016c24b867d89 - a190875f536f94ae2af8aae90bf0afabed437b36cf640d85529b150155eed53e - 4c6f78a0ac906b51d5075516f40f505412bc84c9309bf27aad64eafeaa112a41; - 7163512100699c32d5fadbe3583f2f6f314c347f1e66c434b15ac06a5733f3ed - 2806d76598a43c24820daaf87afa5a9a4d414e5d8f51993f1b01166bb5479c27 - 01d5d023a6c5f7ec1d5df3179bb240e3003a9e3be8ad4e154c6e8f7cb7af6536 - ec2a2fdc593a0813e2a20ce8644dbf1cffc561c41752b1eab391708348509a49; - e950533666a4a1edc3dae30637d6b005e34b614fe75555be0e1759def06a2aee - ac5a603347a585ca19eba141b1dd1b8833855e9807776627e8c9f92001a4b9b0 - "" ""; - d3c5ccb02442548901b3ffa2ed5564735b0b041386fd38e6c40844dc9183006e - 5e6f23ccef94660e569bc42093d2b862ca605b81d64bb3589331d015082b4996 - d7d578a72f1ea2dcacd0a96be285e9635230dc297fa7f6e1f2b9754e2d29190c - 162a8758d0e15d23532f56941d7a169cadcf23d68058091e0d468ab1d2d6e673; - 37cad075017c111f99135be6a0f553535d56153cef8839eee1e70614d65df1c2 - e5f9944a377be3ab64daccfc9e711f4aa522c68a80efd0a70c72cdd4507014b7 - "" ""; - 85dedba748f478537d016f20b9871e830e513514fbd27141aa54ca77b2a673be - 950bc6fb51f6d8c36b7ddc8cb28d9efd498690a46c57888b279de0e549e84c52 - fb7871031556b171a25dfd0483f0e2ed8d24a8acc2d9fc201f42f0b892fd541a - f2868efceaa94e8e5da202fb7c0f1d1272db57533d2603dfe0bd0f476d02ab65; - d70f399a983c6ad48acca796d9106c5e7681f34bdf34248f6dc54620282bb327 - cad23bcd1fb96331bc8139f2a8f21d24492e56a7b80e343a7002acc96a739454 - ff70c5bffe08911fb5522b21beecfd80fb018f0afef24fe85cfb7e4a5024960a - ee8e3a4001f76ee04aadd4de4113027f04fe70f5010db017a30481b5afdb6975; - 71ee96ced0b50bc560f2477a88ea2447573490f71850f084ae0b318cafd8a75f - 15c61eefd2c05d72fb07e44a006dfe314d8797f978bab1fe9f9276bcc82b542a - "" ""; - c27a9f169b8096308f313ab5a521886084f03ec6d9e8b30e4773d0a3ab1a7c67 - a7ca0e7fc5566dfc3790a3de164ef26d6452715db428994d438e79f65034d174 - 129427bd4c2195fac5a0da4c52ff634c697f18c3b02d0e7aad45a64d03b6e922 - db6bd842b3de6a053a5f25b3ad009cb39680e73c4fd2f18552ba59b2fc49165d; - dd73476aeab865af0775723ebd2128ca71621b1d95231813c3d3cb32b805f418 - dc6621f2ba82deb8272243baa5d2e177a60b1b780daa3ba081040e05b1d1b2f9 - 32ae54f7a7dfa101bad00f723898d29a7307454f86cd1197c44b07d1b997fa1f - bb51ab0858205efe452ff08dc7672d658cf8bab07932ee683bb4f82e46680560; - 3a3ee482bf7075fa38780616603133ecea7b56acab59d96ebf7192e21c49a806 - b7e6d647792961137dadce55ce69634379338bbda45fbef9d56be52620738d06 - 122b696683c2d1f3feedaf6166037ddbd7281e0c4c875724177f240b54e0dc22 - dbd496997c3d2e0c0112509e99fc822428d7e1f3b378a8dbe880dbf4ab1f235d; - 71f31797a8a36123e4a0b173ee4bc5a04d7799d1eba246df51cf943aeba0270c - 7340069440d6c72b4536018eec373f50a1142c9e79de8a5396f994e53c64ab18 - "" ""; - 0d2a6a9de4d52289cc724840670abcc5a4ee04f1197bd1d230689431b01afce0 - 21457f6784da81822df90f09b44782bd50a12c4fb378091cd33b177c734e0728 - 2b272304b3cca59e26431d91118a95c965bd542191c7cef760b085673e96a432 - c2d8dcfb4c335a61d9bce26eee756a369a42abde6e3831089f4f7a98c1695b4d; - 288b09090258a71747c1a08a51b0894a0c096f5b88ee38ea56a3aaefc1afa0f5 - a7f6391e06b8972b18e899753bf3853270cae7971774041fa9bf09a55349f950 - "" ""; - e912e39e2199c3980c5fe3cac6d8bed394367f28213524f006a9b2c0cce4a6dc - e6b4a592e37fb5d3af73c486cc211a57d4077c093a161276dcb6eb44303d3ec6 - "" ""; - ec6785be59b890e07176c09195430b7f5daee0b0898ee744e578ac25873012b6 - b3cd2df2c2531beeca882607d73f38403d8ff384f99be1ce582536bc3d4bfcd1 - "" ""; -} - -sub-mulc-add-sub-mul { - ## A very basic smoke-test. - 03 01 5 01 07 02 37; - - ## Stress the bounds. - 000000feffff030000f0ffffdfffff7f000000ffffff03000008ffff1f000040 00 - 0xfffff - 000000feffff030000f0ffffdfffff7f000000ffffff03000008ffff1f000040 - 000000feffff030000f0ffffdfffff7f000000ffffff03000008ffff1f000040 00 - 00000cf2ffdf4400a09a000079fdffea040098edffa73b024072ffbfe0feff65; - - ## Random tests. - 6f0dc2547ad77f7b3da324876e63c724c1f69cb2bc70ff960f1594f90202e17f - 23a2d45c26880166516e6831ab5070dd2247992418ad7cc41155a9362744f763 - 4783 - e145b5f91b683918d1efe6193de27909bf9051b0157acfa458bc3f63e5272de5 - e694fc475a442bd72cbbf11206474e3169fa74ad453aec3034c1dcc1f1dfbce0 - f9b4f1ac9369241a302f874305cd2d2fba362b5735d36d3e072c7198d7dd4005 - 08518c9f52236272202869bf7cb549c667f6a27d1c4f18ab58605d63821a6c61; - f1b3d663fb9458ba8e4521e8e2c976fafc8936433b62e316c6dcff794b1ac8d0 - 2185dd6948ef2339c9a43518dd02eac6518852d1c35858dbdf5c1acf1d995884 - -128133 - d7a628aa59d409b755a1ff0d76f37ae8e4a73d47375940c61351074f3c42ad2a - 4a353e9e7e9a0700ab2c043cc05f9795cc267e001b64799ca1849f024a42dfd7 - dbef6513fba5ca19c545b162718eeba960b0930b8ce99c3edac5facf5fddf4f2 - 9dbfe69897a273171ab4a697f88a0d4b420a3ada7a7f9e67d0ba871e2097026d; - e8624dbe04a1b19102019d7fd9e06fe502764afb92330d03693279e872e84f81 - 8da8b04024ff708a8b5fa31a6a654fc31d3748f74a897898aa42c2bb65494586 - -118148 - 83f63df59ce4b3161427b932ecbd7796bd162b553b70bbfef8a990ba6f20c23e - 9d896d69ec478456fb6cad67774c6e3e0e313aadc0564d759380981fb12dc3b8 - 0e8799aa8de1b1ac4aeae4d1e8cd5936c66b8a0a60c8d17ec23bc9c9f94421ea - 2221a87687c127b352e077bf7e975c83c667c8ce603e9d9fa5e02b195c7ad873; - 2527a8ab98898038e9e132a1bc8349a33e2c2f6ec8b6c15b06410177297d30fb - 71cdbe058a0357295dd5134fb95a630055f39d9bd8fa0c759b1b70fbef6147d0 - -14780 - 0fe111e19ddf5d11d40b584a31888aea4a388540b86d14b962a1a7135114d5b3 - a6386eeff2764007a570ba7e82a214667c2949a793fa0a52b7665c09285c6661 - a7557aaa000c8840e08163b7eec08bf24ba275a35d85bfd7813aaafcc22715c8 - 867491333fc048b229ddb4740b1fe6dca1feebf1d40660814feeb1fce97fca12; - fe07ffcd6b14f75efd74ff983e8e5c20f379b0c78907f0e453753b457fb53159 - 617f2f7c1153eaea3ccae7dfb07fbe804b2cb5c8205d657c3106b5a60100cafc - -128312 - a0af624a3f54278e2f7cc77f5d0f10750179bb18e07da059feb0bc98fb1d688f - ce432859e6d7e691ba9b44d467e8a5f1a97979facd2d3c7deec46e121193133b - d60050fad0f5c4b2e042141e4f7a418d3e8a8a308acc96651728f363ee793628 - b9e4e8873e006d41104b1cd6a32282fa2b94ade000dd57dee6dd506cceb34c34; - b46e84be433f9e4f43ffa2f1f5200013953d820d292e3af978c54401a252111c - cb7cec0c48efa4e0e54f05ac18574d5f67bf1a1193d6d58f42183abc9f5bdd49 - -3288 - 18603c0562c4d893a699fa6258e2de57e1cafd3e8ad756806d09db0c1ac9f86c - 0854368c6b459ba6fcaa95db92605c9d791bf4dcc57bfda2ef318b48f7521d73 - 0c83d0b2d331ccc62bbcd2d2771b18bc0b909a3bbebcdcb99020952672f050d4 - d54073b190601f1cc36c25109a5b44f04b6c2240c268bc71cb983d3dfb25cd64; - 1f490365c3b82416fd3866a42a03f3bd643844e0d0cbebb66af54aa35de3efa4 - dc805758c7e714a2acbc1e467520ecc3b9d23ce5133fe79e377e6d4520cd5196 - -129141 - 1a53a3728ef3587085d0b530be8ae95e367927f9ac3b7126445d32b46f3abfad - 0af6ce5107ca06fdfe732d11161b197830a963ec667065c5293bbdf843e23672 - 5bbfb655a175dcf7a4f4fc886a03e3d99cddbd34524c3cd2fb13b793bb2132be - 7e5576020e7bac35c7f5b3dc6b60b2c1cca55f6c98141682efb4737963d0307e; - 09e03f5d67a92cf076740e4261833f244b60da6d02cb42278e2ed9183b6eba3a - 5a8b665434e91158559cfecf1d43d562c307518a3ce889165b406b1aae38a674 - -13299 - 16e0d405bc40f2075f5dd901769def19f15759faef9a5fb6356b94c5c48be3e0 - 101da726c0dfd102c8eb2178640054248225a6fcfac1bab28a09b59cf38703d6 - f268d102402d31a33e52a941a06c64a30a721ed55184edfcfcd85db6fe3db676 - 24fc9112ce6d3d70e8c245f9e2c883290384462065a5a1ab5821b9cf9d61953b; - f86ba345a367c676d99450d4893ef4033201c8ddbb631c4658e4ed24ece98749 - a3c51a17107327742f44cc2e265482522cf39b6bcbff919bcf99fc033d76348f - -88039 - 5dcbe0be5f9f80b46d2e651504b10a3e481257a4bfacf40d8ccacea9d73dc2ea - 2ac88350fbffcbc743d36fe45c80a70a8cbe88be36759943c8e124163e432dec - f54685e704df0e499e495b3b77e64aa0ec0c9fc0bb18ed456a412ac6079fe9d2 - 3e7c00ea9ee49825f5fbb9b704dc720b062d8e08ee8dd410f3d34d255602b56b; - 1cd810875f48ef4c71ecb0997acfa31249ebcc9280e7c2f741038a0529f653d3 - ba2e564cae8cdc2bea40d64b5598493ac2b11902d91b5aec7a0e4a8649aa7ab2 - -77488 - ca4929fb0fed99fd9dca7a21275dbd97185900d4eb362eb09bcb5ce7098aaaa2 - 89b395b440fab27d3b32e0740caac3ce38affbd80b2f8f7b6709294d6770873e - d2cd5ac1ea7b0e1f45bd3cc64b651518dcdf9f25078de7cc4970bf54976a0c8d - 06ea5e15853bb29db5cfccd62db2e64067c90a97eab43039cacf4ee639ffe979; - 9960c3131e513fba3241b1f9bdf44fdbe06c43d9cda9e05fdb451eda3e8df394 - 4c5f72392dddd1b8e84db5bfc2db04985fe3d1226a470c851a489f98d954e6ec - -33449 - 04eacb794c87c19087b793a0e2d187cc7e0b07d265fd6cc46946780d2ab83810 - 414db559bd22f12717b431310c1063534de5e627e983f4967b2fb38f2c5f87b0 - 599bee129778596ba77c27a896020fa55123b8635ff3d9efd56fe406de878146 - 26c7d591e0028dd611d6e84969da716eb740207e49f5ea02f17a3224612def12; - 2cfc4c9cb8ca259bd4ffcbbd498510f8a65cca584303a28ed475584bd1eed111 - 3223cab1344be86c0af9995a769276cddbf70eaf55caee24dd4ec0d06c2f4309 - -53728 - 3a48f8bd8a229fa9f5b9d7c4135ef6c3a251b0ce451f482471f017e963839405 - bec0e71a657e85e024d91c41b3a2f75f478528d8ae1afb70bdc5da255d20de06 - 53dc48614937bd5ea1bce51b166bc9947e248a98cd0fac55f632cded216e9cfd - 2999f607e716f0c769e9fdeff636568674f3601166d6b7f566a369b5d4e2797a; - c37946f39bde051e4a6f91a18fda21ec2bfcc375b703bbb81fdcc7ff15cfedf4 - f37e2f1bb6b71763263e742cfd1ce8a9e004a5e06faf0afc52cf49ea89ad9244 - -69223 - 0592777a8c77c1713a72b2ce18fa318fa93e9c6e6b870e54723a43408b502b74 - cf575224b26f636b4b4f28c90995b87d900f6ca5ec9de6c24e65b747d303d221 - 8ab7d691dd76d7cd63d3456c677987a9e53904a4895f053e3de08786d564c837 - 1d667ed7c9b93f2972de23f4d633bcb5f2e56e446cba103c3cf2cf0931687b13; - 2afb15ae6438b8eef9d07f2491e43e32a2b9287381c7bf036dce2a1b0a3542e5 - 18c9bb7c91d5e5ed96e6effc6609fe40e72c5634cac2cf6fb55b083c3339f40a - -33255 - c0c870e0ee2116aa1182b2b4ee4bfde446f721fa6f1bba3a2ed4fb703855c673 - 91fd148ae6d53a419983999020d845503cc923e012e6869201615fbb8e460360 - 5d02294b16e04ca4a7fa4fa5dc9f12c7156e2a68c02495ea171a8cf13d35af99 - f1f90c61c85c137e2e9d5ca7a6b388afd954f6c93548e5fc3b82e02fe875923e; - a7a7193315006fd85c97226f44708d61ecddad2e184d69b0db62f9fb2bc678bb - 87a64ef3c67f464441927c08fd1b57d17bd644a422b96f151aa2d7920989e4ac - 67151 - 6b31a270025004a878f214f100a764165033e170ea5e4c52832673cf88f9f0b3 - 0c0af67c56e0b2336ba06f447ea4f9cbf052147e35f16216b306ef1211ce4142 - 54fec5270095dfc21f44805ba17565386bc50d45bd1f797ebfa04da5040ad08c - 92fdbcabd91ab43baa827594672dede4f0c71d8302b4cc8cd79270aa0c96d915; - 5d72825031c526d9e1efe34fcbbbd81b91460112f9f950e78e12c777a2994a59 - 4334ab5246765e241435c6faac0a00add3a5adcdafe017121d03b9561d0d3516 - -66199 - ef3211bb4e1bac43430e48594577d1d271f76b46ea7e44542c23524b3d6236bc - 1bfb4fb8d8429f0dd7a6cbc23dc2357ce9c1c72be3acf0a49abc331ac751e68a - 7cf2ea00463d76152e230cb5465ab55d30f09afbd007d2b55393cfe8e348cf9a - c0a66f24e5800bec2b9ff65207afd4b29326525b910381d233bd91d51530d046; - 01a66900161a4ad98f028a8da8f10142b4855712a7eb8ffbd699b13b7cc1a471 - c6f8a0b42c3f2a1109201c7a97e3307f6cb56a1a27f13e4567456d9eac2a2f4e - -71473 - e2eef0e19682ebb44cfdf84c71cb556311432fd948951a661d4240e16bc68d1c - f69b44aaff31db04fa4e8f14f51051d353e50110b1562b27d4493ac5e44a5b07 - 29039f65da48a24be024cf8f1af95ea9b09a08a54eec810e97018add81eec1df - a827fcc698403d01f8c2597a582ac8ddd612e5c2a520b0a2428e8dd35c58002d; - bc607923665e36ea0f8206b358fb3a327ef9a70ddcadb2edc49660891e932726 - 33e905cd1b262eba320c61428704c1d7c354361043ea7233c69f1f691f7c7175 - -101999 - e1b804b366c155d0f1a09fdbede434c669bf7f188daa96b8542dcbc9bbe66b6b - 413d410937fbf0575bf34c0b70ee6cd5737e17b6058e774f889104b2f6cacc7b - 0784aeb89be679694477cf399b605473c2c48887b687a980d7d333632e060e6c - 16edc745e1596492fadffd303c31ce5827c3971c591c68f9e2b4f62c967aaa6f; - 904e1b99ee3f860409a2db3aa4e539b2b50cebc57359f23fca21b5bb1306dc50 - 133d76a1f768d77a6801d73a570b35f6dbbd98aabfa4258445684143cd30a39f - -50858 - 547270fdf41f753a4189d2a9630ab17b4c6034829770a40fd8346e75e92610cf - 076c4e34375857b9e6289287e03c744fd60d76c377a772f6edef3ad30e4afafb - f2e8a830fe203901f5f34ae6e606aa8f6cffb504b166cba4cdd84d011b783b90 - 659233daf8ebd47c77b9d46ac65237e1bfdeebbcc552c7db5cf8dd2d4bd1aa2d; - a6f4bce9adbe5a68585c205d20b05c6662748f5f1dd2458defbc126792837a63 - 8f1110929626587241fd403c8332b2ebbc398d4dd7042b993fc24a18b53e3847 - 81985 - 012aaf1e00a521e8e0639ed116e15476f0f8f1c6dff47d860ed60e0bb7c156f7 - 13aaf4f9f20d64110beef21bde5c7262c4bff80a85a08db1e098d45ec3d69457 - eb3230fdacce04518359bfa7cff0c9d6d015966545e40e1c1da18b760031b2aa - 607f7b77fc8d3ca15cdf6e2abba71853fa74739f83589a4458854ae2db0a4727; -} diff --git a/f25519.c b/f25519.c index 6dfc511..4e0d1cc 100644 --- a/f25519.c +++ b/f25519.c @@ -1,3 +1,44 @@ +/* + * f25519.c: arithmetic modulo 2^255 - 19 + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Remove the 16/32-bit implementation, since C99 always has 64-bit + * arithmetic. + * + * * Remove the test rig code: a replacement is in a separate source file. + * + * * Disable some of the operations which aren't needed for X25519. + * (They're used for Ed25519, which we don't need.) + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * Arithmetic modulo 2^255 - 19 @@ -27,14 +68,10 @@ /*----- Header files ------------------------------------------------------*/ -#include "config.h" - -#include "ct.h" #include "f25519.h" /*----- Basic setup -------------------------------------------------------*/ -#if F25519_IMPL == 26 /* Elements x of GF(2^255 - 19) are represented by ten signed integers x_i: x * = SUM_{0<=i<10} x_i 2^ceil(51i/2), mostly following Bernstein's original * paper. @@ -68,30 +105,9 @@ typedef uint32 upiece; typedef uint64 udblpiece; (w)->P[8] = v##8; (w)->P[9] = v##9; \ } while (0) -#elif F25519_IMPL == 10 -/* Elements x of GF(2^255 - 19) are represented by 26 signed integers x_i: x - * = SUM_{0<=i<26} x_i 2^ceil(255i/26); i.e., most pieces are 10 bits wide, - * except for pieces 5, 10, 15, 20, and 25 which have 9 bits. - */ - -typedef int16 piece; typedef int32 dblpiece; -typedef uint16 upiece; typedef uint32 udblpiece; -#define P p10 -#define PIECEWD(i) \ - ((i) == 5 || (i) == 10 || (i) == 15 || (i) == 20 || (i) == 25 ? 9 : 10) -#define NPIECE 26 - -#define B10 0x0400 -#define B9 0x200 -#define B8 0x100 -#define M10 0x3ff -#define M9 0x1ff - -#endif - /*----- Debugging machinery -----------------------------------------------*/ -#if defined(F25519_DEBUG) || defined(TEST_RIG) +#if defined(F25519_DEBUG) #include @@ -134,8 +150,6 @@ DEF_FDUMP(fdump, piece, PIECEWD, NPIECE, 32, get_2p255m91()) void f25519_load(f25519 *z, const octet xv[32]) { -#if F25519_IMPL == 26 - uint32 xw0 = LOAD32_L(xv + 0), xw1 = LOAD32_L(xv + 4), xw2 = LOAD32_L(xv + 8), xw3 = LOAD32_L(xv + 12), xw4 = LOAD32_L(xv + 16), xw5 = LOAD32_L(xv + 20), @@ -199,50 +213,6 @@ void f25519_load(f25519 *z, const octet xv[32]) /* And with that, we're done. */ STASH(z, x); - -#elif F25519_IMPL == 10 - - piece x[NPIECE]; - unsigned i, j, n, wd; - uint32 a; - int b, c; - - /* First, just get the content out of the buffer. */ - for (i = j = a = n = 0, wd = 10; j < NPIECE; i++) { - a |= (uint32)xv[i] << n; n += 8; - if (n >= wd) { - x[j++] = a&MASK(wd); - a >>= wd; n -= wd; - wd = PIECEWD(j); - } - } - - /* There's a little bit left over from the top byte. Carry it into the low - * piece. - */ - x[0] += 19*(int)(a&MASK(n)); - - /* Next, convert the pieces into a roughly balanced signed representation. - * If a piece's top bit is set, lend a bit to the next piece over. For - * x_25, this needs to be carried around, which is a bit fiddly. - */ - b = x[NPIECE - 1]&B8; - c = 19&((b >> 3) - (b >> 8)); - x[NPIECE - 1] -= b << 1; - for (i = NPIECE - 2; i > 0; i--) { - wd = PIECEWD(i) - 1; - b = x[i]&BIT(wd); - x[i + 1] += b >> wd; - x[i] -= b << 1; - } - b = x[0]&B9; - x[1] += (b >> 9) + (x[0] >> 10); - x[0] = (x[0]&M10) - (b << 1) + c; - - /* And we're done. */ - for (i = 0; i < NPIECE; i++) z->P[i] = x[i]; - -#endif } /* --- @f25519_store@ --- * @@ -259,8 +229,6 @@ void f25519_load(f25519 *z, const octet xv[32]) void f25519_store(octet zv[32], const f25519 *x) { -#if F25519_IMPL == 26 - piece PIECES(x), PIECES(y), c, d; uint32 zw0, zw1, zw2, zw3, zw4, zw5, zw6, zw7; mask32 m; @@ -359,76 +327,6 @@ void f25519_store(octet zv[32], const f25519 *x) STORE32_L(zv + 8, zw2); STORE32_L(zv + 12, zw3); STORE32_L(zv + 16, zw4); STORE32_L(zv + 20, zw5); STORE32_L(zv + 24, zw6); STORE32_L(zv + 28, zw7); - -#elif F25519_IMPL == 10 - - piece y[NPIECE], yy[NPIECE], c, d; - unsigned i, j, n, wd; - uint32 m, a; - - /* Before we do anything, copy the input so we can hack on it. */ - for (i = 0; i < NPIECE; i++) y[i] = x->P[i]; - - /* First, propagate the carries throughout the pieces. - * - * It's worth paying careful attention to the bounds. We assume that we - * start out with |y_i| <= 2^14. We start by cutting off and reducing the - * carry c_25 from the topmost piece, y_25. This leaves 0 <= y_25 < 2^9; - * and we'll have |c_25| <= 2^5. We multiply this by 19 and we'll ad it - * onto y_0 and propagte the carries: but what bounds can we calculate on - * y before this? - * - * Let o_i = floor(255 i/26). We have Y_i = SUM_{0<=j>= 10; - for (i = 1; i < NPIECE; i++) { - wd = PIECEWD(i); - d += y[i] + (MASK(wd)&m); - yy[i] = d&MASK(wd); - d >>= wd; - } - - /* Choose which value to keep. */ - m = NONZEROP(c) | ~NONZEROP(d - 1); - for (i = 0; i < NPIECE; i++) y[i] = (yy[i]&m) | (y[i]&~m); - - /* Store the result as an octet string. */ - for (i = j = a = n = 0; i < NPIECE; i++) { - a |= (upiece)y[i] << n; n += PIECEWD(i); - while (n >= 8) { - zv[j++] = a&0xff; - a >>= 8; n -= 8; - } - } - zv[j++] = a; - -#endif } /* --- @f25519_set@ --- * @@ -463,16 +361,11 @@ void f25519_set(f25519 *x, int a) void f25519_add(f25519 *z, const f25519 *x, const f25519 *y) { -#if F25519_IMPL == 26 z->P[0] = x->P[0] + y->P[0]; z->P[1] = x->P[1] + y->P[1]; z->P[2] = x->P[2] + y->P[2]; z->P[3] = x->P[3] + y->P[3]; z->P[4] = x->P[4] + y->P[4]; z->P[5] = x->P[5] + y->P[5]; z->P[6] = x->P[6] + y->P[6]; z->P[7] = x->P[7] + y->P[7]; z->P[8] = x->P[8] + y->P[8]; z->P[9] = x->P[9] + y->P[9]; -#elif F25519_IMPL == 10 - unsigned i; - for (i = 0; i < NPIECE; i++) z->P[i] = x->P[i] + y->P[i]; -#endif } /* --- @f25519_sub@ --- * @@ -487,18 +380,15 @@ void f25519_add(f25519 *z, const f25519 *x, const f25519 *y) void f25519_sub(f25519 *z, const f25519 *x, const f25519 *y) { -#if F25519_IMPL == 26 z->P[0] = x->P[0] - y->P[0]; z->P[1] = x->P[1] - y->P[1]; z->P[2] = x->P[2] - y->P[2]; z->P[3] = x->P[3] - y->P[3]; z->P[4] = x->P[4] - y->P[4]; z->P[5] = x->P[5] - y->P[5]; z->P[6] = x->P[6] - y->P[6]; z->P[7] = x->P[7] - y->P[7]; z->P[8] = x->P[8] - y->P[8]; z->P[9] = x->P[9] - y->P[9]; -#elif F25519_IMPL == 10 - unsigned i; - for (i = 0; i < NPIECE; i++) z->P[i] = x->P[i] - y->P[i]; -#endif } +#ifndef F25519_TRIM_X25519 + /* --- @f25519_neg@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@) @@ -511,20 +401,19 @@ void f25519_sub(f25519 *z, const f25519 *x, const f25519 *y) void f25519_neg(f25519 *z, const f25519 *x) { -#if F25519_IMPL == 26 z->P[0] = -x->P[0]; z->P[1] = -x->P[1]; z->P[2] = -x->P[2]; z->P[3] = -x->P[3]; z->P[4] = -x->P[4]; z->P[5] = -x->P[5]; z->P[6] = -x->P[6]; z->P[7] = -x->P[7]; z->P[8] = -x->P[8]; z->P[9] = -x->P[9]; -#elif F25519_IMPL == 10 - unsigned i; - for (i = 0; i < NPIECE; i++) z->P[i] = -x->P[i]; -#endif } +#endif + /*----- Constant-time utilities -------------------------------------------*/ +#ifndef F25519_TRIM_X25519 + /* --- @f25519_pick2@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) @@ -542,7 +431,6 @@ void f25519_pick2(f25519 *z, const f25519 *x, const f25519 *y, uint32 m) { mask32 mm = FIX_MASK32(m); -#if F25519_IMPL == 26 z->P[0] = PICK2(x->P[0], y->P[0], mm); z->P[1] = PICK2(x->P[1], y->P[1], mm); z->P[2] = PICK2(x->P[2], y->P[2], mm); @@ -553,10 +441,6 @@ void f25519_pick2(f25519 *z, const f25519 *x, const f25519 *y, uint32 m) z->P[7] = PICK2(x->P[7], y->P[7], mm); z->P[8] = PICK2(x->P[8], y->P[8], mm); z->P[9] = PICK2(x->P[9], y->P[9], mm); -#elif F25519_IMPL == 10 - unsigned i; - for (i = 0; i < NPIECE; i++) z->P[i] = PICK2(x->P[i], y->P[i], mm); -#endif } /* --- @f25519_pickn@ --- * @@ -578,7 +462,6 @@ void f25519_pickn(f25519 *z, const f25519 *v, size_t n, size_t i) uint32 b = (uint32)1 << (31 - i); mask32 m; -#if F25519_IMPL == 26 z->P[0] = z->P[1] = z->P[2] = z->P[3] = z->P[4] = z->P[5] = z->P[6] = z->P[7] = z->P[8] = z->P[9] = 0; while (n--) { @@ -595,17 +478,9 @@ void f25519_pickn(f25519 *z, const f25519 *v, size_t n, size_t i) CONDPICK(z->P[9], v->P[9], m); v++; b <<= 1; } -#elif F25519_IMPL == 10 - unsigned j; +} - for (j = 0; j < NPIECE; j++) z->P[j] = 0; - while (n--) { - m = SIGN(b); - for (j = 0; j < NPIECE; j++) CONDPICK(z->P[j], v->P[j], m); - v++; b <<= 1; - } #endif -} /* --- @f25519_condswap@ --- * * @@ -623,7 +498,6 @@ void f25519_condswap(f25519 *x, f25519 *y, uint32 m) { mask32 mm = FIX_MASK32(m); -#if F25519_IMPL == 26 CONDSWAP(x->P[0], y->P[0], mm); CONDSWAP(x->P[1], y->P[1], mm); CONDSWAP(x->P[2], y->P[2], mm); @@ -634,12 +508,10 @@ void f25519_condswap(f25519 *x, f25519 *y, uint32 m) CONDSWAP(x->P[7], y->P[7], mm); CONDSWAP(x->P[8], y->P[8], mm); CONDSWAP(x->P[9], y->P[9], mm); -#elif F25519_IMPL == 10 - unsigned i; - for (i = 0; i < NPIECE; i++) CONDSWAP(x->P[i], y->P[i], mm); -#endif } +#ifndef F25519_TRIM_X25519 + /* --- @f25519_condneg@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@) @@ -655,16 +527,10 @@ void f25519_condswap(f25519 *x, f25519 *y, uint32 m) void f25519_condneg(f25519 *z, const f25519 *x, uint32 m) { -#ifdef NEG_TWOC mask32 m_xor = FIX_MASK32(m); piece m_add = m&1; # define CONDNEG(x) (((x) ^ m_xor) + m_add) -#else - int s = PICK2(-1, +1, m); -# define CONDNEG(x) (s*(x)) -#endif -#if F25519_IMPL == 26 z->P[0] = CONDNEG(x->P[0]); z->P[1] = CONDNEG(x->P[1]); z->P[2] = CONDNEG(x->P[2]); @@ -675,17 +541,13 @@ void f25519_condneg(f25519 *z, const f25519 *x, uint32 m) z->P[7] = CONDNEG(x->P[7]); z->P[8] = CONDNEG(x->P[8]); z->P[9] = CONDNEG(x->P[9]); -#elif F25519_IMPL == 10 - unsigned i; - for (i = 0; i < NPIECE; i++) z->P[i] = CONDNEG(x->P[i]); -#endif #undef CONDNEG } -/*----- Multiplication ----------------------------------------------------*/ +#endif -#if F25519_IMPL == 26 +/*----- Multiplication ----------------------------------------------------*/ /* Let B = 2^63 - 1 be the largest value such that +B and -B can be * represented in a double-precision piece. On entry, it must be the case @@ -721,67 +583,6 @@ void f25519_condneg(f25519 *z, const f25519 *x, uint32 m) CARRYSTEP(z##9, _t9, M25, B24, 1, _t8, 26); \ } while (0) -#elif F25519_IMPL == 10 - -/* Perform carry propagation on X. */ -static void carry_reduce(dblpiece x[NPIECE]) -{ - /* Initial bounds: we assume |x_i| < 2^31 - 2^27. */ - - unsigned i, j; - dblpiece c; - - /* The result is nearly canonical, because we do sequential carry - * propagation, because smaller processors are more likely to prefer the - * smaller working set than the instruction-level parallelism. - * - * Start at x_23; truncate it to 10 bits, and propagate the carry to x_24. - * Truncate x_24 to 10 bits, and add the carry onto x_25. Truncate x_25 to - * 9 bits, and add 19 times the carry onto x_0. And so on. - * - * Let c_i be the portion of x_i to be carried onto x_{i+1}. I claim that - * |c_i| <= 2^22. Then the carry /into/ any x_i has magnitude at most - * 19*2^22 < 2^27 (allowing for the reduction as we carry from x_25 to - * x_0), and x_i after carry is bounded above by 2^31. Hence, the carry - * out is at most 2^22, as claimed. - * - * Once we reach x_23 for the second time, we start with |x_23| <= 2^9. - * The carry into x_23 is at most 2^27 as calculated above; so the carry - * out into x_24 has magnitude at most 2^17. In turn, |x_24| <= 2^9 before - * the carry, so is now no more than 2^18 in magnitude, and the carry out - * into x_25 is at most 2^8. This leaves |x_25| < 2^9 after carry - * propagation. - * - * Be careful with the bit hacking because the quantities involved are - * signed. - */ - - /*For each piece, we bias it so that floor division (as done by an - * arithmetic right shift) and modulus (as done by bitwise-AND) does the - * right thing. - */ -#define CARRY(i, wd, b, m) do { \ - x[i] += (b); \ - c = ASR(dblpiece, x[i], (wd)); \ - x[i] = (dblpiece)((udblpiece)x[i]&(m)) - (b); \ -} while (0) - - { CARRY(23, 10, B9, M10); } - { x[24] += c; CARRY(24, 10, B9, M10); } - { x[25] += c; CARRY(25, 9, B8, M9); } - { x[0] += 19*c; CARRY( 0, 10, B9, M10); } - for (i = 1; i < 21; ) { - for (j = i + 4; i < j; ) { x[i] += c; CARRY( i, 10, B9, M10); i++; } - { x[i] += c; CARRY( i, 9, B8, M9); i++; } - } - while (i < 25) { x[i] += c; CARRY( i, 10, B9, M10); i++; } - x[25] += c; - -#undef CARRY -} - -#endif - /* --- @f25519_mulconst@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@) @@ -795,8 +596,6 @@ static void carry_reduce(dblpiece x[NPIECE]) void f25519_mulconst(f25519 *z, const f25519 *x, long a) { -#if F25519_IMPL == 26 - piece PIECES(x); dblpiece PIECES(z), aa = a; @@ -811,17 +610,6 @@ void f25519_mulconst(f25519 *z, const f25519 *x, long a) /* Following `CARRY_REDUCE', we'll have |z_i| <= 2^26. */ CARRY_REDUCE(z, z); STASH(z, z); - -#elif F25519_IMPL == 10 - - dblpiece y[NPIECE]; - unsigned i; - - for (i = 0; i < NPIECE; i++) y[i] = a*x->P[i]; - carry_reduce(y); - for (i = 0; i < NPIECE; i++) z->P[i] = y[i]; - -#endif } /* --- @f25519_mul@ --- * @@ -836,8 +624,6 @@ void f25519_mulconst(f25519 *z, const f25519 *x, long a) void f25519_mul(f25519 *z, const f25519 *x, const f25519 *y) { -#if F25519_IMPL == 26 - piece PIECES(x), PIECES(y); dblpiece PIECES(z); unsigned i; @@ -902,48 +688,6 @@ void f25519_mul(f25519 *z, const f25519 *x, const f25519 *y) */ for (i = 0; i < 2; i++) CARRY_REDUCE(z, z); STASH(z, z); - -#elif F25519_IMPL == 10 - - dblpiece u[NPIECE], t, tt, p; - unsigned i, j, k; - - /* This is unpleasant. Honestly, this table seems to be the best way of - * doing it. - */ - static const unsigned short off[NPIECE] = { - 0, 10, 20, 30, 40, 50, 59, 69, 79, 89, 99, 108, 118, - 128, 138, 148, 157, 167, 177, 187, 197, 206, 216, 226, 236, 246 - }; - - /* First pass: things we must multiply by 19 or 38. */ - for (i = 0; i < NPIECE - 1; i++) { - t = tt = 0; - for (j = i + 1; j < NPIECE; j++) { - k = NPIECE + i - j; p = (dblpiece)x->P[j]*y->P[k]; - if (off[i] < off[j] + off[k] - 255) tt += p; - else t += p; - } - u[i] = 19*(t + 2*tt); - } - u[NPIECE - 1] = 0; - - /* Second pass: things we must multiply by 1 or 2. */ - for (i = 0; i < NPIECE; i++) { - t = tt = 0; - for (j = 0; j <= i; j++) { - k = i - j; p = (dblpiece)x->P[j]*y->P[k]; - if (off[i] < off[j] + off[k]) tt += p; - else t += p; - } - u[i] += t + 2*tt; - } - - /* And we're done. */ - carry_reduce(u); - for (i = 0; i < NPIECE; i++) z->P[i] = u[i]; - -#endif } /* --- @f25519_sqr@ --- * @@ -958,8 +702,6 @@ void f25519_mul(f25519 *z, const f25519 *x, const f25519 *y) void f25519_sqr(f25519 *z, const f25519 *x) { -#if F25519_IMPL == 26 - piece PIECES(x); dblpiece PIECES(z); unsigned i; @@ -1003,10 +745,6 @@ void f25519_sqr(f25519 *z, const f25519 *x) /* See `f25519_mul' for details. */ for (i = 0; i < 2; i++) CARRY_REDUCE(z, z); STASH(z, z); - -#elif F25519_IMPL == 10 - f25519_mul(z, x, x); -#endif } /*----- More complicated things -------------------------------------------*/ @@ -1063,6 +801,8 @@ void f25519_inv(f25519 *z, const f25519 *x) #undef SQRN } +#ifndef F25519_TRIM_X25519 + /* --- @f25519_quosqrt@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) @@ -1170,318 +910,6 @@ int f25519_quosqrt(f25519 *z, const f25519 *x, const f25519 *y) return (rc); } -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -#include -#include -#include - -static void fixdstr(dstr *d) -{ - if (d->len > 32) - die(1, "invalid length for f25519"); - else if (d->len < 32) { - dstr_ensure(d, 32); - memset(d->buf + d->len, 0, 32 - d->len); - d->len = 32; - } -} - -static void cvt_f25519(const char *buf, dstr *d) -{ - dstr dd = DSTR_INIT; - - type_hex.cvt(buf, &dd); fixdstr(&dd); - dstr_ensure(d, sizeof(f25519)); d->len = sizeof(f25519); - f25519_load((f25519 *)d->buf, (const octet *)dd.buf); - dstr_destroy(&dd); -} - -static void dump_f25519(dstr *d, FILE *fp) - { fdump(stderr, "???", (const piece *)d->buf); } - -static void cvt_f25519_ref(const char *buf, dstr *d) - { type_hex.cvt(buf, d); fixdstr(d); } - -static void dump_f25519_ref(dstr *d, FILE *fp) -{ - f25519 x; - - f25519_load(&x, (const octet *)d->buf); - fdump(stderr, "???", x.P); -} - -static int eq(const f25519 *x, dstr *d) - { octet b[32]; f25519_store(b, x); return (memcmp(b, d->buf, 32) == 0); } - -static const test_type - type_f25519 = { cvt_f25519, dump_f25519 }, - type_f25519_ref = { cvt_f25519_ref, dump_f25519_ref }; - -#define TEST_UNOP(op) \ - static int vrf_##op(dstr dv[]) \ - { \ - f25519 *x = (f25519 *)dv[0].buf; \ - f25519 z, zz; \ - int ok = 1; \ - \ - f25519_##op(&z, x); \ - if (!eq(&z, &dv[1])) { \ - ok = 0; \ - fprintf(stderr, "failed!\n"); \ - fdump(stderr, "x", x->P); \ - fdump(stderr, "calc", z.P); \ - f25519_load(&zz, (const octet *)dv[1].buf); \ - fdump(stderr, "z", zz.P); \ - } \ - \ - return (ok); \ - } - -TEST_UNOP(neg) -TEST_UNOP(sqr) -TEST_UNOP(inv) - -#define TEST_BINOP(op) \ - static int vrf_##op(dstr dv[]) \ - { \ - f25519 *x = (f25519 *)dv[0].buf, *y = (f25519 *)dv[1].buf; \ - f25519 z, zz; \ - int ok = 1; \ - \ - f25519_##op(&z, x, y); \ - if (!eq(&z, &dv[2])) { \ - ok = 0; \ - fprintf(stderr, "failed!\n"); \ - fdump(stderr, "x", x->P); \ - fdump(stderr, "y", y->P); \ - fdump(stderr, "calc", z.P); \ - f25519_load(&zz, (const octet *)dv[2].buf); \ - fdump(stderr, "z", zz.P); \ - } \ - \ - return (ok); \ - } - -TEST_BINOP(add) -TEST_BINOP(sub) -TEST_BINOP(mul) - -static int vrf_mulc(dstr dv[]) -{ - f25519 *x = (f25519 *)dv[0].buf; - long a = *(const long *)dv[1].buf; - f25519 z, zz; - int ok = 1; - - f25519_mulconst(&z, x, a); - if (!eq(&z, &dv[2])) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "x", x->P); - fprintf(stderr, "a = %ld\n", a); - fdump(stderr, "calc", z.P); - f25519_load(&zz, (const octet *)dv[2].buf); - fdump(stderr, "z", zz.P); - } - - return (ok); -} - -static int vrf_condneg(dstr dv[]) -{ - f25519 *x = (f25519 *)dv[0].buf; - uint32 m = *(uint32 *)dv[1].buf; - f25519 z; - int ok = 1; - - f25519_condneg(&z, x, m); - if (!eq(&z, &dv[2])) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "x", x->P); - fprintf(stderr, "m = 0x%08lx\n", (unsigned long)m); - fdump(stderr, "calc z", z.P); - f25519_load(&z, (const octet *)dv[1].buf); - fdump(stderr, "want z", z.P); - } - - return (ok); -} - -static int vrf_pick2(dstr dv[]) -{ - f25519 *x = (f25519 *)dv[0].buf, *y = (f25519 *)dv[1].buf; - uint32 m = *(uint32 *)dv[2].buf; - f25519 z; - int ok = 1; - - f25519_pick2(&z, x, y, m); - if (!eq(&z, &dv[3])) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "x", x->P); - fdump(stderr, "y", y->P); - fprintf(stderr, "m = 0x%08lx\n", (unsigned long)m); - fdump(stderr, "calc z", z.P); - f25519_load(&z, (const octet *)dv[3].buf); - fdump(stderr, "want z", z.P); - } - - return (ok); -} - -static int vrf_pickn(dstr dv[]) -{ - dstr d = DSTR_INIT; - f25519 v[32], z; - size_t i = *(uint32 *)dv[1].buf, j, n; - const char *p; - char *q; - int ok = 1; - - for (q = dv[0].buf, n = 0; (p = str_qword(&q, 0)) != 0; n++) - { cvt_f25519(p, &d); v[n] = *(f25519 *)d.buf; } - - f25519_pickn(&z, v, n, i); - if (!eq(&z, &dv[2])) { - ok = 0; - fprintf(stderr, "failed!\n"); - for (j = 0; j < n; j++) { - fprintf(stderr, "v[%2u]", (unsigned)j); - fdump(stderr, "", v[j].P); - } - fprintf(stderr, "i = %u\n", (unsigned)i); - fdump(stderr, "calc z", z.P); - f25519_load(&z, (const octet *)dv[2].buf); - fdump(stderr, "want z", z.P); - } - - dstr_destroy(&d); - return (ok); -} - -static int vrf_condswap(dstr dv[]) -{ - f25519 *x = (f25519 *)dv[0].buf, *y = (f25519 *)dv[1].buf; - f25519 xx = *x, yy = *y; - uint32 m = *(uint32 *)dv[2].buf; - int ok = 1; - - f25519_condswap(&xx, &yy, m); - if (!eq(&xx, &dv[3]) || !eq(&yy, &dv[4])) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "x", x->P); - fdump(stderr, "y", y->P); - fprintf(stderr, "m = 0x%08lx\n", (unsigned long)m); - fdump(stderr, "calc xx", xx.P); - fdump(stderr, "calc yy", yy.P); - f25519_load(&xx, (const octet *)dv[3].buf); - f25519_load(&yy, (const octet *)dv[4].buf); - fdump(stderr, "want xx", xx.P); - fdump(stderr, "want yy", yy.P); - } - - return (ok); -} - -static int vrf_quosqrt(dstr dv[]) -{ - f25519 *x = (f25519 *)dv[0].buf, *y = (f25519 *)dv[1].buf; - f25519 z, zz; - int rc; - int ok = 1; - - if (dv[2].len) { fixdstr(&dv[2]); fixdstr(&dv[3]); } - rc = f25519_quosqrt(&z, x, y); - if (!dv[2].len ? !rc : (rc || (!eq(&z, &dv[2]) && !eq(&z, &dv[3])))) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "x", x->P); - fdump(stderr, "y", y->P); - if (rc) fprintf(stderr, "calc: FAIL\n"); - else fdump(stderr, "calc", z.P); - if (!dv[2].len) - fprintf(stderr, "exp: FAIL\n"); - else { - f25519_load(&zz, (const octet *)dv[2].buf); - fdump(stderr, "z", zz.P); - f25519_load(&zz, (const octet *)dv[3].buf); - fdump(stderr, "z'", zz.P); - } - } - - return (ok); -} - -static int vrf_sub_mulc_add_sub_mul(dstr dv[]) -{ - f25519 *u = (f25519 *)dv[0].buf, *v = (f25519 *)dv[1].buf, - *w = (f25519 *)dv[3].buf, *x = (f25519 *)dv[4].buf, - *y = (f25519 *)dv[5].buf; - long a = *(const long *)dv[2].buf; - f25519 umv, aumv, wpaumv, xmy, z, zz; - int ok = 1; - - f25519_sub(&umv, u, v); - f25519_mulconst(&aumv, &umv, a); - f25519_add(&wpaumv, w, &aumv); - f25519_sub(&xmy, x, y); - f25519_mul(&z, &wpaumv, &xmy); - - if (!eq(&z, &dv[6])) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "u", u->P); - fdump(stderr, "v", v->P); - fdump(stderr, "u - v", umv.P); - fprintf(stderr, "a = %ld\n", a); - fdump(stderr, "a (u - v)", aumv.P); - fdump(stderr, "w + a (u - v)", wpaumv.P); - fdump(stderr, "x", x->P); - fdump(stderr, "y", y->P); - fdump(stderr, "x - y", xmy.P); - fdump(stderr, "(x - y) (w + a (u - v))", z.P); - f25519_load(&zz, (const octet *)dv[6].buf); fdump(stderr, "z", zz.P); - } - - return (ok); -} - -static test_chunk tests[] = { - { "add", vrf_add, { &type_f25519, &type_f25519, &type_f25519_ref } }, - { "sub", vrf_sub, { &type_f25519, &type_f25519, &type_f25519_ref } }, - { "neg", vrf_neg, { &type_f25519, &type_f25519_ref } }, - { "condneg", vrf_condneg, - { &type_f25519, &type_uint32, &type_f25519_ref } }, - { "mul", vrf_mul, { &type_f25519, &type_f25519, &type_f25519_ref } }, - { "mulconst", vrf_mulc, { &type_f25519, &type_long, &type_f25519_ref } }, - { "pick2", vrf_pick2, - { &type_f25519, &type_f25519, &type_uint32, &type_f25519_ref } }, - { "pickn", vrf_pickn, - { &type_string, &type_uint32, &type_f25519_ref } }, - { "condswap", vrf_condswap, - { &type_f25519, &type_f25519, &type_uint32, - &type_f25519_ref, &type_f25519_ref } }, - { "sqr", vrf_sqr, { &type_f25519, &type_f25519_ref } }, - { "inv", vrf_inv, { &type_f25519, &type_f25519_ref } }, - { "quosqrt", vrf_quosqrt, - { &type_f25519, &type_f25519, &type_hex, &type_hex } }, - { "sub-mulc-add-sub-mul", vrf_sub_mulc_add_sub_mul, - { &type_f25519, &type_f25519, &type_long, &type_f25519, - &type_f25519, &type_f25519, &type_f25519_ref } }, - { 0, 0, { 0 } } -}; - -int main(int argc, char *argv[]) -{ - test_run(argc, argv, tests, SRCDIR "/t/f25519"); - return (0); -} - #endif /*----- That's all, folks -------------------------------------------------*/ diff --git a/f25519.h b/f25519.h index fc75546..8450748 100644 --- a/f25519.h +++ b/f25519.h @@ -1,3 +1,42 @@ +/* + * f25519.h: arithmetic modulo 2^255 - 19 + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and lightly modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Remove the 16/32-bit implementation, since C99 always has 64-bit + * arithmetic. + * + * * Disable some of the operations which aren't needed for X25519. + * (They're used for Ed25519, which we don't need.) + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * Arithmetic modulo 2^255 - 19 @@ -34,7 +73,7 @@ /*----- Header files ------------------------------------------------------*/ -#include +#include "fake-mLib-bits.h" #ifndef CATACOMB_QFARITH_H # include "qfarith.h" @@ -44,19 +83,12 @@ typedef union { int32 p26[10]; - int16 p10[26]; } f25519; -#if !defined(F25519_IMPL) && defined(HAVE_INT64) -# define F25519_IMPL 26 -#endif - -#ifndef F25519_IMPL -# define F25519_IMPL 10 -#endif - /*----- Functions provided ------------------------------------------------*/ +#define F25519_TRIM_X25519 + /* --- @f25519_set@ --- * * * Arguments: @f25519 *z@ = where to write the result @@ -108,6 +140,8 @@ extern void f25519_load(f25519 */*z*/, const octet /*xv*/[32]); extern void f25519_store(octet /*zv*/[32], const f25519 */*x*/); +#ifndef F25519_TRIM_X25519 + /* --- @f25519_pick2@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) @@ -141,6 +175,8 @@ extern void f25519_pick2(f25519 */*z*/, const f25519 */*x*/, extern void f25519_pickn(f25519 */*z*/, const f25519 */*v*/, size_t /*n*/, size_t /*i*/); +#endif + /* --- @f25519_condswap@ --- * * * Arguments: @f25519 *x, *y@ = two operands @@ -181,6 +217,8 @@ extern void f25519_add(f25519 */*z*/, extern void f25519_sub(f25519 */*z*/, const f25519 */*x*/, const f25519 */*y*/); +#ifndef F25519_TRIM_X25519 + /* --- @f25519_neg@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@) @@ -208,6 +246,8 @@ extern void f25519_neg(f25519 */*z*/, const f25519 */*x*/); extern void f25519_condneg(f25519 */*z*/, const f25519 */*x*/, uint32 /*m*/); +#endif + /* --- @f25519_mulconst@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@) @@ -260,6 +300,8 @@ extern void f25519_sqr(f25519 */*z*/, const f25519 */*x*/); extern void f25519_inv(f25519 */*z*/, const f25519 */*x*/); +#ifndef F25519_TRIM_X25519 + /* --- @f25519_quosqrt@ --- * * * Arguments: @f25519 *z@ = where to put the result (may alias @x@ or @y@) @@ -276,6 +318,8 @@ extern void f25519_inv(f25519 */*z*/, const f25519 */*x*/); extern int f25519_quosqrt(f25519 */*z*/, const f25519 */*x*/, const f25519 */*y*/); +#endif + /*----- That's all, folks -------------------------------------------------*/ #ifdef __cplusplus diff --git a/fake-mLib-bits.h b/fake-mLib-bits.h new file mode 100644 index 0000000..3fa7ecb --- /dev/null +++ b/fake-mLib-bits.h @@ -0,0 +1,47 @@ +/* + * This file is part of secnet. + * See README for full list of copyright holders. + * + * secnet is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version d of the License, or + * (at your option) any later version. + * + * secnet is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 3 along with secnet; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ + +#ifndef fake_mLib_bits_h +#define fake_mLib_bits_h + +/* The header defines a large number of types and macros for + * various kinds of bithacking. Notably, it has machinery for autodetecting + * suitable types holding (at least) various numbers of bits -- a service + * which C99 provides through other means. + * + * This file provides a small portion of the interface, just + * enough to make the pieces of code lifted from Catacomb feel at home. + */ + +#include +#include "unaligned.h" + +typedef uint8_t octet; +typedef uint_fast32_t uint32; +typedef uint_fast64_t uint64; +#define HAVE_UINT64 1 + +#define LOAD32_L(p) (get_uint32_le(p)) +#define STORE32_L(p, x) put_uint32_le((p), (x)) + +#define U32(x) ((uint32)(x) & 0xffffffffu) + +#define NEG_TWOC 1 /* assume two's complement */ + +#endif /* fake_mLib_bits_h */ diff --git a/fgoldi-tests.in b/fgoldi-tests.in deleted file mode 100644 index 1f635c7..0000000 --- a/fgoldi-tests.in +++ /dev/null @@ -1,572 +0,0 @@ -### Test cases for arithmetic mod 2^448 - 2^224 - 1. - -add { - ## Some easy ones. - ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff - 00 - ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff; - fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff - 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff; - fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff - 01 00; - - ## Random tests. - 6b3944398448a0a5f6c4e1be9abfcbb082b8f68f1c831d51ef2244f6e1a4c4baaf0ada769c1261b8e14b4856de381d69961078ea1949d39c - 62e933c5f93e57e042d66b89d3c72ee85441b1207732d888b3d6bc35f3bcef91a6f4564cb085fd3239191c2fe427dcdb0e81164d30ca8145 - cd2278fe7d87f785399b4d486e87fa98d7f9a7b093b5f5d9a2f9002cd561b44c56ff30c34c985eeb1a656485c260f944a5918e374a1355e2; - 34938a406030a285024e9ff0a45987b53accc9d5d59828de8b8e07ba693b64d1dd2c7a190e708253a9ae57572e44fa458c8f8ac87cd96037 - 9d05863131328886c7203fe70924761e56244d40a04d4b5592f1c6a457b9d94fe950fb8a865f9091ba9223479f3e46680fb78ccddc776bf2 - d298107291622a0cca6eded7ae7dfdd390f0161676e673331e80ce5ec2f43d21c77d75a494cf12e563417b9ecd8240ae9b4617965951cc29; - 4e9cb6823482233daf59662d00212f2afe42183f8ce949b2e0ca5473e32ab647fe9bc1c472b2288715c0d5b118043fbc9aec782654363cdd - 6c62329ec8eb576b6866cb6af702b891dd2cd72d21c354ada34221141381acca066fb46a8fbce28df44f0ac8062e38847067b8639be867f8 - bbfee820fd6d7ba817c03198f723e7bbdb6fef6cadac9e5f840d7687f7ab6212050b762f026f0b150a10e0791f3277400b54318aef1ea4d5; - b46d33f24a69c2288bed34eb054d1fcd6244606cffca7d53ff4e68f113174655a9a72898ad2699fe49d069a0a84e077bf48205008dee04aa - 9abc68911a75a6a376837cc6fc0e18c63cfb81747a59ba1314412f032f8b2a2fc5dde29176d141e71dbc11aeb2ecb9a336c8467882a175ea - 4f2a9c8365de68cc0171b1b1025c37939f3fe2e079243867139097f443a270846e850b2a24f8dae5678c7b4e5b3bc11e2b4b4c780f907a94; - 1195eae69f2bad43b7b8330395e41c811bae2f753f0a6727b9decd2e553dce743dbb568b45140c3a464c8646db12b3af18df328a95640706 - 8fc020ba693b4014fbf4e9c64223a8c3234e1361b8e2a745e3897f582537e20417831c159c107451fec49b88c4cde774330d8986430b39e0 - a0550ba10967ed57b2ad1dcad707c5443ffc42d6f7ec0e6d9c684d877a74b079543e73a0e124808b441122cf9fe09a244cecbb10d96f40e6; - 4b25a323cba12b5d042369a065a3696c7613898205f7defd3ab15ec351ec9fe1ba453c8b9abf254ff793c92b1f77d5f23f7629c04ec5c70d - b12ee8f930b029e2e4b79b808566b88b8087a510e5f80751ffc8f5426709bc2b40608e3e769dbd97d37dfe8a36fd25fbc1efb2cd9eda09f2 - fc538b1dfc51553fe9da0421eb0922f8f69a2e93eaefe64e3a7a5406b9f55b0dfba5cac9105de3e6ca11c8b65574fbed0166dc8ded9fd1ff; - c441e6cebc634bd7de7de356e855528d52f4affae7cdd585352d94218ca171929b17b8f49ea294f5151a277c116519de5ff92ce4e2f6ce0a - 809617d4e40d53223f01887bfab5a7d2dc1eb4f680ae59981b33e11fe71345b3155f567cc867cd9e48c8b534870c7df49dff883c0900d8cd - 44d8fda2a1719ef91d7f6bd2e20bfa5f2f1364f1687c2f1e5160754173b5b645b1760e71670a62945ee2dcb0987196d2fdf8b520ecf6a6d8; - a92361d9c458605877a6d9229128b1a52f7bab378d0d389568aae10d09d419b0e6436684b438abcaa3e1710efee5ecec1af06cf0c82b339d - 74bc6cd43025234b1a6e15fe2d4fab520c874af6f896b82ecb096b0ec3cf73ecf04ef1d13ca612ef0981b8aca0a769ae60202eca36410b0e - 1de0cdadf57d83a39114ef20bf775cf83b02f62d86a4f0c333b44c1ccca38d9cd7925756f1debdb9ad622abb9e8d569b7b109bbaff6c3eab; - f0ed25db758767b83b1d5ab6f8bdbe8e263b18341ea296b2a5d27c0d928004d6c48695ac88af863ed12be6629d8a1b58ca83ddb4ff9c778b - 44998d5a87e29ace239af04334451efca0d8bb88b441140caab3e79da9c73f1354df0c4e2a8148141bb44c33eb63f1c0025ec2b289390e06 - 3487b335fd6902875fb74afa2c03dd8ac713d4bcd2e3aabe4f8664ab3b4844e91866a2fab230cf52ecdf329688ee0c19cde19f6789d68591; - 64429139cb6dd44a64984ac73cdf306354a32772da0724c647164d89218906de465c0c47f2841564fc69933d140088a02584bbeb7a138e7a - 391d7bf04dd8082b6b196651c251737ba319720b66075f2e65a06023e1dc9697ee4c540b6fae20bdc333c9a95e69266b5ebeccf0b2aea18d - 9e5f0c2a1946dd75cfb1b018ff30a4def7bc997d400f83f4acb6adac03669d7535a9605261333621c09d5ce77269ae0b844288dc2dc22f08; - 0bb7ca441d108e3d7a4c43025798eb1f1036e2d2200e2457aa93a631c068bf9e99805e8c69344d6f5fc063865f2e94bb954c20645f8b7003 - 3f47bc6701604867acc3cf534d62c9847617954d860c34ac2bcacbfb1c24c99a7442a6170ea6539df0c98afaf6fc8f45dcaa77afebcc8290 - 4afe86ac1e70d6a426101356a4fab4a4864d7720a71a5803d65d722ddd8c88390ec304a477daa00c508aee80562b240172f797134b58f393; - 93205ac6e814337d0d12f8e55f0b62a32ba948cbc6df03293d51e67a7aa7e1457d201991f3392f1cc4a4a9b6b2ed27407ac4e24a5b0e2664 - c2d648607a99e6dccb9f9940ffed57de39928d9c3fcbabd79876ecf1a5476ff5a637d0052f04d82a2794bf0e31268fd6ff640b4aa1ac921f - 55f7a22663ae195ad9b191265ff9b981653bd66706abaf00d6c7d26c20ef503b2458e996223e0747eb3869c5e313b7167a29ee94fcbab883; - 42bb562d81bac7f606d2157697f29f1799b3e5172f003f44785b80006fb56681b832ff6e7875d6a146b09a9a95f9f3cfb210f5b9aa545e0c - e7cc109d2ea008a1c938c66e296911c0d7503b1a961f23edce9532c718e53518729dcc6f7e921f831c56d1d8ee7c5b4919f4030ce6703e68 - 298867caaf5ad097d00adce4c05bb1d770042132c51f623147f1b2c7879a9c992ad0cbdef607f62463066c7384764f19cc04f9c590c59c74; - 4cfc133cf2b3e22f569340c3a59299087f9caf8b36562d418f2e18494769278c16a22641e4de8f675e9540d6fc0f8c210a64dd63c8d01453 - f33b0a3beaad1fb12ba48d69ef999bb7a5af3bd2b977aaf518bc65a13caaa9d61cacbb7c5ce6173a282d341cf83c86a458c8d2d10a1c1ac2 - 40381e77dc6102e18137ce2c952c35c0244ceb5df0cdd736a8ea7dea8413d162334ee2bd40c5a7a186c274f2f44c12c6622cb035d3ec2e15; - fc64ef657d34477c17b0674b697cc5a4bc8e665ba1dee02e5afd0d2f57e0a64abb2bc428215d9e8ece95c5283e4233d483201c286e4997cb - ed4af51625762548e95f32e7042f07bb260f734fb9ba43301daddff9a863990d79791d5db1bbbdbad75c09ce313d93638c219c989702c5ed - eaafe47ca2aa6cc400109a326eabcc5fe39dd9aa5a99245f77aaed280144405834a5e185d2185c49a6f2cef66f7fc6371042b8c0054c5cb9; - 2fa4cdcae0b01f3f3aa28d4ff311054c73683c09749eb312cd4ff7cf018fa647a66b44477459cab757b9149623ecf9064dba16d5601eafb7 - b378045a6652eea3cc9a8530dea6361daa86866f038e579670f2d50e072417342f1887827335a0a041d1411b24a68d8f190edd8a251ac3c7 - e31cd22447030ee3063d1380d1b83b691defc278772c0ba93d42cdde09b3bd7bd583cbc9e78e6a58998a56b14792879666c8f35f8638727f; - 5107c636bcd6bc59ec9c7fcf04efbf90fdde936bff7e221be660d542f74fcccb8b49220b93744203bdb7b026f1bb9fd9a64c0187fd3d99a7 - ee48bc6d5c231bd7be253ed69171d2525157d0d8fe12fdafa6e7a3285f0d966fd4c570928f61850138489fca5cb540444c24b602d9025899 - 405082a418fad730abc2bda5966092e34e366444fe911fcb8c48796b575d623b600f939d22d6c704f5ff4ff14d71e01df370b789d640f140; - 475e593758fa8506baa94e1b6070aeaff278d905af67f9e5a5273ae0737825d220c02ae7a89f39998f98895c83e51e7bd0cc0c9126273792 - 3f724d7bbb27bf8b2f4e328bd865e412ed6207802703def28b9b64567b15f7648c1f96ca5092400e32427f9880c95fa0a83f7fbdd6b2d2b7 - 87d0a6b213224592e9f780a638d692c2dfdbe085d66ad7d831c39e36f08d1c37addfc0b1f9317aa7c1da08f503af7e1b790c8c4efdd9094a; - fb7923d1a8666b372b41792749ae312903e1b1a8198970a5da6d85dc19a4326bcde206ee841a2bf106c95e99b42fa7eb3fa559b4b88d31c2 - 45e467dafaee144bbd614028c0ea4d3a37b4ef99ded5c9e44b7526916218202401233364bffadac9424143bac99b4c2d89ceea71c3fd0ea4 - 415e8baba3558082e8a2b94f09997f633a95a142f85e3a8a26e3ab6d7dbc528fce053a52441506bb490aa2537ecbf318c97344267c8b4066; - 2212850af1b191227fc4875e981ee15968832cb6898243af481b62d91ae5cb26fdcd72e45a54cbbbd9efc5e1739f8683d8ab318586b51e7c - 6b7b3294bfd31a11644924c988b0b19cfc1db66d8e674040ee21537b54aed4e1e217f0b3427d7d4d9dc7d9dcbcda8c2c47c5348b9eaa7ddb - 8e8db79eb085ac33e30dac2721cf92f664a1e22318ea83ef363db5547093a008e0e562989dd1480977b79fbe307a13b01f71661025609c57; -} - -sub { - 890e734c6f4af5b1c62cf6fdd0facf76af535bdc9781396c59a6cd8c37cc96aac97fa61bef07c60c69dfb633049014868473d28481385ba1 - 0a06a622804bfe9041259a435be8c40aa56d1be10dd3c4261157c16c0d0d99d11b0f5dce0b164a2e6d4c53813242954830a39f2c894fb315 - 7f08cd29effef62085075cba75120b6c0ae63ffb89ae7445484f0c202abffdd8ad70494de3f17bdefb9263b2d14d7f3d54d03258f8e8a78b; - 17935b9768cf9ecdc3b3a4c3c87ee20f766bca820f620c1852a48d680f445f1a28ee6a9a18fbdcdb9f35846bc6f0bbb1687b227bcadd4c3a - 9f913b62023a48e577ac9aaa6d06bb5cf46ea3acc2946a80f66fba02859837491a31b6740a5ed1178c8b6faf4198ac836419deb8aa439c0d - 78012035669556e84b070a195b7827b381fc26d64ccda1975b34d3658aab27d10dbdb4250e9d0bc413aa14bc84580f2e046244c21f9ab02c; - b1689e72355c7305d5cab07e2d672e7b92872c115f03f9b45fe7c9d3354ea0d3702f4f915900085ec44e816dcd731086c999c0e97ce52b40 - a85e9b5cbe9f628049f91b9adcc1db63f19e8f7c37b92e43015d0f76f188c1cfe89c86910afb82c2c6f1f7197562b919380a1b32b2439006 - 090a031677bc10858bd194e450a55217a1e89c94274aca715e8aba5d44c5de038892c8ff4e05859bfd5c89535811576c918fa5b7caa19b39; - 8f952f2233cdba45ccaafcb8e6d17b38529a44ff49e8ac8dc6378710d5e5af052c460e2758e3ee28f5866e71737c9b6e7731c03d11d21cd6 - 5bc41fd436b58032dd4f50cd0c57bda1127a3033c2183d8133cb9c40760ea41bb42f48f36b6a2f3bcd0dbc60b5bef5e4b712308ca0f2b443 - 34d10f4efc173a13ef5aacebd97abe963f2014cc87cf6f0c936ceacf5ed70bea7716c633ec78bfed2779b210bebda589bf1e90b170df6792; - 708939d3a13fe996dd90b1128231b7da3593c12d9ab880a4da9febe7f12bfefe72aab1608145911fdfa1e3f1f59b426a06dee253d4d3eeb6 - 008929e61e53becf9bc6dcbf6414f3a71e9f134fcab293cd42e096fef3d87a472a79ed1ce623708aee31e12f5bef9bc6d0aa470ce2a52f80 - 700010ed82ec2ac741cad4521d1dc43217f4addecf05edd697bf54e9fd5283b74831c4439b212195f06f02c29aaca6a335339b47f22dbf36; - a7996b0ae1d8ad5856ae5cf3abc8fc61c4b3579d951b632b9af67dce957365759fb5a6f54965a86b1dcccc9439eebdeb04f616c3fb4db382 - 2df8e6cf52e985d0e20f4f5e9bbaf1b8bd7d7b982da05568b7ea82fd2a5c0302d0ce9feec5e135eca886fd30827905eae204a51e498a173d - 7aa1843a8eef2788739e0d95100e0ba90636dc04687b0dc3e20bfbd06a176273cfe606078483727f7445cf63b774b80122f171a4b2c39b45; - 74179531aaf2ee4e7a309350982fc9ce501ad18c650f0adacce5da9b520ce27c04ca69dca0e719713d4d10db532401bee26b7ff9819bf532 - 6a3554898f2951ed005bc4ac74dfd0ef124cffbb52301109d8414719473dc17a602a3b530195c383efa22dd6da87414395886e4b9dd5b5f3 - 09e240a81ac99d6179d5cea32350f8de3dced1d012dff8d0f4a393820acf2002a49f2e899f5256ed4daae204799cbf7a4de310aee4c53f3f; - e7c145e38ca66fd86991538ab11231abb60af8b0ab7460e047f7b5b69bbe4a3a56c28c14131c35621f4014d541ffabd642c774bc1a5c66c7 - 9ca047c2251cc6012bd734198e4b2c6ca0d50a85db601659b8380510fc6c1d08a27fa5fb8eb3c9e5622185f83fba6ed128d153cc9563e1d6 - 4a21fe20678aa9d63eba1e7123c7043f1635ed2bd0134a878fbeb0a69e512d32b442e71884686b7cbc1e8fdc01453d051af620f084f884f0; - 8f01ab3bbedf7ac443423793a422910a54dd73f121ce6f52270d7953386bf2b0eb228b2560b7103aa94f3190e80038505f2b21a9f138c414 - 44a6b845b4b3b6d9c55478664fa2134df50e7ff4c5184aa57bcc8d01da42cdbb78da3898fd92287b604b6a369c06d695241c48605b57808f - 4a5bf2f5092cc4ea7dedbe2c55807dbd5ecef4fc5bb525adab40eb515d2825f57248528d6224e8be4804c7594cfa61ba3a0fd94896e14385; - 1b6f84c1ad9ec3d008f345a19305aa35e5b55efeb535024b0fc9aee4be1c031bb070655fc5e672ea75b5db98cff0dcfb5427e21e5ffc4fa9 - ad5d4e308c69186e87ac97551e9ec34f2d1746d5f6712b126c3415346ac2271450aca96fc6b9e82ef7e2f3fad60df4f184e34dff8fb53b02 - 6e1136912135ab628146ae4b7567e6e5b79e1829bfc3d638a39499b0545adb0660c4bbeffe2c8abb7ed2e79df8e2e809d043941fcf4614a7; - 25ce194230be078d7f35b85d68706d768fec7994654fcd3f63f3d32eaf59f17bc87a617d41f76b7d0c78b63377a203e43194f0b056d26b0b - 76266bea72a15cdc355867a490e775c909b7b6cfc833107e7c6b7dbaed2c8491c6d000b2d7d2beb72d72937285aa1bceff18aa35d0c52158 - aea7ae57bd1cabb049dd50b9d788f7ac8535c3c49c1bbdc1e6875674c02c6dea01aa60cb6924adc5de0523c1f1f7e715327b467b860c4ab3; - c010bfa3d130f868f2b975318139c2a847c69014b76164192b437fd7e26b892a5a2425670fe3e8fd9efdfa250f57579d1af2d24f8eb6ce92 - bfe65616e278b6ce46b295600131bf5ea092451a87f6bc3adf1c86f2fe717351b073062ced1394a14051bb33f3874cca569aae8ba97605f9 - 002a688defb7419aab07e0d07f08034aa7334bfa2f6ba7de4b26f9e4e2f915d9a9b01e3b22cf545c5eac3ff21bcf0ad3c35724c4e43fc999; - b2f21992b1f2155b7afc3a1d731b52c03cf14208e634b7da123888d652afcd919e9f5f0bea8b9986c71a7ba08fefe58ee0402d9a23b95f2c - ae241fa6292c63f3c09301255a866825b39c9645512ea123486f9a873cacab567cd169c463fb1cf0417633a7055d831d23fd1d58dd42e726 - 04cefaeb87c6b267b96839f81895e99a8954acc2940616b7cac8ed4e1603223b22cef54686907c9685a447f989926271bd430f4246767805; - b714b60b2614ab6ce63bf8eae621357f2e921f79de94982fcd5f524015db3faa52b15ff042733958fa202786f61bfed0b9fb5d5873619aec - 0c99e1da4c747ad1a625321cf9359b1d823544d1eacfddc38e4bfd729ed2f9fb37760242340f7986843fb8fa0435bcb5cffdf11453caebcf - ab7bd430d99f309b3f16c6ceedeb9961ac5cdba7f3c4ba6b3e1455cd760846ae1a3b5dae0e64c0d175e16e8bf1e6411beafd6b432097ae1c; - c5425daf8f7089def2ff910e256d9496fc109d2698cf15dec1ce3f8116231969c5ed327626362b0658c60e74023a3cae5ef128fb5d27cad7 - bc4e49fbf095f73894c4d623a210475cb7ba78ebbcbee8ab55a851162f789fb21e72de95afe4ddd45b90289f94f6d02b5f5a4b90c603ea31 - 09f413b49eda91a55e3bbbea825c4d3a4556243bdb102d326c26ee6ae7aa79b6a67b54e076514d31fc35e6d46d436b82ff96dd6a9723e0a5; - 9aa20b4259efd3a701a63347181fa63f56f42a97ef836bf3aab88d30bbf28a91bbf713a0170024e6057e2281ac113f9b58cb13d63e850ea7 - 09e7104367d8c0441d811ecc619af04def9236752c2d47bc508b0de3c3b29c74533d8eb9fee13279aed8d58247e4010206c697d9b72bab43 - 91bbfafef1161363e424157bb684b5f16661f421c35624375a2d804df73fee1c68ba85e6181ef16c57a54cfe642d3d9952057cfc86596363; - e8ead9316aeb8f56d43418cd3bb1a71234c9e20b4a6dc1604ffdfdbcaacebe73b71d18c2c167544304d895d67e2daa2538a4ad0708cd9acf - ff3603f0960bb7a92f2b7fbfe242b467164e0ca72e89bcab6c467b5391166d05c601b38de40643f04d5b50ff8ec62b18c69e9df74f01babe - e9b3d641d3dfd8aca409990d596ef3aa1d7bd6641be404b5e2b6826919b8516ef11b6534dd601153b67c45d7ef667e0d72051010b8cbe010; - f37b41d9950036d560f02b8befd6f5c73096b8995850b9fc563291fba59fd994916744fbd4c1dd5d17a9e5ecd4ec4a658dfdae1ba7024bc6 - eeda58ba400f16a946381fb11f0ac0db895957236bcc629ce9d1ea425eef8412ea73af488b97f1afa950736f26c3cace887417b699cc3410 - 05a1e81e55f11f2c1ab80cdacfcc35eca63c6176ed8356606d60a6b847b05482a7f394b2492aecad6d58727dae298096048997650d3616b6; - 2bdb71a053047c4173718ce104e5b8671fbd61c59bfe8b20b890ceda15a69d24eec3775f4ce8a9c16d36e50626bc334e0fc1be492d800c06 - b1ccd0dac33ac46b2709f9626ed70136f98dfbc705ad93ea8f1b325d644daf2c0180cb83bfdbb7398d3f58c0f6600056a174850b9db91ed4 - 790ea1c58fc9b7d54b68937e960db731262f66fd9551f83528759c7db058eef7ec43acdb8c0cf287e0f68c462f5b33f86d4c393e90c6ed31; - 8f3fd6346c7f2dacf0d7cdb88a5bca3b222a895a07b169d0bcd0af0a9aa634876ae1a939262dd75bd12b5a97127155a015e00acac7d5cbc8 - 0e9c03c5a06accdddd0d8613e41a00f2b586e297e366987e02e7536e0ca1b4c2c75fed619655acddffe8585c7a828432d90575731a4c8519 - 81a3d26fcb1461ce12ca47a5a640ca496ca3a6c2234ad151bae95b9c8d0580c4a281bcd78fd72a7ed142013b98eed06d3cda9556ad8946af; -} - -condswap { - db0be3ccfda1e2f8492bffb5d3344f1856ff1896b6a067d2fa064423ac5b05b669db1c9b51899c44a7f470be4173856d9aa3d1cd10cb8c9b - 3005560f89232a97cebf6808e7493dd0f17e572556b53723b57faee51d8a0a45c7fb51aeb916f59c74ea6041494483b2fdce72189d1bd031 - 0xffffffff - 3005560f89232a97cebf6808e7493dd0f17e572556b53723b57faee51d8a0a45c7fb51aeb916f59c74ea6041494483b2fdce72189d1bd031 - db0be3ccfda1e2f8492bffb5d3344f1856ff1896b6a067d2fa064423ac5b05b669db1c9b51899c44a7f470be4173856d9aa3d1cd10cb8c9b; - ea009751f6a7045ec7d6d46b16cbe663f5a78fca3835626c79864bec4030443bb9349654d52b2edab92b8f4aa876a97e868aa6267a54e6b1 - 8c6f864ef7f664f4985ed8c1ea0c63bd7ab355b5321c2712791b610a2dadddc90a65ca8d5c25ff199b011193796b08f96420934615103b7b - 0x00000000 - ea009751f6a7045ec7d6d46b16cbe663f5a78fca3835626c79864bec4030443bb9349654d52b2edab92b8f4aa876a97e868aa6267a54e6b1 - 8c6f864ef7f664f4985ed8c1ea0c63bd7ab355b5321c2712791b610a2dadddc90a65ca8d5c25ff199b011193796b08f96420934615103b7b; - dc3aa7d363058993cbdc54e95f3c972a2cea17cdf9370fccdfedfa1ba939ca35f762c5c6283f84348282fd56d83539804427eabe3bd6170d - 8c47a0990eccf7300986232dbc8ee26e8996c3bb4b73663ec5525312bea8975221c9f49039840c181d042654a8c1806bb86702ac7d0b80f4 - 0x00000000 - dc3aa7d363058993cbdc54e95f3c972a2cea17cdf9370fccdfedfa1ba939ca35f762c5c6283f84348282fd56d83539804427eabe3bd6170d - 8c47a0990eccf7300986232dbc8ee26e8996c3bb4b73663ec5525312bea8975221c9f49039840c181d042654a8c1806bb86702ac7d0b80f4; - 69b45538513af2148e0a2903539bc5e20fca4da447278bf5967091d2e781121080c14a41989f9ee5218c444d3a42989ba890c7be7faae5d3 - 935eadbde0c571c29deb4d8404dd39a8cca177ced36c359abfa7a6cafe6075422e1d79cba8d81cdbdfa4a5144faf37b19ca22b2b40fe1a0b - 0x00000000 - 69b45538513af2148e0a2903539bc5e20fca4da447278bf5967091d2e781121080c14a41989f9ee5218c444d3a42989ba890c7be7faae5d3 - 935eadbde0c571c29deb4d8404dd39a8cca177ced36c359abfa7a6cafe6075422e1d79cba8d81cdbdfa4a5144faf37b19ca22b2b40fe1a0b; - de30072f175127ad4200a08099f4d0df0edfa40eb02e21a03c5628dcb2f70da8bce9ebbb1ebed2aca391e73a4114c06bcdbf762bf28777cf - 5eaf3aecf1f7d1fd3b43be8fa450163c79f162b0c6eaa4b1ad39baaf3a4c36564e001c935fdce38e90789151beff0f3cc4fdfc2d86dcb587 - 0x00000000 - de30072f175127ad4200a08099f4d0df0edfa40eb02e21a03c5628dcb2f70da8bce9ebbb1ebed2aca391e73a4114c06bcdbf762bf28777cf - 5eaf3aecf1f7d1fd3b43be8fa450163c79f162b0c6eaa4b1ad39baaf3a4c36564e001c935fdce38e90789151beff0f3cc4fdfc2d86dcb587; - 1bb20a5a05b190737ad6b2bc5bc2b9259fa7e36eac8f3032a7c56ed59c1510baaea32bba898b329b0c64fadbe454095b9f82b366bfae3d8b - cf0a87c8befed020caf82f37b4c5f17d2aa9ff8ab75baa156cfe2716ac1eaabf9bc760c2ddcd66a9d02a8384ad1db9e8f857b151d126e0ef - 0x00000000 - 1bb20a5a05b190737ad6b2bc5bc2b9259fa7e36eac8f3032a7c56ed59c1510baaea32bba898b329b0c64fadbe454095b9f82b366bfae3d8b - cf0a87c8befed020caf82f37b4c5f17d2aa9ff8ab75baa156cfe2716ac1eaabf9bc760c2ddcd66a9d02a8384ad1db9e8f857b151d126e0ef; - c186531a219344dc485cd5dad6500616ac8e0653693168573cb9be590b02dfb1ddc5d87d27f2d9fa46ffeda955a6285b7ef2b9bf84825d06 - 91f3be7eb2e0be38d92974d81be5126ef40d358f242d23aa4863fb16ba3e8844e02edc87c0206e211587886ed532da0ab148cfcf64e9b58d - 0x00000000 - c186531a219344dc485cd5dad6500616ac8e0653693168573cb9be590b02dfb1ddc5d87d27f2d9fa46ffeda955a6285b7ef2b9bf84825d06 - 91f3be7eb2e0be38d92974d81be5126ef40d358f242d23aa4863fb16ba3e8844e02edc87c0206e211587886ed532da0ab148cfcf64e9b58d; - 9f2476d6db424d19ee0cba4ed091da5b44ca63caf2f711eaeb7edcc75f49e0d0c367c1f2817b6bb39460f897432901064cabed7f6a03b1f0 - 66e7dcd34d76a19e3285685112b7619f9a3557764a918922faf1370bb97c2b2fa845dd34662cfe7299ab702c68fd43b5f6f15a0af6625f2e - 0xffffffff - 66e7dcd34d76a19e3285685112b7619f9a3557764a918922faf1370bb97c2b2fa845dd34662cfe7299ab702c68fd43b5f6f15a0af6625f2e - 9f2476d6db424d19ee0cba4ed091da5b44ca63caf2f711eaeb7edcc75f49e0d0c367c1f2817b6bb39460f897432901064cabed7f6a03b1f0; - f124ac31d304a29cdd94bdc0611c61064a7c5f09cf6847bccd52fc7a7b77ede73b42b1ef75f000de4361028e0fb63896f4ef5ad3bc1b9c90 - 6629084a230c793086e469b9a01e052ad7a5680d6955667e0dfb19a250f447d9e238695400dc4ecaeefcebed44d374e57ec4e414f5629e63 - 0x00000000 - f124ac31d304a29cdd94bdc0611c61064a7c5f09cf6847bccd52fc7a7b77ede73b42b1ef75f000de4361028e0fb63896f4ef5ad3bc1b9c90 - 6629084a230c793086e469b9a01e052ad7a5680d6955667e0dfb19a250f447d9e238695400dc4ecaeefcebed44d374e57ec4e414f5629e63; - b64f2952510827bef3d32ef6347251274c7241d9913268a7a6a5c360a4b29e7ed04d09a9ee5aa83235eaf8c0582b076b21d78b7062952773 - 77897028a9a81fd54362a6085aa2c2fd6fdd44589f447c7310b9b3b5a29b54ed15c57e2c9fbff16f20129a4dbd43640a0d1037e277ca5c93 - 0xffffffff - 77897028a9a81fd54362a6085aa2c2fd6fdd44589f447c7310b9b3b5a29b54ed15c57e2c9fbff16f20129a4dbd43640a0d1037e277ca5c93 - b64f2952510827bef3d32ef6347251274c7241d9913268a7a6a5c360a4b29e7ed04d09a9ee5aa83235eaf8c0582b076b21d78b7062952773; - 4d75efd204a66aed323456e6f55cb891ee7a31d739ae89726e0ea84532f9c740d1b647b117094fb85da2c62da04f3b9cb13db6b840046b7c - 0afd07bb073a150e7b82711e1f42f7b0789af8192ea6b4e1b24a3d48de7f8b802875aca5a02a9d24deca0b58c895992a449d01026495b96c - 0x00000000 - 4d75efd204a66aed323456e6f55cb891ee7a31d739ae89726e0ea84532f9c740d1b647b117094fb85da2c62da04f3b9cb13db6b840046b7c - 0afd07bb073a150e7b82711e1f42f7b0789af8192ea6b4e1b24a3d48de7f8b802875aca5a02a9d24deca0b58c895992a449d01026495b96c; - 1ff4eb5f0280744f0c909cede8be29cccb8ae43e4626018a9a1d352a97d987678863ba34bdeb183bb5e9347e96760665f5881570778a2e19 - 49cd390a9edc7fad6c84c2e44ce09e490161094d2dc6cad30759fbef10aa30e5aa6474bc46571188418f3e4a2b19ecfc379a1f94e3a44e48 - 0x00000000 - 1ff4eb5f0280744f0c909cede8be29cccb8ae43e4626018a9a1d352a97d987678863ba34bdeb183bb5e9347e96760665f5881570778a2e19 - 49cd390a9edc7fad6c84c2e44ce09e490161094d2dc6cad30759fbef10aa30e5aa6474bc46571188418f3e4a2b19ecfc379a1f94e3a44e48; - e96c0316baf01c25ef8a41c02e99aa84c82f8eecd3249be268834afb5f7e95f0ad10bfad4160bb335c30ffd6a1090c91c57eb6ac7a7a5e66 - 115e6f115bc4e19af60710f3dd821fb58cb680a32d6973eae9ea3e48f1928dc1d9f684a8c8de80affc59bc0fb342bb040f89d2d46b8ff8fc - 0x00000000 - e96c0316baf01c25ef8a41c02e99aa84c82f8eecd3249be268834afb5f7e95f0ad10bfad4160bb335c30ffd6a1090c91c57eb6ac7a7a5e66 - 115e6f115bc4e19af60710f3dd821fb58cb680a32d6973eae9ea3e48f1928dc1d9f684a8c8de80affc59bc0fb342bb040f89d2d46b8ff8fc; - 71bd8f5036da4c33f6940348ea448c2f9bccb152dab40b410bd695923a9e255b33aaf361055be4bb9a570e201dce784cc1ccb0f89faca85f - 971b2f6569ddd9099a87ec4086d8218abcfbe81579f25f03634e471170a5088f48a6cfd09ed9e389ca37b780165c00b206304229135b6044 - 0xffffffff - 971b2f6569ddd9099a87ec4086d8218abcfbe81579f25f03634e471170a5088f48a6cfd09ed9e389ca37b780165c00b206304229135b6044 - 71bd8f5036da4c33f6940348ea448c2f9bccb152dab40b410bd695923a9e255b33aaf361055be4bb9a570e201dce784cc1ccb0f89faca85f; - 0f1165e19968f3e6159e9f7f843c1b849e5c3917af4e2798869112c6efca9993ed339c8495eec8c54b286820bf7befdc8ae344e4d309c077 - 7ce5a2ae66b9bddd30c98d9aa9fcdd6ef90d244d10115d15cf5d81e9e389f6852b153a42c642447043fcfd278166b92c624508973449b0e8 - 0xffffffff - 7ce5a2ae66b9bddd30c98d9aa9fcdd6ef90d244d10115d15cf5d81e9e389f6852b153a42c642447043fcfd278166b92c624508973449b0e8 - 0f1165e19968f3e6159e9f7f843c1b849e5c3917af4e2798869112c6efca9993ed339c8495eec8c54b286820bf7befdc8ae344e4d309c077; - 6dd07b4891d8f45ad1ee64da38383ec50d6f29634767607eca19a547cadc3c157ebe7d86a28d4d2fa2d40f2c5402d8b338cfd8d30aeadb6a - 63da9a5a0cd51e58168ddb305c0e70a2f898279dae6394e1b3e1ef3a0763847d5d2f15be493114360204d037d7d3c3a9e746d27dcb544ded - 0xffffffff - 63da9a5a0cd51e58168ddb305c0e70a2f898279dae6394e1b3e1ef3a0763847d5d2f15be493114360204d037d7d3c3a9e746d27dcb544ded - 6dd07b4891d8f45ad1ee64da38383ec50d6f29634767607eca19a547cadc3c157ebe7d86a28d4d2fa2d40f2c5402d8b338cfd8d30aeadb6a; - d91228b648f75350d775432af35be9aa283e9729fcd3b689f0c7ee02ea67efd33493980ae5eec92ad6ab42ccd253a7aab5a62c26be275278 - 07c5d1b4f9b8db88cd4187b1ae5e175bf703af12b26d066c1d55dd367569d3e23e3d0470f3c47e6761746ce7de39cf563500d026a6791980 - 0xffffffff - 07c5d1b4f9b8db88cd4187b1ae5e175bf703af12b26d066c1d55dd367569d3e23e3d0470f3c47e6761746ce7de39cf563500d026a6791980 - d91228b648f75350d775432af35be9aa283e9729fcd3b689f0c7ee02ea67efd33493980ae5eec92ad6ab42ccd253a7aab5a62c26be275278; - f9e764e20657319802b53ee29df43b0d83d994d9049b9820fc0c31b631265c49f6613923a042eadce5902fb81753784ff5a9c0de2c4f6b12 - 6ab2f8279e82aa65e8326e5c60bfa067e4967b3ea67d0369853282e5429736529a43eeee3fdf24ebbe5ca85b59647994fc99c90da83c6229 - 0xffffffff - 6ab2f8279e82aa65e8326e5c60bfa067e4967b3ea67d0369853282e5429736529a43eeee3fdf24ebbe5ca85b59647994fc99c90da83c6229 - f9e764e20657319802b53ee29df43b0d83d994d9049b9820fc0c31b631265c49f6613923a042eadce5902fb81753784ff5a9c0de2c4f6b12; - 772289865ac905fac203e4654b258890ddb91cac71c6d2af3826e3acfebfa222c937b40069ce3a757e2ffd960b5821ed1ad54e4ad2e3c6fd - 58dbf838ab81a754533c7f80fea48cbc981f724e4c150ddbb0afb5c711a8e21079446f77c427f7eb1892c096fa3eae5e2b070413611cd184 - 0xffffffff - 58dbf838ab81a754533c7f80fea48cbc981f724e4c150ddbb0afb5c711a8e21079446f77c427f7eb1892c096fa3eae5e2b070413611cd184 - 772289865ac905fac203e4654b258890ddb91cac71c6d2af3826e3acfebfa222c937b40069ce3a757e2ffd960b5821ed1ad54e4ad2e3c6fd; - 0bd6656d68c41bfc5389db274367f69191754919435ba58d2256017b5bc595d102c6f4f745b3ceb0c32bd0a6cdadded3a3dc925ef2b5c73c - 1d903009c74d3d135a192bd42466cd28303f482626a7d10832f1f6eae72c3b051b0373e62300a71226011475034f0bfc6c9a65601bb83993 - 0xffffffff - 1d903009c74d3d135a192bd42466cd28303f482626a7d10832f1f6eae72c3b051b0373e62300a71226011475034f0bfc6c9a65601bb83993 - 0bd6656d68c41bfc5389db274367f69191754919435ba58d2256017b5bc595d102c6f4f745b3ceb0c32bd0a6cdadded3a3dc925ef2b5c73c; -} - -mulconst { - cb908747a1af81f52715ef8440aed06aaacbcd7903c99cdecef5ec54e7845bedaad6475028b0cbdb0d53b6eeb71843f900fefd398a083d5a -417895 - e95e64fd1b2e2e79d1bfef5c96942eaf7ca5d40b1af774ed9c4ea2351c8ae81013f896bafd1f0b0e3a3c2ca3347c6cf88f988877af5e009b; - 46b23d83c0848e79af947191cb76b087483beec6224af749e59c0c5ae27ff8abada31da895f8132aae0457f5ddc30d18a8d52046fbe6ef55 384370 - 31c9bf2f3bdfd3c1dc115db96d7a1c15e2a9ae67dfebccddc9408a0dcd147d9aa62ce4a55a2d6ad54542317756a08d6be3b959bf132624e2; - 53e19751de62909506bebf74411d359014ec4b6afbb8ce14eeed8a3938013f0fee6897e3cc3adcbc90d7df321c4caa1941d0e5909551335d -49682 - 82fb902a8992ec1032a6837cec56189c45d1c1fdc47748e17dd9ecabc807a52eb537d6411f99f4d3b328e7ca76475924f90506a8adeb908e; - 7ff3b9b3d8ee248a48d0c8d308d8c3658374acc92303143061a46656ae2b35094ed7b5b27d23366c0e42ee0a9471a4355d81cda0e4390348 131908 - adbb3dd21e634dfe2c41593c65249f03a048338037d4a107892df36f10e3ff68402d6f48e74bc7a7858f2c3650fd2a10acdfd4213850529e; - f532f4f5ab5447b083ee4225246aaa4448696e4fc8bcf5b0ec1b52df88354e5327d7a3cf6e15db9945205968c275755ea3906a27437d29ed 383911 - 1f42b3585a2553ab19b14639c3e3aca636d88053c70fb758962713783bcd824b729fb4d01dd56a344d991bf2d32a2967acf470b39bee88a6; - ef0e2a829097e50575eae6b1ad3fa10b8e417b0363654e0cb07a563a905c02e367c6f1ad7be1469b9f5295e3db0726853adffb820715f7d1 -226220 - a7c5387af1b9f61f09d628feac1a050173021386775c9f534557b8841b812155325e3632eee7a2302ef8af0b4746575d6c2bcf3b29f674b0; - 3b4655b1c22542ca413f76bc24751a01cdab6b385b50301d67fd62ba31ad132150e38e12a849405112c4742e93b92849bd8b872c29edb2f9 -89924 - b51c0dfa2407a89435fedbcfd7835b6e0849d8626995fd00974f44c49d794d3c5dc16028e9fdee45bbcd269035e8bdba695a6653028d4d59; - 48bdc2073bff25ae9bf7fcc368d65602a71e48c343bc7181c361331f108867d56c588f698aa5b91222f5dbbc859bce656f2607b053222fc7 66432 - e845dfe65d563884074ffeecaa325706df4a129b73b056cab6ad999588216d72525222ce00ce4d2ffb09fcf6f010a6eeb2eb753fefd44b47; - 98a26f23f83673a480076b2fc7ccfef07fbbe70c4160d5af638c345f7d17b00931efff543fd47b7b8b362a70657a458566ada4aefd1c5eaf 492192 - 0ef483482255b5ca0f8338317f6eaf9c4fbf8bde8b8b04e26d2cdc0632186f1e62a9c3a1be23e8dc444ce50783135aeca614c884bdb77a30; - 6ebf7c4e06837120cc852a077945656046e64c2d88ce440bdfc8d38736a4d510a722bc8b0d225f11df0e704e4b04c48bf481da68fd1e150e -7098 - 8d4e2cd12323b5744442fe4e4fc21748b344d7f94794398ec187f0f986ee743cd733a7a16bd4495818ab033103f020c794c988c5d2c1628a; - 94e49f2bb473a7273abed94363c4dc3d13db159e3c3698a62ce5f321252aa03c7f63dd6eff9529c985f43abc7283d11140cb44ff6fd0f3d3 -392951 - 58a606cdc1bf1d5646fc08c7a6b3336fbe532c823c70242ea7536cc6dcdde7c4f492306e39ac0fb88367e41d63a8305d69fab57a52c8c284; - cd262298ce3b73294bfb523c30206fc3771144890a0ebcef19e02e5085973a6aeefabdf8cb7186d57be38ee84b114b9a7a22556c0cf88df1 -237681 - 7553420c53b255fb909d6e9008f043e7af25a2a9c29b177b830ff1ae6f6fdcb6aefb8386465f24634fb04c6078322ac691586f91cf7928bd; - cc9bd2e72ce15dd50877f95812b65c65cf09b14e2817784a5b296c123e498c532362180a932a455b2ddb75e26335dbcb21eb94a90ebb6940 246794 - 8838e720b6e497d9cde9fbddc2333c13cb5bdbbbe5afe41ffd61f5035c8c4987fddb8036c25b0505765bf1a5aa369c6bf7723c65278584a8; - d8ab6b8f3523e98f49140e051c0b744bb0068d20f499c0763aa28ec1d1dd7e86356f357149c317376be96cd520b3ae04a2c4d468d74745e8 -360296 - 4c0bc5f6fc52c6302b74c790d57ccc8fae59f2aeebb59c3393c56e70060f4d170ea41354f5040804a6e8dcb4a7c585ee71a6d90454e701de; - 6036fbfb9fcc223a1776ec67c9424788aabe553a7d6a0472159edc747ebaf97e99f7263ece635ef0b702a3610aef32e17f59fae503e18d74 -5433 - f6fa9a49b55077330fcda976a19ba7cfd98e44fa54044840df0ae9e19710193e684703f7fadbcbbc534e7be3adec0cae0d95ea414494f368; - a3433dfc89ec4d6d858bb5b018e2d474b7de7604ed4491957fe16453d3793740ef88136814f59b19ed3610252e74cbc3a36571d02e57913b 237641 - 7a01a802b7a5aca44675887d9cf94d04d4893e2dc5d7474090cb32798fa370690255f57d18dce2a57126bb5883672b5a74a1c780f48f7bd8; - c17ecc6099e9630a4ec20f4199abe1c10d414f6d734014ada1e6f097090a2bb4e638fb52d9bf56080d77c2b535f52cb091cbaad3c65072e8 517226 - 708adeac4ff99cac4c3eb649d55276f58a7d21a0507af176a53893c567050d352af501a9c242baf53121e8b56f5679b175dc01538350b644; - 134263fd765e5f1da64900df5643c5241d4fa8a9e96ee59f01667b64f9122e85e995b90d4bf5d5fe9f68825dfa6edd19d8ce009270ae2984 390674 - 2ffbda7ccbeecd8dc4600965679146753c496d35bfa546e13edbbaa259065b024c8aaa3a17a3384f4f14d5ee01371ac55fb50a153b4ac1c0; - 54326fffef9f0fe1207a07c8ac063d64b3fe81528e005f857319a74da2c3423a552b05f8c465908b028a2dcf15cb7158c99a1d2bdfd890da -255467 - e554e875e480c68c4fd780425ff8fb50f18bbafd0536a09489bc7cf197fdcb80dd4c7e31447a1a862066b6761ea39ea3b8c3002039c86b40; - 5c30f73ec3addb2d27e0e79579063f2d30fa9fb47c2b6a3a32553120a047cad83abc901e5a5b4a65f8e51144f7eb0abec9a4d105236b2618 -466309 - 5ec894f6abe2d88971da11b982c3322d1f533a326057816f6273585bfa186a7f569ddf93c27e8e74719ddb515689d5935c56e6b86936f22b; -} - -mul { - ## Easy tests. - 03 02 06; - f7ffffdfffffff00000050000000000000a0ffffff03000090fffffffbffffafffffff00000020000000fdffff9ffffffff9ffff7fffffff - ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff - bfffff6f02000083ffff5f010000a1ffff9ffcffffc0ffff6ffdffffc4ffffff02000082ffff8f03000089ffff6ffaffff7cffffff000000; - f8ff7ffeff5f00001000000800000300000100a0ffffafffff130000fbffff0100000000e0ffffebffffffff7ffffffffeff1f0000080000 - f7ff7f0200e0ffffefffff070000faff7ffefffffefffffffff7ffff040080ffff1fffff8ffffff7ffff0500800200000000f0fffffbffff - 0a0100240020f5ff7ffdff4fffff4100003a00201400400300a8feff030180e6fffff9ff8f02003001002c0000f0ff9f0600d0f8ff670200; - - ## Random tests. - 94aa99eaba90c5eb2efd7101c8efeffc1e44c8fcd84ccb8ef27b9792ae12534c0a250e5400407177bd655e51c343f776a3fd26474da4dc74 - 284a0f7df2d7d7c760cc57b1606625884c1643020230a9eecca7de6098f5338ddf9297daecae8a07e199494cb6db91c2c683566bf79545d2 - 213a31ed7e494f470736ded872f2c4f3675562a7b42bf01ea246be0ecaae2a61ae500690df9f99ea9fa8e5e1b9ccf3614bc34148b7693c91; - a434abefb0de3c7f5e33f9230ead871bb3f06888c0d568b9a74fa32b676dc600fed2d54a042e1b97340852c4d6ef796a18561884d760d4ad - 99d4c85f047d3dd8e530c50ae7d80815a30ec6ba820316f5da922cfa7a51ab45290ac2ab8a53082716a6d7f77ac5a285fac298eca4fd9c52 - 97b2991fcc858d5667d3674484db9435ba71ab0c836c534efb823c123f9e94d0d3445257c55c73e8bd62f1d7acf1d75fea5eea669bfb9912; - fe9911abbe57f1ddd61acd062d59637b129a1571af65fb70169db0d8b12b498a66d1eefcf9c8cbea01179f113afef0ae192550828885689c - e371e9a11f662e38caff28cf4cf5ca8cdfe4a8b99fa12a33765a22ae25506874fdcd85388ed406a955d293320e01957f119027ec4803c2a9 - 171b49441f9891d927d2f6436eee1dc59e7872730be496638017b42151cdf00e9abb212bafc47c05a4e185bf7cf21ccd97b0c8ea426e4381; - 1c300df44d28406d070b10c1920e01ea8b9056d9e1d6f9704dbda3f6328c26a28e9e4aa07dc79e03c09c5639cf8b8c783c8b430b9d8c21a8 - c565b0357a1e8aff3b3a6164ff34c9598a1c15a1551224fb38d25dfa3b0627c9d992dbd215910236aeeed23f4efd99640054b6648946346c - f7871e06efb6f737cb4e04f708827092e94e3c70faee57f70096b9d674d0ac5b228824924bb705de49de9f9c0e834462093a9a5551fc7d5d; - 9014dd22854f1f21fa1475d74eba669101c871c2a21ffd5d10f0792e3cc5d34f15b4735759575dda169e2dd868a5ae64dbeaa2a654cfde5c - c6f59ecf6add5ff92813cd6f37de9c6f8d3ae9cd33e4f3236ff43127f463f297c3067493868adf7823bc285a3d609a57d9b0b841a9b628a1 - cbebe67e30ed82acb0de699a5d874121257b78c2b0642583713b58fdcd089a6277a5c5e571538e4af9025dfc63cd78931be51780055dfb2f; - c8fc23a431d744e45e8bcd2dd2ca612db40b26287970aa878a5cf6283c51b2bd4edb76f705f29bc3911a9aee8fb7272009520f3590ac4c4a - c1015900ea58d6305b8b558c992bff50a8614843cd3d11274830dff6e1db405f8b268100fbc5e44c477cc2a9e83f825c7840e560fc2b2920 - 6ecf49d92efb60a15a9de38ff37d3b23b339d889ad8b11cb332df260b9c49fd28b287a559fa5a5edf732b3bd1014711fb7d088a37cf6ef72; - daaea5c9549776d866be36a032027a65eb8325b1684d3c37cba068e69aad7d4f104ff47c14f669883cdef5dae9a0c7840379631ef97e6bc3 - f8dc00891a9c55481a224309a8024ea257850b2bc62ab10bb5ea5b836776cd46994900d6656b7f7e0d9092fd824b16d20ea14528a0de7729 - 83d3eb62429c2ece396cd7069dfa2985630da2fb0949b52f1df9231c82f32022543d4a2302241d0146b4db97f44ec5342b6444f463ad056f; - 786f4ebb20161c96f93ffe3ee2b0cae50fc454d910b3fae4fbd8454b8ab7975c6cab8f6a1b593996b24b22603137a52ee732f9d19f9a6e43 - d78d3df4f455c8f5d98baaa17200d4c94056e21768c4ca783188bf15c28dc86c581fd9c150f923f905becba19361ca94f7434d8a74744669 - e857a2020e1877b50151772bcf06763285c1d8b2b5ffdb63e13ef4985ccc3b965fdb053305f16feea4a3ac0edad21423c80ef847181bdff7; - 6b48bf18ec4557e745cad3e106511bd5a9bbe136c77cf639745f891f54bb16c11e19770eb5112df8bb6755b97cb1e23c9c7efe589693764e - 95c2a38f889c451f792c3d5d8b3237eed3f99e2b4857bfc48f75d7c0de3f293d2cfa7f97d65d75e0e3df633d84931973ac542ce07ba974b1 - 2fdfb1146b569ac98b0811e600e2d8e578023024ed704f97c7f7d56a2b4a33ac6ec68d14f0789441a904d175fbf8b91603c532ecdffd27e4; - 1fbba059c333843e3cf0cff19bec99bd0cfc89c3b390200165680b742fe540b32042959022e7393c9e13ef7fa3f1dd5ac46595803210c536 - c723bb3649b1d95647636abffd325e363931782f02002ad6d75d2082c980a7a2c5e1d51045880b36d4f62c16250faffcb2acb824d8d3d5d4 - 97041eef8892ecaaa97c4effb8c69160b3878fd302bc5f0862bfe4894bf23193738d8dd95c9eee9539e23fff67243372b97f02c3a3934555; - 26f5bc0c2c49899690fa423478ab1cf7000be27609bf683896a6ce3f619510b061ca04debb6c64540e724d113cd4b8ff3485337851367700 - b8540188b9ca77a82899c7fd26412dcbd6a3c9b45be595f63bce7426d7c16eb20c3a2dc86afe9064edc19840f75f05de828c276e98451ee5 - d973580e88abb6c83defc009607082ffbdcae6ce9d577218580459711682f8708a15de9c62e3ca3b50e91a7bf5781deee152ac801a64fe81; - 6c044d6556abb8efdf5b180695293464a8bc4b9cab201822053c7295973ea0a8866425629cfff1d372a48f51dbc6a7f828691194c32c2c5c - da28b84dfd48f206972fe282449991597bc7f0734916b6f7a253897fca2ccd6b80aa477cfd08549b6d25bd18932128e59889e2dcfaf76157 - a599fabf997468487b9376500b58a51e0e00c86d9eac6f50157aa1017d99ac8b95e7842b36071a192784ef72433c06a1dd042990b71ffe8f; - 50378c6ac56816962d428ea523a0cf87121fb3c53b37bac6d3a05fcbdfb8a5fb20aa014f1e1b01a3963534d403baeb7c436f72cf3cc5db58 - 78901fa015c6f0d3e1072aa87d865579fa405615691a3f27945f9b1431ee8bce8ac9965a1f9b0f42ff10bc77c43cc93566eee9a9b79866ed - 00127644003ed4b518f04abbd058a46015fb328883b92070bc5cf0fd98d7307dfabbc65f3e8551c622792efabe55f03953e498e360410790; - 5db2f6db35af2e1c84ab6832b967bf987cd03adea7113fb8806ce8fb3ffa426dc10997e13afcd39cf5cd65f65f8a09e650fad8e5f6ef2648 - b063695bc97a18d6ccb0785ee4588951dcbee420ce8e37b25cce325352968015c94f9bb784f3a2bfa34c6a1edf710b63f139fff6d4f7b2f3 - 999284a309482f67ab6460e73ad1ad267052b59fe50cd58a245e22079e2b50b119e312ff60a65037cf9faeaa259d22f689eaedd7924f1093; - d5baefaae7fc9000e0d55f287f740dfb1899ba6e9e36338959a16ac5e5f45442a37086b5519a0b439f38b129328aebf468dec4b59c89a249 - 4febc8666dcf2b150faec9902a5f57e97275e7b122724c2b77d9b78655b455d424db93f859b8de6b09c4bad6d5ba68349c65c41caca67f8b - 19e6ed86dc819e6b4368d196679328710f63bf1fcba6652265508b509ecd0e3e8b8bf17f8f1eeb361af107ef684a729a3635cb55de3f8605; - 9974be322a0f471cfe0855456104219d8037ca1cb5aacb9ff5da86a047ce159430cfd92f67e764244996668ac44d8d9787dc1b5754d215c1 - 78c00f878fb41fdb0cd22c026881d5022fc470755e6261945b9bfcc3868f591f08288e4d64a65c9f3d0b05d3ab7f27d801aef29e5e98caf8 - fd51b84f21b06377054dc879b8a176a7799951d5669486b210e4528b9f52bd60f88c2a068f722d85fa12761a4caf2f05bcdeecb7ed62646e; - f4048d4a1602eeec43cdf20c3ac9f7b359935bae3648070276faf07a5c58fdf79771ba6c077ddeae47617971e2145f4960587637e7028822 - 32635c7425108f5d19e35e4d91a4bdf3310bc884c9061d0697556ae25e17cd611e090c1179ca9a68225b283c8ab98a7b1e97508592c60c66 - 8d6a91d016aaa7a0da03b06f5876ce8e8a71d1e5e5eb430d6c5ae16e1d6d9b61e77179b4f6fe43ce37cae27689983d41923f3b30e9d9f930; - 9023c019bf7ef6df45e0e44111903c622220bd3dde046679540302451d001e47a153b0ac7dcfb9831e2d262d8e27002197d9640900e4c1cc - 1f5e2ca612ec6f14df4b528cc35001e763b9414a81381a1a3c7008c0cc525bdb00aea94ce2348f380dda43b5edf4fec7c8cf5ea2f5fec4b8 - bf2c241efc180988232b83cda91e12dd0aec0d22ab68353c9841c4ea0547fd1b377fbca125f8cf92c426f8eb859f85a3853516ec104d9b6e; - bbdecfafa9284e3067081b7d1bd7ce0e488829859628a8f6a38bc1a3ca6ec3130dbc1345b69abb7224b047fd3f2dadcf9cc11a8ec46a6436 - 49a956ee69cdfecf29440d60fde9db1edd94619af97f625d45dc83c64994fe6c1ac858150cb526ca3c58a9fdc09d409ee3ed0b0cbcdb711c - 7abfd47fdfcceb278c917afd059e335110bec63fea48dedf7f8275da8922201ea06be39e3d1bccea2d38f5eb7d7aa5ef4e6fe6792a9f0ce0; - a9483d4f0c94eac273adc392c3f425be610206683cbb6806dca47be3b54ad142fa2c54a7a473675556bcc8cfd50649af3c58d7a91e84b428 - b986365aa08f088fe04aaaf2e00468af3fb41cda961b56ece5bedfd83cf9a0fb959ae70c23d9b27cd1eaf8b611d9e578aa0b9d899b81d5f1 - 4af529627637ad3f3f1269319f4fd426d31e276287ee525d0c64974e55fca1cd58694eadf47e44dc3e843e01c36b22f9717067a907840ca1; -} - -sqr { - ## Easy tests. - 03 09; - f7ffffdfffffff00000050000000000000a0ffffff03000090fffffffbffffafffffff00000020000000fdffff9ffffffff9ffff7fffffff - 8c000040010000f3ffffff040000f4000040120000ff0000800a000099000060060000030000000a0000e7010000180000290200800b0000; - - ## Random tests. - 776cf7ee39df23538f76e6be87ecbb1ed78477b858e3520f24b2b36f09a7dd61daf7bd5990af13c11b1419d8215eb69c30efc3917097797b - 870001f8ff173e02ce682526a513ff99c6e9688cbec13839ecbf0fbc11d8f84f6cf53041b5bdcbc624f9787db9babe61cd477cb9395590d1; - 1e5ef8dd68207b3c3d3c670acee7ecb277ee6bc10be9fa3f3d800e1414bf402298ca443de6fd57ca899188c884a93d4b9c9d1b00a7c9ce44 - 4a6d6da8002b6a0f3f5c3a9631254ccc62cf66c93279c4b77dda55d32514c8b388b543002f8055321c7195ce1fd26f51f48732e664cdc62f; - e02eba6cd5ec1cc39ab92db439896520e50a5f9e9ed6d31ad37d00ebb2a54cb68f1c0ae537006ec2ffb14aaad2de16ff06194929b702b95a - 95632fd74045a49782f6f9d0c86d554cf6efd07f9eef57d669828c77537d4c3a69138d755855640064f5e9bc8fbe0eca96fb04053f565431; - bad2a1348fc0b54791f9f2875009c8be2d30f14526fbbc22c439c1ae2b865436cd74f428766e4e676b795fe9333312f6334d4e4ec2378e26 - d87a8f7ca45620b4646fad2c22792538bd16f37879dbc4d87c21cafa60c282f6415fde2fb6293a8b8a6e5b3901f88d75f9243023b68f41d3; - d6d221f2bf71eba62e49db570e13ca69f4a8a33543298619cda7c8d2524c9446b11ae7b7d301579f047565b7044b5286c2478896800ad992 - fdb163312b884bc6d74c4c269011311388ead9c069884f48487f9ac0d62b39aa175e81976fb599716aaa68db4c02985a6f0ffe522b0fb21b; - 20cc05120202e684981bce1db74af493d218ed8e0f5e76fad46bfeb98c69e504113b0eb91771c602cb422ae09846fbfef7c47afd09689277 - b07d84ff34dc5f0cbcc60037400ee04ba09f34d1d7a0c6a80672a3f6c1da630681d4207ce1325d301b36f0acaafd7579a108646f5a26b755; - 72c4c3e4fcfd36389f558e0d4016f3f088145be47b2de85ee7ab963fcd8c7adf449d5b7c37ad8a32cf97ea9bde5c220fc896cf1b91633e19 - 1e8f68736c3b259b661c0c1ec065a642e717f9e4d86003411b8e15ff89537d8e129c116d2f8a9e7e1b46879deedd66fa6ce2b60ab680cfb0; - 8c524f059e7ebcf3af3072dbd2f76ebc530adba6d26240c8675b5451d5558db648e7a61fefb1369cf2939ba1fadcf8e40385db5d57cacace - a19188e6821f5cc2c53b7e59ae6f70e95fb929c0f282627ccfa2c6d9cb59dc871e9dcf3e2a8d6d66b7a6907d4d36c9de03c3d74325d8c1f1; - dd47eb6f4f68cd3a9abd6af401bd6f3c795d89474dd41a89025b24c8349a0de417c3676bb6ee36002d7c8ff6b4fb4491e693cfa617e079f8 - 871f46c93dea48a0d937b3f1f724f66615daa9200f0b48cee01c3b20e4a05dd6ce01bd7b2713e096cc2bd1c5ce7ca0c075aed0fc1ef6fa51; - 577870fdb83454eed0711eb51d7bd91f9843769737566823e41d0668fad45c82fe069347769244af7230e6fbc40f5a71151279ae65e9893a - efabd464218df4a490b9870d541c45e9b7ab29bae25d9e976539a553995ded0edc5610916883642a032eae4e96eb9e4e1443f747dec98135; - 8ba84194db2aad7b46005423b1251555ea931b933e0083fee76b9863fb528927f27a4a0617b8d75de306103b592a0fbd51b72bfbb051ee2d - 3a29e940174d846df65d51070295f535a03e988fc401ef62f5dd2456cf52668390e61e7b6912186d6d5260f6d6977004003bb106abbdaf02; - 9f17e0943b4e39051abfd8f4512ef177fd5c368ebdf4b0af49df2e1d89e30c4e68ec474d81203964bfe9c1fecc1279e5e4f598ac97b48cb0 - d794adb47cff3f7666dd0a934896015e59f278d9b1d6dc7a06328da96d6e6520670598129b7e1b26f9537216364199cf5c0010f23692ec90; - a6b51625066e4cccb7d45dff5b182e2a6bf4b1cce7090a187d38dd39f08afad6f868c0277bf70d5fb88b6e67432526e4feb39ae707e34990 - 67315efb85e16a1e97130092cc351759d9c18261845329f63eba1e77d91ad2c7df51ffa50b655de81bc807ea2b3e137214a2b08b400f2b7a; - 28a0fe53cf73a0419fdb4cb493c6425be8aa812c3693411816c90621097a9d5687feb16ebf874a30ec849297742b7aab5921427d7b474190 - 69300770a5bc2c9c599431e5f879ef3f3ec065e3a2cfe82e3499018add58acada581e9e81d40799fc74674b9721da018a64138519abdb108; - fad58259395fd5bbcfca35b095253a3a121b62f1694e14cd9e2f85bd08e8a15d1dff98e3b81eeec678821a1ee9d6192c8351bde45ce0581f - bee7e0d6d4de419981ba2aa3964adfc7545e21b72b65c774b2029c22e06f251cebf04cdffd23e2051b57f986cbf7e56f047050714a275e72; - 91e548171a8136d2d26e6bea02cb16ec9591e9cd5b913184b22b43d1029bdb214ef737f6e45f473f7d95b8fde075645c3b0c2dd2bd224278 - abe2936ecf2ac3012455dcac906f691f2d96490539c9621658fd7f66790bbfe0d2df07165ea80e0c3282642d45b63b7db476b53e4f94f1c5; - a52c855daa9ede16ea8de7c681436d5d31eda6ca5b441f972e5cf5639a1c56f689fcb411965271853de2893f22b81d7d0facafdb49292e39 - 382480e92d44199fe5f7c357ad2e5a7277beab1a3055d48e679516151ca85ee3cb498b172087d588738daac2ec1da9638552d76be97626ad; - c65888cdc1a575fc9a06dce8800607f56fe88839948b7e4e2713aae44b0ae6b7c6b68786b11b430d22766e9e4d76af118a972729c67c06b7 - 31311e4ff9600089b533cdac6c05de3ddfe6a450ee7fc90cde1bb297e2deb750336ac3ed2f6fa9b88ece846be6f6aeb392f6753eb6fa475e; - a61c81d621df61ece4b7274f63ae4e9f2e2df1d603fc9303ee361962b2d70bd783ff1b5d8f3ed27f17e7773b2b1c85af7fbd70387bdef5d3 - a014ef20adc291c0238be3759ceb9f9645524b961761c8a991ce67efbddda568359fe36e762980d75a58a7ba10b803c9f883fe4d2239a08b; - 96ced952366c324c5fccd48ac5d475cc1944e7e455dc093f0d9680d6d6abf1e45c76a286ac46acb4de061b9eb673a2d3124e6c3b921ad71f - 6debaeff6a7d2bb2c1389cb3338fc87b2a32e651ecb8d43fc012efc9b9c59c79487b742f0b30d0b64ac283af0d3b877102c6a7ff0f606eb9; -} - -inv { - d665678f17043846f953fb09c88295d7fd0a53bc70ec7d396aff56e7dfa376f3a338f0da0af9e07b66d3ff7443e3829b541bd667201999d4 - 6839ab730bf666c6ca987d254d83bf32b981b466c147f04b823981da75e12c9ded469a0a462861a987c13f05739f47596401fec25a5eee5c; - bb8d567f6163a92603a388405121bd58abfcf05c596bf0624bf65b6a8fe03e6940648382fe01e5ab58e37ce235f4acbfb9e02624001c49da - 3f60d0fa0036da2db915e232bd841d09f006d4ba018c1d268af86d36990579d669ee63393b95c202645dcb1225fe9e64d14270905e63eb79; - d456692d8e00bf9cd86d22a9f4ad9e9879e6298274854ae82729ebbdb0cc46877caeb381506dbb097b10c180d615661189da65d431e3003b - 6e0f5a173fb60be882a2b570200515dc7ad473e2192470ba89e6dda6cfdd6ff77026a1d76acdded7b5881a54d68605140a4ffceae70906d5; - 359ab073b7465de1358a5772aef79db09118541c062421cb30a972525a351f16b5545daed5f9ce8e91a283818df6cdbf443831fbe5f3e848 - 2b0ea74e6f4533498eb3f34247a9674f3a2cf2ab0e4fde65ff11b0d1e756430bc5452ca4b85bd3a1f10f6e4e3b1874df8d19f390a9021757; - 3509fb8b7688f354738d4a8ca4091f66c880db794aacec6115e675090394ca77e1c83b955aaf4d8e75c6e4e9200be1ce5693532a561d970d - cafa18317193054cff7884bada249422ba889c19693d66610fb774fb4bdfeac0e67a5ba6f84ace126c125c46b4cfd627ee777e231a6ffc1f; - 42e2babc095d88b61caa8883e91fd045106db9c4eeb4d945703c1dee3229c58869e21f73909ae2f3c4437d301a2a3724d67f6ad310f63835 - 28c43a594b6471412f504dc10fd79d2c04ec029a7723cfa0a90aef036991f1b56cf156e2cbc7533671086edb54036e9f4ddc9bfe2e3ffcda; - 9c01d006213bcfda413517ec815e8cebc06707f5649398a9d14a5d64754375c1ded8aaefd838e8eba84746de07a0f9b32caa2325c4c8e540 - 0a3b64374ac2149d602a9f0ee4fcf6d814c476f451531a086b04b0dd598287b1758f77780b7de08573326a9767e816309d871fb1962bb1a4; - 7bbd8a2de4bd2ffee4e93d0dd2fa9c5d4abcf9ab86c097921fe7d603b7ffdd07006c7d79d1a10267edce9b3069b134bed727c8f0ed1aca13 - c909ffafbcc09a96723b9afba8ec0d00d5ce0c9d85de3c1e4de24cf44fb934bd0d2397b380885b7419cbbeac339fc85e2161f08c2f3515d7; - 6a64650ccf103604c3b030415f7114c88c7094fbd0fd2f2b6b907a27fe104ef4e0684c17ff9f26f15eee5e7442e679ecad3e49a0629cb5c3 - 9db77e47433997640b4c0916c5123e8a4d9c7c0bcd12b2dafccbababd6c9dbc3f4ec7991ea68b3ad4ffc6f0be4920764c65d98bdeba8a811; - c3823c71f6c0f3679cb9c776e437e718f856c8fde038418942d062423113352aeb60ab84138f2bf73f268386cab0f2a1419660e966c24187 - 558bff4fffa85d6f67ad44938f5b4473d250a87a120af9ff645a7db37a43808abe30c19c90bac94adb190840078214518e189d6c9fc5bef2; - 44bd920b0eaf47695f93d063cd85c43c58470c23796f4a106b298d5f2b091210d103e9575c369bb0be66b2323d89cc29602a8071697931c6 - 67464f2dab3a95c9ac7c783017105df7d561d7ae499ad89c4698da2c0710a1654c89966a7bd30d2d5c0511ed9f020309cde84cecd66be8d0; - a6b12fc35e62532ea7c1fd49dd834bb7957da914ec3daf2e4f446b54916d016054cb59ffd4e3d9eecd4a18b08033ee8d9ff84db072cc4f86 - cc70960f0bb743da1b23d11eb87530a820484a861abd68d2ed7079b487d88481d915b1b34c29d9938b5fa54d05c75cb1aebf0b722a6770b6; - 1773dc978cd9f94186b83fd5e10a456b48058acd9e3bbacbecee2cfd0f8303c64721ca64c2913d57764336ea055700c2fcafc60d9f4b817e - 49e443096eb28c167ee62c63bfe4079418fa8e7f9e58757e13327680890b02ce7c9e5bbbc51366e0b3f5315edc456b6f65a09ea1b1a24438; - 552158406db36accc32edde2f0ce46e23a1d406f60e54ca6a789386df36a57434c826c9586c4b371df3179f675e5956fe7dc3022f785d9e0 - e0025a1007d3dff5e44947a0292bee8db5abbd1a0fca1d3ab0a64a37925396cd96c21af54d36656eb0b60c63fd5651622ec5487d53f976e4; - 6b006d36f60750bb5c59f6eb31e2efe6098ab67de7a7a8a27201652380a295c408ec78351c2a799d62227dffd4731b7605e5c462dce2c1e8 - 21785aae5f73da711f6144894728627824b685fac3d95068a9d0c4e0ee058301a8953322a5ee5be75452164a55477f1a987103a718bf98ca; - 700cb76911e718ce8829f8d767c53e333dd2f7f20d2c020d1da3cc9ce96b9f6c7aad67450d5aab8f8c60e8ad77d4b5fdb86fae92a0ac30fe - 257f202b457f19f27ceed047e6778204c2b71646fcc96e19c6f07518780bb5b1c456fd6e93ce2f1cb0aea1a225137511dc71e446c1fe22c3; - 0c909e0326649d4d375452c5b233a86e90b0fa88b20aa54e02685edd02b70aa022ed8af31e994b70b20101a5cfd8e16ba53c702840b4a16b - 98c41073ea843b4b5ad6b0589699f48a1576e3d834f8e595b8859069b71bf5e16126aa93b20259ff0a03976ff6d7f78239ec1059f8cf1193; - 4529761361781e67037eae69c5ca9977b1e21468834eb83cd369471e5092249015cd263563bff9348a0f51e4a8517e27236ed1ecfe30a780 - e20d5896be18bb273bb0ba84f6c070de45378bac6d793685e654764e5aa847d48403a68560b48dcb12573ac737366ae701072300615b4659; - 6fae83f7eadeaca22b6781f400b01f9de186b12e31fdf56e0ebe98a8420baacf5069ffdf26d0215c16b64027dd69ff29709a64cfe8f52dcb - daa266a02c4500d989670eb63ab78219892d9c1ca2e17f4b5200cf1d920cfece5e80050be77f81a616de840bf19c23835ed17d57aeeea0f5; - 23ca16e8b4c15f8f2b216441d851368d185a7f8587f398b0cf775875678241094538708da0cb2260c5e056b59c003c30c8f84f5088d0c99c - 9de1360b4718fc762e6ffab46827c5e4672a77d797aa608b31c132d1ad8138e7a64ba1f4278a07a6088f8cec9a01ea9bc1427c55241433c5; -} - -sub-mulc-add-sub-mul { - 07ebfe324f64b54e938951a1e437bab4d35c2bbf5f210c5d78ca2b4eb7ef9c3dab61724be4fa7c2e43086b58db7e961f62a44b029f9901d5 - d44920bba642b8162d1c3e956e060bbe6f15484298c2ec55575ee378556b0e8826f627bebda963b7d4d9f1c768a49cd408957105d3c6008a -41997 - e3647583d41ee4e813045d4f7a8b53af084c1dfeab8db93472810e8c54d253a2c100a6fc341bd92223341150d363f00f1c2bbb9ff9f8e7ca - d61c770618adfc42ef3ac4272dfae86a674f8ae4c273d26ad7b9a29943c4740e0c9535812b9ef0d17fb4bfcc77bf60646aa96a11c29035a3 - 76c496c2c798e23c657eb80c44940229ba88f21bcacb21cb6b4cdc8b93d10832f3c4d31819fbeacb6c5a516c7889f0e639abc29ec4d7b604 - 5a94d8487539381061d764a3806e31e1b2add772d2f9cb9c4fb96336f7b36534a9a0f7caf30b7e086c875670a0d568f895502983b1dec2ef; - e1792f9e9c7b70293e041a9059df95bcac07b4112f25d35375ade1794660a0a10c520adf06fd477c79a170ab88108e4b74bc47ede8ddc0a4 - 6cffa5fd3f07f203fcf08c399690b793a152e65aa99c6f9b465d39861c3c46691b635cd02c9e77083ecdee73a54aa1aab5ce6044cb2cb8d8 23228 - 31cd1c1937619b8fe711d22912104fd03fcfa3f14f81f3bc7ec9839c5440836d7c9b92158c818933aa614f9a085f9a1c18d71dd11d09a6db - 2386136ccd81814300b5f3fa148c4025e6d7a2d9da344e56b42811deaa3d4ecbd5365f91d941d7bab20b305ac6dd0457a4b81cc611bb5f11 - 16bf2b1e10c77597990088a8df91150a6e7b6c3008e6584909b2f7184358abf6b59674e210aeec3219a5202440139aecde4a4b6e0f46dbaa - dd373d5908b408e51e3c6f8da1c439f845d40467057a34a96cd53680661b329f073d0bfe6af98543d5d38c3d0476c19d20c54226e7bf8d7c; - fe6d00268bafd5878e0a4ddebad8dff25399a1d18e69f94b471029058e9712b98263d88b4dea5d08d8fe70b3a62ba2d136c2c2713ca809ea - 12be184341bbd7ab5a668f3c3e4b13a60c70cd4e1f229f90901be24a285f3ff0b7391aee82529076c14232f61a11b6a8edffd56af603a25b -252008 - 178e5309ab3a578b8b09149da9539d93309c5214b61e3c045034847354f59d58fee27e31dfcf5d5daa24b5a605686b468a3db727583709d4 - 8da5b2f4c39e442c729a09cf04405136c55cf7b76fbe949ec3b34fb17b2edabcac44f4b4a19afb58c9d86eb87a0c58cff2cf196e6cac7da2 - 3b0be5158a7c13a6c71455025ea5b4466eaa321956fa785f9b74872532e3767d796da94ac47e6d25a368ea1ac79c44fda8d2e13edae5c219 - 7ad75999f1bd89b130fa03274247b36b2c2684163097d46deb852083b5fab0e8755d2150dcd2ee563757f05eb1d132df284ccf818cd56b9c; - e4ef0519fc7af554a4a348cfcea95c6c18752f4a35a946b7d2ad1e6aa77d64ec4012eea4faead2d91c66b0d57198b19317a79e136a98caf9 - 008c72ff456f0f941781020ce6387d8065772af7c68955668a7cb05b53f00960f15fc463029a2e2a353a2fd3bc43790a847ea35c75d6cd26 287411 - 5ee722a21955b3bec9ed5f151686af9da9d3f5e6491e3d9a8d82237b1e3dddb58b827264ab5a1aca3eb8c1de7922b59744567e0467a4357f - 9381ebf793f7b3f523f4621e934217ba463f96279ce2e7d165fc00ea037b20254948132dd2f0481ad9816e1f66da64d081e4d24866094af9 - 62e4648d4716c6e0f99357c8c099c4988cfec4fa21873b7928350f174679f59629a54d78bc8d239800709a585d4890fb2b634f68ec13cd78 - 850e54cf9388bdaf3de63c3e73823c0f39f0b9bf15a9f0262f24c828d2fc8cd7d1ac939193804fac3d92467e26ba5e57d1dc4f8664a270af; - 5f3811d6b8277fd93a197bf4f3dec4bf4dd5fc6a0ac92ee3d0e64ae48fa9e1373cfd63da945db924bbac41a2b78f6819ccdf2820b1a3c4ff - ee669edf4430678ff1190be8e39c06dd00cd9982ab5b625e5a6814ec456f68f9467f1f38519f4bcb392772479ba553060391752ab4fc70aa -254559 - 3d11820f867d39b2b1169030c24a9307eb387f44ee0fc8d53a946e56065e8cf9af6069c9c8099de1565f3d491c33248965ebf941987ade48 - 9582a93732bb52eba39d81c161dd0a996b50dadb13b4eb54085ecb9e86117ed25cb7c78d1a5cc3807a97d740710c2fbf65f97e8de3591163 - 501c2ca79204d22e6c52d32d405310853e7e29da884c0f14782e9029929751821f81a9493c8dd76e582bb48465ce5b40d7c5e398322ceada - dcdc428d085f7548c99d963af7b8af997c1503307d75e298efbfc042d425d385a6b7321d86d5af13809ed3ec6bc5d96afcd026d08caeaa30; - d17c198598d3b5188e5807c445976b769d458ca952a7b99da4b19ffa3b35b6100bd3605136143912640e402a7cb91675e61527244844409b - 9cac226e58f5ffbc41bb82b769ed12d061eef4d2d0369eb12724bcd4db6a1ff85f22d6b25003cbea0308a1b7dcce1450283d4e96ac8d4b8c 516083 - 9f92e7a68af5c7737f3f3e959d2b55230ca11e0dd467bd52a20b91816ce61ac7fa7059934c7a952e43058ff4f277170ec5ecc4cab51baef5 - d4fb3628a45e2290c7fd201ca434ef83911ac2687218605782b3cdca577e692a389756e6b9a0891311727d623fe8ea601fb13efe238adee0 - ce572b3cdd011749634a577c727aa4516d00c4236cdf3b4664c2be35d3efe7e0b140b5ef2d4a0339a8a29eb26025e60e7d166913251966be - 790d7ef8990c44fd271d5a41c55a6d552f60fd8980c1c3b91919fdd5e291c75b0a0cbc4224dfd2ce93de2eef53249f3d9d0955f05b4cefaa; - 396fe89631a66fcf4368600d3a8cbfa6fc903cc8d157f13ac0e4a569436c3230c0a9319a55ebb7e61d428e74b8ce740e973ee5d2b0a99a61 - f644b35fe8d9bd57a0e6837ef03d889df2248a06a0e52a9cdc80307cf68c496f34aa82f246b8d6e040d166ffa1920b7d921938bb33f8e8a0 -339102 - 716c673c21cd0d92d86f8060beba37c65b7d9eb8b1d4f8aa5665478278ea5c3a2a2c4f606aa179bc8b38f4f37b3e077959ac7c8c81a5fba2 - 6379d7843800b16ad06ff70511c7ff656fc93ff95a05617b4adf7e2b6810cf2cf81dfd6b0c7d478d52f2f4989a13a3ccbc3a4e30f85a3279 - 5b982eda7d33ef68c0d94400610744b91572443614a128bc90011a953bc9422910640047809049a513c413b4390a09395da3de6958c44b64 - 91cf825bde194c05cadbb9dcee5f08f152d2bacabc144b4ee498b82ddf4074846ccc75d366184ee29bd322deaf99d6ae81563cc2e7b2e98d; - b8bb334fbe75e81a417ef59e14b52898e34dcc8bca4bb2caa987dc31950a9afa4dd356735dd163eba9073056a2e7f259f1485ef37acf8c24 - 0e872ffa891f664be01868170c452c25cbd41dd0e4df0a66c0ed67dfd3d007c25c50e4b0615450906c69788080546b9a4ad425402c422580 287059 - 52356b0443301992c676f6cfa7eeca79d586324bbb5f8aa71163b89d863ffc7879e55c363ce260fd6ab160e18ef0921d81a4d634799fe816 - 35be6d14d3dc696bb20c90de43c7e08b2427ffc9c63a5c37767ee6756894b6d94c748e9d2c4d8519cbdc2efaa215874bb1923cf7aa5a826c - 8db5fd04e45f9f93c7a2a2e238c7f001fd7c059d02fce693340c106ebb98d7f6f3029d3e820e2e3e912901c33c3dfce56d68a7c42a2f2e0a - 29ff4f6533b4292d0e8f2a7abbd1269d1455d8ec34cadca9df875d544ba10395c36d1e750fb66ff0a9d97a92538a63ab48db8583fa6ebd5f; - 74dfa3166dee585d6d4c5f310259a6f9a407e5c520559f22a3f290733d2f0ba8a276d46820bc73f9231fe25dcc8e9c2e2542eda5024180ed - 50881f8d2fac3278cadb483b7db6e179306b6e967f8fbdb53f70f443ba9f1b1073921a0a1f46c8833856e6a0ead7ab6f445abf833d2550f7 -430161 - 10b16716f590c13b435ce912fd4adb5dcb4982d8e0302dfccff5f9d388efaae716e8d9e2915de30d365a04468f4bec0f4489d81c0e159bd0 - b4e67998a7579734cf8f0fc281bb29e1c3dd4dd4d9c1434e830d4d093ea2b908137dad647ab349c5858d1b3ce20f7378546033114dc0fa68 - 76a10a58f6136ec6b73d96ed1d506b758ddf6f54326f7b2a12d28dec9ed880dac2d16f2f57004c7df846ffb4c5c7de814a0245668df0e804 - 33216663bc217e49c81d64e3957f3a16452193b677c68f3df80315c7496995a752c7f42807d22e6a23ad2f5568ada163ba168cd1ff3631c0; - c047f2b5077afcb0c246abb9104309be15f2c2da8e703e74459d34281992fbbfb95b1012067415c5b17650d10f5d2d12b84c3c825068b881 - 831adf8c6481178176f11f1d7010fa4b51c6e30ae8a9aec3a748a47bad643ff69cc8e1ba47bf9d33183de1c1220e989c58d6b23e8a602ddd -445266 - db32546436b5d585cd4fefcdf8affd7c467c31699787dedd133f205641fcf74ee246a5f62dee25eefb54091b5dd0cb4dc7cfad9cc68bb9cb - 9ea3da4650bbc07d7cefbff97a9bebe5aa932772ce0e47a4bdfaab1be5457f652f9882d8e4ca286b7bce092a4fe93b1c0473a2d5d33d92d3 - a8eeaf02c9e281f2522def4792beff7382ae509316b80ca3e70b36c080706f9cc8589518dd9b27e61c3f3e28c8608524bc201076d6ae2fcb - 463c925f11987399440da6a502b87ee798b2dfc37f012951af57dda87651de7bb96c2c30890e6b65771e70ee08bf41e2bde696dfcb177e83; - 63428356e8b4c5147870a0e653866093d5ca20a691524e3adba1c95af70fc706fdb420391c230dcb70cbad21f028b03e7554efac7bc8bed6 - e99ca8f8dfe11c545b49031f68a605229adac19568b5cfb9b02b9721416c225179968b5583d0588ead12790c5df7c13bae466f934e997b4e -445574 - 7ace55b2ba3365a01a872ef5882a8d47518fec37bd816d809d4716301a7b6811926eb5aa593fb2c852ae2455fa42e92be1038d96ebf31966 - db9244d18540fb524ec9455f493b570aba16ee4f4491247fa18efe63a43c70e533ad6660f64e836675bd788113993836c43a3c5868efe068 - 8cc4affd9631c4ff75313f43588d977f24b58a0ef1c3275b7c142e6113f20d72fe974f11c9f7cf3dc176e1799dcb4230d5bb138ddee2eb34 - 179440042f537fcd021678f32a1346547ac1a4aa5dc3e5bed329c543ec35058efa16af2ca066ffb7087a3daf68345aa3a0a21c6133fd3a59; - 993bb02c2ae6974f6988293ce6eae32f520758329e80ae242801f45937baed48cb9bbc111731aea52883ca30286b7593746e6522fc3ccd54 - 2bbbb81c8e51356355a1e49ebc1c6e160119eca0df8c07d171783665c9d96af7164e6bd7384002ed5c19f531bda705b90e06130bfcb2ad17 -159409 - 6b3eb1b9dac2b8f6d86a0d983bd2b36a98c760ecf5f4aa30e22726e8048cc2e633a7a7bdc862d6bb02fcb0d9e854ac9dce8cb9982645ba44 - fba6ac4753539d9dea1190d160994937af74be3f73856e56dd7ef4fffd1f6e2d99f1466fff7ec4bacd115f4e1f8708adb8c9afa7b17ee887 - 7f28c3d4526328a9f03cbfb3a0b04fc2aac564effcdbcedfd61a160d0499c83742255e86764c344887a93f7f1851903372e40d7034b16f03 - 2bec5989a2f2fc934dc0e673f07f0ea7ebade4d4bdf7bf472f7e779a716dbc4aa01771bd1dcc634780b0da41389c108a76fc67235e028142; - 96ab5a1f5b6cffe08fbe3118d7bf2d09e6da8dfdb0ce69cae1c2d3fe71864db59befd7e252410d04a858ef680a754b2d42f7f4ab7cd38e0d - 673d469ae9193bb79aace5d641041c94b81f6f9a9d12e5a05db86674899ed5650b8d4d30bb00f2b51b0261245dd3a2e18a10f8109cae1535 197264 - 83f7aaef3c944d9d6ef3c329224067a204f738f3625488ba01845e31fa07dda26e08a4e395687b322f594fed860bf1597ab33536c5f24c53 - 9bdc4e2e4e412b65af636a24480a40ab73df53fb209619044317f90df9bba10e5892aa502ee86e1039a8547a4e119caa359e8095ef0f5827 - 659ea4924522edb2aa50430f9bf5ba3112c60af504dd290215a52c8bc275fa8fe0042348811a7cacd0d8bbf95255a547ae9b82db70326b25 - a28bd6727521f46a3ab3ac32a3452c03b7ceca3c06c4e5f260c1868935269b8cbeb3d303cc6df3faee2595788af6f24a52ef8237763793a1; - a0de95d94e3506ed563b974d07454fd347f7b37aa1e9453e0145d23e1867f2aea78434ace37877022343cad84d9100c7683b33c115014903 - ceeac84a960af7e749645352ddbd4a9f7fd77e96268ed8548e4247b6084e13a193233ba02c49da24c89f2a62ed50029ab38eb6566167aaab -5830 - 8568f4c8837fbef756a3c03ee6a59f7ce0b5ffe370afb5c18545e4fe88eae49c65c642494e1cba91c4eb8b2fa94df6ca22b21d3e7b717f3a - 70170f374d567a159bd8e354eceee6aacbedfcf9a2be6b530808152a96e93a301518f0042baecaf90170bdc4cc8c2e1003bfe737cd258929 - cfa4cd159f5793a1833bfdb97261c204d3a80a01e1488ce8c628e68225bbcffa785093267eb3f75702e70b6abef59bc0a223ecfa09aac356 - 7302a30f89bf3163baf814605772b0ca175aec6a030e53a2677c49351d88f1c095a1974e1dabcf5859c206f4bd3e932f7973766e81e0c278; - c297bf2bf6e64d4446a2e5d1c6448f5881c5973ccf6e75730dcf2bb74096e603a354461e02e818a94ace1f47053d23710719135cdd366d92 - 8966ea0a08b7f43706340232c68a264c54b4e609ad8c901d0c0768c2aa5660434e5d4ce7510883238b17a8c92f8013d2488730d3a28ca291 -266784 - c52a9e11dce1938ffb862357a9a696ee72c9fe18f7163d29052c949b4ac0fa151052dffa3546cdefdef598c28ebcc620d064783e8ee20413 - 04f0bdf761a2cfebb822a12bb44b2def0906ae99cf84e7bff6d033e4082c2fed1961942288b0e2beb11a0e96db8a5037fa61631cd89896e4 - add0f3d532987482db8148a8ef3724e27ad497bdcd804686114acb3a86e4e561001a7af6420bbeef57b77bf8444c4b978e5cd136083d9118 - efda70e401d9e5beea539fb3ce7a145bfc90422e049387f222db53edae81078046fb1e2db538ebd7ba36ff5509691c83ef9c51f3581edc2e; - 06768f69843008554828e6665685231b32e60fa878cdc11536819fb04874df4c6f9023b356f1cfb03a1706d04f472f1f1cba2148e161f936 - 61d686b96bd02a99efe67123f3962e318ce9836b1ed0b7a39ae98483f38efa78a89063badbf97325b4743b2342647ed8a44a164e76328781 -301528 - f8987e1314d3a3fa7ed1784fd04e4b381e9bbee6a785400e51d66402bd95c13de03e4a8213fbcbcec493f0ab8f3aef54794d8baeb9579b57 - dee30a4b1359ae1459b790e8bedbce16eef2e299082dd2a07e46063c79af11524e438740af78d161afbd5b410888ab9f64eb4129dd1caadf - cc52f548a25b964b2556be59c5243b63a323701d696d8d3f866be512554227b8aa3567960aec684ba50701be5528f188a9bcba490517949f - bf88a0bbfcf8d048525ba4b7f64988bb8db5ab4abe40c20530b512f130dd54ed8f0bf9c36f51c20735415e25905d4047d896bf6eef7325ec; - b2fd5cba9d6d5487c5257954d1d170a99cd27c2e990aa7b20006d8615b929f9024c5b3a0b063dc9c364a668cde34b4a26ec4e374d38d2a32 - e4796d1ed6d6cd3443a095e6f91e80db3ea043b1f9026e4015a4abff5b2ecde79848dd0b856db0f47a6f29e1759fbaeb2ac82d2d8a939d89 -338517 - 65c169eec5df306b2d17d58f7c1f833bea184fadbbc8924803cc0ff2804d24531e69004059169f29423b5692d54c92fec7936933eac92317 - ab7c743547424e08a733876339fc4434d1c0ede96dbcfc7a92acbb6ec4e1f6e330d13cee90e4378863022bb49b57b6b4617b37fb5e6f7d0a - 5fb79ffb10f7c3bc4cc98025f7c7f71bdb4041a5161e7fdee2a701692d16ae77d23680becc76f14e66a7e961d8841adad5485043e13b7694 - 365da4af25fe7f21edf0706495f44475b2d3a9b157b3008dd745cb8e756e3da662108d6c05d573aedfbaa0fd0c8420b6b7ab8d418d273be2; - 0b1fe73972fe3400b1a9563b759cc65dc7f685031405e14ecbf1ab977c7c9afceafa91f51d1127f09058b637c9cdc39fa665be7c2a4d55d6 - 349cebcab0d98aea0beb0d38dde902e4f6caa23cbb066e68ef8d384613b4ecf6d21780ae1844c4b3eb9598cfd62fc001505d3ce4e66746ae -242599 - 7c7018b38125bf7415723b398f888458a647f4a2f2ff0b7dcbd6eb7ae873c44068429efde0be1f2f28ae1c8e01db9f812442fabaf51ffadb - c125c39bcf8ae742747cc2f711e470b8386403e275a14e5651f1dae89231cb3ee186a3d2c1b1a74002ac70e1fc1a5adc89a17734aa231650 - feb78a43f6e633e7b92ffb2789f6486cc7597ce0ce9ce2486828af900d97c9ee8fcd0f52d43d01e141f9987ad194dfaa8a31b9d649e487ac - 32318ade75655d7aacba10759063893db2482b2083a924915afefc63891f9951b58bf5525f5b330f16422c65bdf77a5508f1830849c2a941; - 080f596d6be6f4554477689f6ac45ff60a880924f6e609701bd6d1fe32eb4f1be13edf39399eb170fa5b5b9801e38301e7ed768383cab6cf - f14535e25853aa97a8bc8128610eaab77977d07d3a89608a837b16fb2c2878f8edf11a2276f3c42ee21ba275dd4e6059574f887abcf6480f 273443 - f273139e62664cb2b5f9c268c37abfcddc054c0f30ed8f0fd643017a989512cf115467ca704b3442b1c92496e378f4df6434b27e9c9fbacb - 8af391a0b26881d67fa19196d5dded3e00cc3dc60247781ec1d000e635b6f39f7186e948bbb5b03894f0a000b27838dbda844836c5c29d99 - 56513a9d50e48e2464df2069404f09c21d4bf112d2223ea316e78cb4ebbca403327ab344af7e15b17b9865ea8d801cc7d4f6f7283687c3bd - 9c3043751d7889855a337637b51e1fb9c7bb47d75ef529e4e8545822cbb2f535ef1579b9c660813438e2e9f16bb35f4a7843d3e7820e1406; - a5d6bc11f9251ec7d03e87c267b2eb05d51fdbeb24970e2c87a7d8923f7adbf4bff904e5ae498f5984072d7a21c703ba6765bc3292e43bfe - 2be24a92df5b92545f72e710d4a5c71f881d544305e891dc9fcf2b39a24a5e80fe44f856411fc886566f428b5443af8140543e549d092170 -140922 - 629534899a55d04d6e0c879ea02b9eb05675cf6074ce400d8caa25b2adc59eedcd88f203f9440db9fb06c5bfcd65512324d01f871b485650 - 867e9ed2dbef2b0d485a7d5dc71266eae2b6053c2f1e09dfba6192f015419e06868aaaefefdc3b03cb26e50cc4861f38eac76ac69e5ab1fd - 61d009f31c5be4eaca1f44ab6800f0116dadb7923e427db6e525f03c17b380eaa6d0c8f06440674c80f0040c272b8b956366a82ca28dccbf - a7628d76da5a4a8dcabfcd28252b9fb1f780e2d32f72a0f1f8da7ff7d354c6d35a72efb2b75e87c332f93557c1a5e1bd51813e18ee1fe241; -} diff --git a/fgoldi.c b/fgoldi.c index 5b2889f..6a8d35b 100644 --- a/fgoldi.c +++ b/fgoldi.c @@ -1,3 +1,41 @@ +/* + * fgoldi.c: arithmetic modulo 2^448 - 2^224 - 1 + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Remove the 16/32-bit implementation, since C99 always has 64-bit + * arithmetic. + * + * * Remove the test rig code: a replacement is in a separate source file. + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * Arithmetic in the Goldilocks field GF(2^448 - 2^224 - 1) @@ -27,8 +65,6 @@ /*----- Header files ------------------------------------------------------*/ -#include "config.h" - #include "fgoldi.h" /*----- Basic setup -------------------------------------------------------* @@ -37,7 +73,6 @@ * (hence the name). */ -#if FGOLDI_IMPL == 28 /* We represent an element of GF(p) as 16 28-bit signed integer pieces x_i: * x = SUM_{0<=i<16} x_i 2^(28i). */ @@ -54,32 +89,9 @@ typedef uint32 upiece; typedef uint64 udblpiece; #define M27 0x07ffffffu #define M32 0xffffffffu -#elif FGOLDI_IMPL == 12 -/* We represent an element of GF(p) as 40 signed integer pieces x_i: x = - * SUM_{0<=i<40} x_i 2^ceil(224i/20). Pieces i with i == 0 (mod 5) are 12 - * bits wide; the others are 11 bits wide, so they form eight groups of 56 - * bits. - */ - -typedef int16 piece; typedef int32 dblpiece; -typedef uint16 upiece; typedef uint32 udblpiece; -#define PIECEWD(i) ((i)%5 ? 11 : 12) -#define NPIECE 40 -#define P p12 - -#define B12 0x1000u -#define B11 0x0800u -#define B10 0x0400u -#define M12 0xfffu -#define M11 0x7ffu -#define M10 0x3ffu -#define M8 0xffu - -#endif - /*----- Debugging machinery -----------------------------------------------*/ -#if defined(FGOLDI_DEBUG) || defined(TEST_RIG) +#if defined(FGOLDI_DEBUG) #include @@ -123,8 +135,6 @@ DEF_FDUMP(fdump, piece, PIECEWD, NPIECE, 56, get_pgoldi()) void fgoldi_load(fgoldi *z, const octet xv[56]) { -#if FGOLDI_IMPL == 28 - unsigned i; uint32 xw[14]; piece b, c; @@ -158,35 +168,6 @@ void fgoldi_load(fgoldi *z, const octet xv[56]) for (i = NPIECE - 1; i--; ) { b = z->P[i]&B27; z->P[i] -= b << 1; z->P[i + 1] += b >> 27; } z->P[0] += c; z->P[8] += c; - -#elif FGOLDI_IMPL == 12 - - unsigned i, j, n, w, b; - uint32 a; - int c; - - /* First, convert the bytes into nonnegative pieces. */ - for (i = j = a = n = 0, w = PIECEWD(0); i < 56; i++) { - a |= (uint32)xv[i] << n; n += 8; - if (n >= w) { - z->P[j++] = a&MASK(w); - a >>= w; n -= w; w = PIECEWD(j); - } - } - - /* Convert the nonnegative pieces into a balanced signed representation, so - * each piece ends up in the interval |z_i| <= 2^11 + 1. - */ - b = z->P[39]&B10; z->P[39] -= b << 1; c = b >> 10; - for (i = NPIECE - 1; i--; ) { - w = PIECEWD(i) - 1; - b = z->P[i]&BIT(w); - z->P[i] -= b << 1; - z->P[i + 1] += b >> w; - } - z->P[0] += c; z->P[20] += c; - -#endif } /* --- @fgoldi_store@ --- * @@ -202,8 +183,6 @@ void fgoldi_load(fgoldi *z, const octet xv[56]) void fgoldi_store(octet zv[56], const fgoldi *x) { -#if FGOLDI_IMPL == 28 - piece y[NPIECE], yy[NPIECE], c, d; uint32 u, v; mask32 m; @@ -269,80 +248,6 @@ void fgoldi_store(octet zv[56], const fgoldi *x) STORE32_L(zv + 4*i, u); STORE32_L(zv + 4*i + 28, v); } - -#elif FGOLDI_IMPL == 12 - - piece y[NPIECE], yy[NPIECE], c, d; - uint32 a; - mask32 m, mm; - unsigned i, j, n, w; - - for (i = 0; i < NPIECE; i++) y[i] = x->P[i]; - - /* First, propagate the carries. By the end of this, we'll have all of the - * the pieces canonically sized and positive, and maybe there'll be - * (signed) carry out. The carry c is in { -1, 0, +1 }, and the remaining - * value will be in the half-open interval [0, φ^2). The whole represented - * value is then y + φ^2 c. - * - * Assume that we start out with |y_i| <= 2^14. We start off by cutting - * off and reducing the carry c_39 from the topmost piece, y_39. This - * leaves 0 <= y_39 < 2^11; and we'll have |c_39| <= 16. We'll add this - * onto y_0 and y_20, and propagate the carries. It's very clear that - * we'll end up with |y + (φ + 1) c_39 - φ^2/2| << φ^2. - * - * Here, the y_i are signed, so we must be cautious about bithacking them. - */ - c = ASR(piece, y[39], 11); y[39] = (piece)y[39]&M11; y[20] += c; - for (i = 0; i < NPIECE; i++) { - w = PIECEWD(i); m = (1 << w) - 1; - y[i] += c; c = ASR(piece, y[i], w); y[i] = (upiece)y[i]&m; - } - - /* Now we have a slightly fiddly job to do. If c = +1, or if c = 0 and - * y >= p, then we should subtract p from the whole value; if c = -1 then - * we should add p; and otherwise we should do nothing. - * - * But conditional behaviour is bad, m'kay. So here's what we do instead. - * - * The first job is to sort out what we wanted to do. If c = -1 then we - * want to (a) invert the constant addend and (b) feed in a carry-in; - * otherwise, we don't. - */ - mm = SIGN(c); - d = m&1; - - /* Now do the addition/subtraction. Remember that all of the y_i are - * nonnegative, so shifting and masking are safe and easy. - */ - d += y[ 0] + (1 ^ (mm&M12)); yy[ 0] = d&M12; d >>= 12; - for (i = 1; i < 20; i++) { - w = PIECEWD(i); m = MASK(w); - d += y[ i] + (mm&m); yy[ i] = d&m; d >>= w; - } - d += y[20] + (1 ^ (mm&M12)); yy[20] = d&M12; d >>= 12; - for (i = 21; i < 40; i++) { - w = PIECEWD(i); m = MASK(w); - d += y[ i] + (mm&m); yy[ i] = d&m; d >>= w; - } - - /* The final carry-out is in d; since we only did addition, and the y_i are - * nonnegative, then d is in { 0, 1 }. We want to keep y', rather than y, - * if (a) c /= 0 (in which case we know that the old value was - * unsatisfactory), or (b) if d = 1 (in which case, if c = 0, we know that - * the subtraction didn't cause a borrow, so we must be in the case where - * p <= y < φ^2. - */ - m = NONZEROP(c) | ~NONZEROP(d - 1); - for (i = 0; i < NPIECE; i++) y[i] = (yy[i]&m) | (y[i]&~m); - - /* Convert that back into octets. */ - for (i = j = a = n = 0; i < NPIECE; i++) { - a |= (uint32)y[i] << n; n += PIECEWD(i); - while (n >= 8) { zv[j++] = a&M8; a >>= 8; n -= 8; } - } - -#endif } /* --- @fgoldi_set@ --- * @@ -421,8 +326,6 @@ void fgoldi_condswap(fgoldi *x, fgoldi *y, uint32 m) /*----- Multiplication ----------------------------------------------------*/ -#if FGOLDI_IMPL == 28 - /* Let B = 2^63 - 1 be the largest value such that +B and -B can be * represented in a double-precision piece. On entry, it must be the case * that |X_i| <= M <= B - 2^27 for some M. If this is the case, then, on @@ -447,58 +350,6 @@ void fgoldi_condswap(fgoldi *x, fgoldi *y, uint32 m) (z)[8] += _c; \ } while (0) -#elif FGOLDI_IMPL == 12 - -static void carry_reduce(dblpiece x[NPIECE]) -{ - /* Initial bounds: we assume |x_i| < 2^31 - 2^27. */ - - unsigned i, j; - dblpiece c; - - /* The result is nearly canonical, because we do sequential carry - * propagation, because smaller processors are more likely to prefer the - * smaller working set than the instruction-level parallelism. - * - * Start at x_37; truncate it to 10 bits, and propagate the carry to x_38. - * Truncate x_38 to 10 bits, and add the carry onto x_39. Truncate x_39 to - * 10 bits, and add the carry onto x_0 and x_20. And so on. - * - * Once we reach x_37 for the second time, we start with |x_37| <= 2^10. - * The carry into x_37 is at most 2^21; so the carry out into x_38 has - * magnitude at most 2^10. In turn, |x_38| <= 2^10 before the carry, so is - * now no more than 2^11 in magnitude, and the carry out into x_39 is at - * most 1. This leaves |x_39| <= 2^10 + 1 after carry propagation. - * - * Be careful with the bit hacking because the quantities involved are - * signed. - */ - - /* For each piece, we bias it so that floor division (as done by an - * arithmetic right shift) and modulus (as done by bitwise-AND) does the - * right thing. - */ -#define CARRY(i, wd, b, m) do { \ - x[i] += (b); \ - c = ASR(dblpiece, x[i], (wd)); \ - x[i] = (dblpiece)((udblpiece)x[i]&(m)) - (b); \ -} while (0) - - { CARRY(37, 11, B10, M11); } - { x[38] += c; CARRY(38, 11, B10, M11); } - { x[39] += c; CARRY(39, 11, B10, M11); } - x[20] += c; - for (i = 0; i < 35; ) { - { x[i] += c; CARRY( i, 12, B11, M12); i++; } - for (j = i + 4; i < j; ) { x[i] += c; CARRY( i, 11, B10, M11); i++; } - } - { x[i] += c; CARRY( i, 12, B11, M12); i++; } - while (i < 39) { x[i] += c; CARRY( i, 11, B10, M11); i++; } - x[39] += c; -} - -#endif - /* --- @fgoldi_mulconst@ --- * * * Arguments: @fgoldi *z@ = where to put the result (may alias @x@) @@ -516,12 +367,7 @@ void fgoldi_mulconst(fgoldi *z, const fgoldi *x, long a) dblpiece zz[NPIECE], aa = a; for (i = 0; i < NPIECE; i++) zz[i] = aa*x->P[i]; -#if FGOLDI_IMPL == 28 CARRY_REDUCE(z->P, zz); -#elif FGOLDI_IMPL == 12 - carry_reduce(zz); - for (i = 0; i < NPIECE; i++) z->P[i] = zz[i]; -#endif } /* --- @fgoldi_mul@ --- * @@ -543,24 +389,8 @@ void fgoldi_mul(fgoldi *z, const fgoldi *x, const fgoldi *y) *c = y->P + NPIECE/2, *d = y->P; unsigned i, j; -#if FGOLDI_IMPL == 28 - # define M(x,i, y,j) ((dblpiece)(x)[i]*(y)[j]) -#elif FGOLDI_IMPL == 12 - - static const unsigned short off[39] = { - 0, 12, 23, 34, 45, 56, 68, 79, 90, 101, - 112, 124, 135, 146, 157, 168, 180, 191, 202, 213, - 224, 236, 247, 258, 269, 280, 292, 303, 314, 325, - 336, 348, 359, 370, 381, 392, 404, 415, 426 - }; - -#define M(x,i, y,j) \ - (((dblpiece)(x)[i]*(y)[j]) << (off[i] + off[j] - off[(i) + (j)])) - -#endif - /* Behold the magic. * * Write x = a φ + b, and y = c φ + d. Then x y = a c φ^2 + @@ -614,7 +444,6 @@ void fgoldi_mul(fgoldi *z, const fgoldi *x, const fgoldi *y) #undef M -#if FGOLDI_IMPL == 28 /* That wraps it up for the multiplication. Let's figure out some bounds. * Fortunately, Karatsuba is a polynomial identity, so all of the pieces * end up the way they'd be if we'd done the thing the easy way, which @@ -630,10 +459,6 @@ void fgoldi_mul(fgoldi *z, const fgoldi *x, const fgoldi *y) */ for (i = 0; i < 2; i++) CARRY_REDUCE(zz, zz); for (i = 0; i < NPIECE; i++) z->P[i] = zz[i]; -#elif FGOLDI_IMPL == 12 - carry_reduce(zz); - for (i = 0; i < NPIECE; i++) z->P[i] = zz[i]; -#endif } /* --- @fgoldi_sqr@ --- * @@ -648,8 +473,6 @@ void fgoldi_mul(fgoldi *z, const fgoldi *x, const fgoldi *y) void fgoldi_sqr(fgoldi *z, const fgoldi *x) { -#if FGOLDI_IMPL == 28 - dblpiece zz[NPIECE], u[NPIECE]; piece ab[NPIECE]; const piece *a = x->P + NPIECE/2, *b = x->P; @@ -721,9 +544,6 @@ void fgoldi_sqr(fgoldi *z, const fgoldi *x) for (i = 0; i < 2; i++) CARRY_REDUCE(zz, zz); for (i = 0; i < NPIECE; i++) z->P[i] = zz[i]; -#elif FGOLDI_IMPL == 12 - fgoldi_mul(z, x, x); -#endif } /*----- More advanced operations ------------------------------------------*/ @@ -783,206 +603,4 @@ void fgoldi_inv(fgoldi *z, const fgoldi *x) #undef SQRN } -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -#include -#include -#include - -static void fixdstr(dstr *d) -{ - if (d->len > 56) - die(1, "invalid length for fgoldi"); - else if (d->len < 56) { - dstr_ensure(d, 56); - memset(d->buf + d->len, 0, 56 - d->len); - d->len = 56; - } -} - -static void cvt_fgoldi(const char *buf, dstr *d) -{ - dstr dd = DSTR_INIT; - - type_hex.cvt(buf, &dd); fixdstr(&dd); - dstr_ensure(d, sizeof(fgoldi)); d->len = sizeof(fgoldi); - fgoldi_load((fgoldi *)d->buf, (const octet *)dd.buf); - dstr_destroy(&dd); -} - -static void dump_fgoldi(dstr *d, FILE *fp) - { fdump(stderr, "???", (const piece *)d->buf); } - -static void cvt_fgoldi_ref(const char *buf, dstr *d) - { type_hex.cvt(buf, d); fixdstr(d); } - -static void dump_fgoldi_ref(dstr *d, FILE *fp) -{ - fgoldi x; - - fgoldi_load(&x, (const octet *)d->buf); - fdump(stderr, "???", x.P); -} - -static int eq(const fgoldi *x, dstr *d) - { octet b[56]; fgoldi_store(b, x); return (memcmp(b, d->buf, 56) == 0); } - -static const test_type - type_fgoldi = { cvt_fgoldi, dump_fgoldi }, - type_fgoldi_ref = { cvt_fgoldi_ref, dump_fgoldi_ref }; - -#define TEST_UNOP(op) \ - static int vrf_##op(dstr dv[]) \ - { \ - fgoldi *x = (fgoldi *)dv[0].buf; \ - fgoldi z, zz; \ - int ok = 1; \ - \ - fgoldi_##op(&z, x); \ - if (!eq(&z, &dv[1])) { \ - ok = 0; \ - fprintf(stderr, "failed!\n"); \ - fdump(stderr, "x", x->P); \ - fdump(stderr, "calc", z.P); \ - fgoldi_load(&zz, (const octet *)dv[1].buf); \ - fdump(stderr, "z", zz.P); \ - } \ - \ - return (ok); \ - } - -TEST_UNOP(sqr) -TEST_UNOP(inv) - -#define TEST_BINOP(op) \ - static int vrf_##op(dstr dv[]) \ - { \ - fgoldi *x = (fgoldi *)dv[0].buf, *y = (fgoldi *)dv[1].buf; \ - fgoldi z, zz; \ - int ok = 1; \ - \ - fgoldi_##op(&z, x, y); \ - if (!eq(&z, &dv[2])) { \ - ok = 0; \ - fprintf(stderr, "failed!\n"); \ - fdump(stderr, "x", x->P); \ - fdump(stderr, "y", y->P); \ - fdump(stderr, "calc", z.P); \ - fgoldi_load(&zz, (const octet *)dv[2].buf); \ - fdump(stderr, "z", zz.P); \ - } \ - \ - return (ok); \ - } - -TEST_BINOP(add) -TEST_BINOP(sub) -TEST_BINOP(mul) - -static int vrf_mulc(dstr dv[]) -{ - fgoldi *x = (fgoldi *)dv[0].buf; - long a = *(const long *)dv[1].buf; - fgoldi z, zz; - int ok = 1; - - fgoldi_mulconst(&z, x, a); - if (!eq(&z, &dv[2])) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "x", x->P); - fprintf(stderr, "a = %ld\n", a); - fdump(stderr, "calc", z.P); - fgoldi_load(&zz, (const octet *)dv[2].buf); - fdump(stderr, "z", zz.P); - } - - return (ok); -} - -static int vrf_condswap(dstr dv[]) -{ - fgoldi *x = (fgoldi *)dv[0].buf, *y = (fgoldi *)dv[1].buf; - fgoldi xx = *x, yy = *y; - uint32 m = *(uint32 *)dv[2].buf; - int ok = 1; - - fgoldi_condswap(&xx, &yy, m); - if (!eq(&xx, &dv[3]) || !eq(&yy, &dv[4])) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "x", x->P); - fdump(stderr, "y", y->P); - fprintf(stderr, "m = 0x%08lx\n", (unsigned long)m); - fdump(stderr, "calc xx", xx.P); - fdump(stderr, "calc yy", yy.P); - fgoldi_load(&xx, (const octet *)dv[3].buf); - fgoldi_load(&yy, (const octet *)dv[4].buf); - fdump(stderr, "want xx", xx.P); - fdump(stderr, "want yy", yy.P); - } - - return (ok); -} - -static int vrf_sub_mulc_add_sub_mul(dstr dv[]) -{ - fgoldi *u = (fgoldi *)dv[0].buf, *v = (fgoldi *)dv[1].buf, - *w = (fgoldi *)dv[3].buf, *x = (fgoldi *)dv[4].buf, - *y = (fgoldi *)dv[5].buf; - long a = *(const long *)dv[2].buf; - fgoldi umv, aumv, wpaumv, xmy, z, zz; - int ok = 1; - - fgoldi_sub(&umv, u, v); - fgoldi_mulconst(&aumv, &umv, a); - fgoldi_add(&wpaumv, w, &aumv); - fgoldi_sub(&xmy, x, y); - fgoldi_mul(&z, &wpaumv, &xmy); - - if (!eq(&z, &dv[6])) { - ok = 0; - fprintf(stderr, "failed!\n"); - fdump(stderr, "u", u->P); - fdump(stderr, "v", v->P); - fdump(stderr, "u - v", umv.P); - fprintf(stderr, "a = %ld\n", a); - fdump(stderr, "a (u - v)", aumv.P); - fdump(stderr, "w + a (u - v)", wpaumv.P); - fdump(stderr, "x", x->P); - fdump(stderr, "y", y->P); - fdump(stderr, "x - y", xmy.P); - fdump(stderr, "(x - y) (w + a (u - v))", z.P); - fgoldi_load(&zz, (const octet *)dv[6].buf); fdump(stderr, "z", zz.P); - } - - return (ok); -} - -static test_chunk tests[] = { - { "add", vrf_add, { &type_fgoldi, &type_fgoldi, &type_fgoldi_ref } }, - { "sub", vrf_sub, { &type_fgoldi, &type_fgoldi, &type_fgoldi_ref } }, - { "mul", vrf_mul, { &type_fgoldi, &type_fgoldi, &type_fgoldi_ref } }, - { "mulconst", vrf_mulc, { &type_fgoldi, &type_long, &type_fgoldi_ref } }, - { "condswap", vrf_condswap, - { &type_fgoldi, &type_fgoldi, &type_uint32, - &type_fgoldi_ref, &type_fgoldi_ref } }, - { "sqr", vrf_sqr, { &type_fgoldi, &type_fgoldi_ref } }, - { "inv", vrf_inv, { &type_fgoldi, &type_fgoldi_ref } }, - { "sub-mulc-add-sub-mul", vrf_sub_mulc_add_sub_mul, - { &type_fgoldi, &type_fgoldi, &type_long, &type_fgoldi, - &type_fgoldi, &type_fgoldi, &type_fgoldi_ref } }, - { 0, 0, { 0 } } -}; - -int main(int argc, char *argv[]) -{ - test_run(argc, argv, tests, SRCDIR "/t/fgoldi"); - return (0); -} - -#endif - /*----- That's all, folks -------------------------------------------------*/ diff --git a/fgoldi.h b/fgoldi.h index b05fd77..1857008 100644 --- a/fgoldi.h +++ b/fgoldi.h @@ -1,3 +1,39 @@ +/* + * fgoldi.h: arithmetic modulo 2^448 - 2^224 - 1 + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and lightly modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Remove the 16/32-bit implementation, since C99 always has 64-bit + * arithmetic. + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * Arithmetic in the Goldilocks field GF(2^448 - 2^224 - 1) @@ -34,7 +70,7 @@ /*----- Header files ------------------------------------------------------*/ -#include +#include "fake-mLib-bits.h" #ifndef CATACOMB_QFARITH_H # include "qfarith.h" @@ -44,7 +80,6 @@ typedef union { int32 p28[16]; - int16 p12[40]; } fgoldi; #if !defined(FGOLDI_IMPL) && defined(HAVE_INT64) diff --git a/montladder.h b/montladder.h index 02d2961..4292158 100644 --- a/montladder.h +++ b/montladder.h @@ -1,3 +1,33 @@ +/* + * montladder.h: Montgomery's ladder + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb (2017-04-30). The file's original comment headers + * are preserved below. + */ /* -*-c-*- * * Definitions for Montgomery's ladder diff --git a/qfarith.h b/qfarith.h index abcd293..fcedf3e 100644 --- a/qfarith.h +++ b/qfarith.h @@ -1,3 +1,40 @@ +/* + * qfarith.h: utilities for quick field arithmetic + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Use C99 signed integer types instead of our own local probing. + * + * * Remove the support for non-two's-complement targets. + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * Utilities for quick field arithmetic @@ -35,35 +72,15 @@ /*----- Header files ------------------------------------------------------*/ #include +#include -#include +#include "fake-mLib-bits.h" /*----- Signed integer types ----------------------------------------------*/ -/* See if we can find a suitable 64-bit or wider type. Don't bother if we - * don't have a corresponding unsigned type, because we really need both. - */ -#ifdef HAVE_UINT64 -# if INT_MAX >> 31 == 0xffffffff -# define HAVE_INT64 - typedef int int64; -# elif LONG_MAX >> 31 == 0xffffffff -# define HAVE_INT64 - typedef long int64; -# elif defined(LLONG_MAX) -# define HAVE_INT64 - MLIB_BITS_EXTENSION typedef long long int64; -# endif -#endif - -/* Choose suitable 32- and 16-bit types. */ -#if INT_MAX >= 0x7fffffff - typedef int int32; -#else - typedef long int32; -#endif - -typedef short int16; +typedef int_fast32_t int32; +typedef int_fast64_t int64; +#define HAVE_INT64 1 /*----- General bit-hacking utilities -------------------------------------*/ @@ -117,42 +134,7 @@ typedef short int16; # define CONDSWAP(x, y, m) \ do { mask32 t_ = ((x) ^ (y))&(m); (x) ^= t_; (y) ^= t_; } while (0) #else - - /* We don't have two's complement arithmetic. We can't use bithacking at - * all: if we try to hack on the bits of signed numbers we'll come unstuck - * when we hit the other representation of zero; and if we switch to - * unsigned arithmetic then we'll have overflow when we try to convert a - * negative number back. So fall back to simple arithmetic. - */ - typedef uint32 mask32; - - /* Convert an unsigned mask M into a `mask32'. Our masks are unsigned, so - * this does nothing. - */ -# define FIX_MASK32(m) ((mask32)(m)) - - /* If Z is zero and M has its low 32 bits set, then copy (at least) the low - * 32 bits of X to Z; if M is zero, do nothing. Otherwise, scramble Z - * unhelpfully. - */ -# define CONDPICK(z, x, m) \ - do { (z) += (x)*(int)((unsigned)(m)&1u); } while (0) - - /* If M has its low 32 bits set, then return (at least) the low 32 bits of - * X in Z; if M is zero, then return (at least) the low 32 bits of Y in Z. - * Otherwise, return an unhelful result. - */ -# define PICK2(x, y, m) \ - ((x)*(int)((unsigned)(m)&1u) + (y)*(int)(1 - ((unsigned)(m)&1u))) - - /* If M has its low 32 bits set then swap (at least) the low 32 bits of X - * and Y; if M is zero, then do nothing. Otherwise, scramble X and Y - * unhelpfully. - */ -# define CONDSWAP(x, y, m) do { \ - int32 x_ = PICK2((y), (x), (m)), y_ = PICK2((x), (y), (m)); \ - (x) = x_; (y) = y_; \ - } while (0) +# error "Targets without two's complement arithmetic aren't supported" #endif /* Return zero if bit 31 of X is clear, or a mask with (at least) the low 32 diff --git a/x25519-tests.in b/x25519-tests.in index b80521d..875b0a3 100644 --- a/x25519-tests.in +++ b/x25519-tests.in @@ -1,51 +1,655 @@ -### Tests for X25519. - -x25519 { - ## These are from Daniel J. Bernstein, `Cryptography in NaCl', 2009-03-10, - ## https://cr.yp.to/highspeed/naclcrypto-20090310.pdf - - ## Make Alice's public key. - 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a - 0900000000000000000000000000000000000000000000000000000000000000 - 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a; - - ## Make Bob's public key. - 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb - 0900000000000000000000000000000000000000000000000000000000000000 - de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f; - - ## Make the shared secret using Alice's private key. - 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a - de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f - 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742; - - ## Make the (same) shared secret using Bob's private key. - 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb - 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a - 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742; - - ## These tests are from RFC7748. I've clamped the public values because - ## RFC7748 wants the top bits ignored. - a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4 - e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c - c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552; - 4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d - e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a413 - 95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957; -} - -x25519-mct { - ## These tests are from RFC7748. - - 0900000000000000000000000000000000000000000000000000000000000000 - 0900000000000000000000000000000000000000000000000000000000000000 - 1 422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079; - 0900000000000000000000000000000000000000000000000000000000000000 - 0900000000000000000000000000000000000000000000000000000000000000 - 1000 684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51; - - ## This one takes aaaaages. - ##0900000000000000000000000000000000000000000000000000000000000000 - ## 0900000000000000000000000000000000000000000000000000000000000000 - ## 1000000 7c3911e0ab2586fd864497297e575e6f3bc601c0883c30df5f4dd2d24f665424; -} +### Test cases for arithmetic mod 2^255 - 19. -*-conf-*- + +###-------------------------------------------------------------------------- +test add + +## Some easy things, mostly to test loading and storing. +x 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +y 0000000000000000000000000000000000000000000000000000000000000000 +z 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 + +x ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f +y 0000000000000000000000000000000000000000000000000000000000000000 +z ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f + +x edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f +y 0000000000000000000000000000000000000000000000000000000000000000 +z 0000000000000000000000000000000000000000000000000000000000000000 + +## Random tests. +x bb8cd45b6185ee8ca34c4d7560425fd5c2fc22871113c6427198e8f9439a8523 +y 98f16cc5e44b7228b7f3b6ed91930d68bba5071157d19259c48034d2817e30d5 +z 667e412146d160b55a400463f2d56c3d7ea22a9868e4589c35191dccc518b678 + +x 8ef938a7b07a668c234c2c5bb65115b8e2e22a3703cda51c70e7a56a075d4f34 +y 1f3cd4bf4f768058c4de1aa5aeb90e227338e308c7a0a199050ca1c38d1e034c +z c0350d6700f1e6e4e72a4700650b24da551b0e40ca6d47b675f3462e957b5200 + +x 8b2c4678fd4f8b7254eea925e4da8d472db7f97d349d1b2134ced884b747ea7d +y 58dca7954f843b7e4dc56b048903e7728df66ef6824f29932b2f568c995ddf2c +z f608ee0d4dd4c6f0a1b3152a6dde74babaad6874b7ec44b45ffd2e1151a5c92a + +x 9cd64f0cf439bccd224f7a789396b9f888998d1ba9759c93a5d6a27f45db0e67 +y 12f724a127052612081e27e3915db9a540de9b64c566edc313914ad94424464e +z c1cd74ad1b3fe2df2a6da15b25f4729ec97729806edc8957b967ed588aff5435 + +x 82e59fa9703b2557303665fe24e3d46259da974d78155f05c6b8891f92fc808d +y 98a073ec62baf1354b681a3c78d62df1698ed5077dbe2bd68ba4a6e0233e3447 +z 2d861396d3f5168d7b9e7f3a9db90254c3686d55f5d38adb515d3000b63ab554 + +x 686ceca221d0f4c6d98287e97c506085064e7b172672b88ee555dd0308bfd309 +y 60adc3675be5e6c2921a74b5b8b24b0a26341a19567dae713a720786bc72df16 +z c819b00a7db5db896c9dfb9e3503ac8f2c8295307cef660020c8e489c431b320 + +x a50a5b82d2451ed9a5844585712202a6dc0e0230501d57b8c00f4bd4771aed9e +y 98d71b8b140aea02ad47d9b19e47d2a03257adc1d5c47611adc667652b78c87c +z 63e2760de74f08dc52cc1e37106ad4460f66aff125e2cdc96dd6b239a392b51b + +x 1637e3eb4c5d173b8cba29bdb13b930f48ae0599e354819f8ae0cf70f0f7b61b +y ffeef1767df70de7a4a75864c03935d7934c6cf5228b9c3000813ed0e55447e2 +z 2826d562ca542522316282217275c8e6dbfa718e06e01dd08a610e41d64cfe7d + +x 9e8bf571c45bc5f37c9126e70498698978903b94d9c6712baef91894ab924fda +y 480f68f8ee644bfb64e3fa514eaf16aea6368da6813802c4c3e6ce8f6540dfa3 +z 0c9b5d6ab3c010efe1742139534780371fc7c83a5bff73ef71e0e72311d32e7e + +x df9bdbd478bd1ec1ff078cdc76f2a5fcdc52f0198ba412e0b5a10e664b175dad +y 080bc47bd2fb2ba3be6a07a02162f76020479f2cc6469c6766df23acf9517896 +z 0da79f504bb94a64be72937c98549d5dfd998f4651ebae471c8132124569d543 + +x b6dd223f5d8a3dc5dd6f7a0679173ff656303017a17f17f4086fd4ecd3a23020 +y 560d827aad23c26fddbfd16c3514a9b518a4586d6e3c5739860743662b14f4b4 +z 1feba4b90aaeff34bb2f4c73ae2be8ab6fd488840fbc6e2d8f761753ffb62455 + +x 1d59691a670c40143ca7f7e693389ab64a911b17a2fe4368fba9097b40864162 +y cb42d3ba12a8b90ef1622ea09241d3157c515043040914356d6d99b95089fa07 +z e89b3cd579b4f9222d0a2687267a6dccc6e26b5aa607589d6817a334910f3c6a + +x 82b48877e9c8c18edb52db3e1417d894e572a8edd84335d93c642158f2a926e0 +y 93c6a39c1ef97f318c3b13bf8e77bea653b2eb130bdf43b00a0e0e40a362e819 +z 287b2c1408c241c0678eeefda28e963b39259401e422798947722f98950c0f7a + +x a6137481c5b9b8bcb3c87f3868c5f812da71aeb21c5ce18a508773120ea4f659 +y 812eacdc5a8eb2e8fde0c23a19c2e33466d754ab3109d28ff48fb41dab8066e2 +z 4d42205e20486ba5b1a942738187dc474049035e4e65b31a45172830b9245d3c + +x 598fb4096a7054e317e66bc9633d56dfcaeabc31a7bbc9da13074b242edeca09 +y 929b1bddd55c99b06b99a3ffbac5adc1d28823cb8354adcfea60b7a87fe32039 +z eb2ad0e63fcded93837f0fc91e0304a19d73e0fc2a1077aafe6702cdadc1eb42 + +x c42183d915267e655409326b1b77a042d8918feefd75dd3d18551f398ef426e7 +y e3729a6110686ffa57d1c69284a60fb36173148a89b1810d04614f03c8f90084 +z cd941d3b268eed5facdaf8fd9f1db0f53905a47887275f4b1cb66e3c56ee276b + +x 67b8b7ea7e7f9f52d686f906589c919b293bff6d3127e7ac581dc1630af7bcc1 +y 99d18d2190ef0da148b843c014fea3efea59f9adbb28fa38407191fcc24e029c +z 268a450c0f6fadf31e3f3dc76c9a358b1495f81bed4fe1e5988e5260cd45bf5d + +x bc3422b79e01234fefd3637a19bfb2dd0a83bf2071b27bf5389918a50e579294 +y b665dffe064aceffaabba94697cf27054d016427ebaf68858c5250cc5c1b770f +z 859a01b6a54bf14e9a8f0dc1b08edae2578423485c62e47ac5eb68716b720924 + +x d419cbfd5514d9cffa1765b9f273fd7492000a3d110586ed0b8137760a2e808e +y bcb52f423917c074464b2078d1c3f883fb793b02411b8b13c08266d17658a499 +z b6cffa3f8f2b994441638531c437f6f88d7a453f52201101cc039e4781862428 + +x 2f7eb8051d16a52b797e2618881bd0857eb205bf97e581e09680f86308f7e082 +y 9ceda63b29c3bfedbb6f3f0be2f3f2bd285bb9d21620c3edde69629b00b1c3cd +z f16b5f4146d9641935ee65236a0fc343a70dbf91ae0545ce75ea5aff08a8a450 + +###-------------------------------------------------------------------------- +test sub + +x dfb53b4ff67c742728c564d50ae20e3e3617804478a95e511d37ff4dcf04fa3f +y 9bc2006bb07dcf7bf0b461e7599e3c3cbfcdf6b6f41fc1db2219767ce9c43bcd +z 1ef33ae445ffa4ab371003eeb043d2017749898d83899d75fa1d89d1e53fbe72 + +x 432ec65076c94af41e054a43f64fe4eecb23f50a303fd38e0172e4e846e67394 +y 3642c84c5f5fcd5a0f3f2e37114beb8e7b614c39d354f1b32fe7e9cc918da5c8 +z faebfd03176a7d990fc61b0ce504f95f50c2a8d15ceae1dad18afa1bb558ce4b + +x 1725a986c03d9d53346ab2064545ba90ab38191e19ded9ecc2f44d422ab04150 +y 11a20caef0239e4ffb5ab2f7d3576633a0d4a08c78a02f35765fafff5398c48b +z f3829cd8cf19ff03390f000f71ed535d0b647891a03daab74c959e42d6177d44 + +x ec5d5cdfc8183f9aa3d47634d16427c3a399e2166bfa4ddfecbc911e5f33ceba +y 649f8e29c483765c4232c369fd0e50a0026eac306eb4bd6924e7b4d7d3f73e26 +z 9bbecdb50495c83d61a2b3cad355d722a12b36e6fc459075c8d5dc468b3b8f14 + +x cc9927c331884612d8fab9a2262ad0db38f55e0cc587e45b972ea8b1f504450d +y 30c5c9f8d5491a350051bbc6bb78e568d98061b43cb1797cd3d7454e8a7aa1bf +z 76d45dca5b3e2cddd7a9fedb6ab1ea725f74fd5788d66adfc35662636b8aa34d + +x 662bc96da214e50f13e07a15b8e0b78f512c744a66975b2170ba28079ca7d03b +y 84b072295dca0abef806ec5c1e594179dc5e9eb172c178af1902a42ea7a3728e +z cf7a5644454ada511ad98eb89987761675cdd598f3d5e27156b884d8f4035e2d + +x ed6f947157492eccc5fb1d0542593d58a47e2d87355dc0378e65376163fcf457 +y cb27e06c5ebf42a61caadd4fb222799772aaef31487bf61ac84c15f58af265d3 +z 0f48b404f989eb25a95140b58f36c4c031d43d55ede1c91cc618226cd8098f04 + +x 33c2fc57d8ffc29e6d670cfc4e25b695320055cf443ade53f49f6c23c452f644 +y 3814860ccbb4391894c107961170d3af1594988a7972b97d0fb2169631b216fa +z d5ad764b0d4b8986d9a504663db5e2e51c6cbc44cbc724d6e4ed558d92a0df4a + +x d0fd0d5e73be5c534aa37645aecc49b202fadb30733f16d0de719a70bec2c751 +y 910c7b4d317397cff70c91e5bf8ec42ba1700b0866adbbfe99b7fbb2c46c7093 +z 2cf19210424bc5835296e55fee3d85866189d0280d925ad144ba9ebdf955573e + +x e0f8130d6b0125e824b254ed57edc59455a8a4704a3f14a4ae8dbf8721595468 +y 4e4f69af6f85742068ad70225e8850c85aef3d3fb3ba3b52c2be979db4eb979d +z 7fa9aa5dfb7bb0c7bc04e4caf96475ccfab866319784d851ecce27ea6c6dbc4a + +x 204d5f69ebab4597d2aa9295ecc2959480a2ab0b225674cc8a147cf7c1e59717 +y 3abdd29c94819ec7507673bd5cc4fb267fcb17c1509abd5e462b46b012f815a8 +z c08f8ccc562aa7cf81341fd88ffe996d01d7934ad1bbb66d44e93547afed816f + +x e2d75c74060aee615b6cfc815c8618f826b07c4987e10f20d27ff74eab3ac7d0 +y 7a06b32d284b5faedb91dac8e94cb7f76c678bad81ed78ac4e75eb9edd8d11e9 +z 55d1a946debe8eb37fda21b972396100ba48f19b05f49673830a0cb0cdacb567 + +x 8d50b0573b0bb945bf128e1a9a37c151e991581673cf6295db5a6223d428ac9d +y 47ca477794fdf378f3486355b5348960ee957470b8c74d62199ac48b4478c4ca +z 338668e0a60dc5cccbc92ac5e40238f1fafbe3a5ba071533c2c09d978fb0e752 + +x b66b49190a99456aaac5c33beaec423a3fa79a84df0f00122aed29151185ceef +y 13c06f7941743bfa261845d99772fd0d5f1a8258aeda53b161505ed8bdca1bc8 +z a3abd99fc8240a7083ad7e62527a452ce08c182c3135ac60c89ccb3c53bab227 + +x 44ac89bb8d4de1a8756b00401236ea4e316a2fe637f6e5f052576da70c29c4ea +y 05dd39ac32768d899b80ed10279aa10d6316d60ab2d061e877dc5f21ce8e1140 +z 52cf4f0f5bd7531fdaea122feb9b4841ce5359db85258408db7a0d863e9ab22a + +x ef0f6c7f56ff22260c66d583f79c7f581181d3a0f3167c93786bb6c89de4372c +y be934afeffaf5e6755a92e6606ffd054627dbe1b18ad6ae543363a01da605512 +z 317c2181564fc4beb6bca61df19dae03af031585db6911ae34357cc7c383e219 + +x 773e0db8f86c5182b5f51d10376f42cde275dac6a646ab1cab065760e045107e +y 3f92ddafdfe67d357b4f9b61807bcb8b0f1f6c2dacba27902f48fc15a31db606 +z 38ac2f081986d34c3aa682aeb6f37641d3566e99fa8b838c7bbe5a4a3d285a77 + +x 34860a848d0afb20e43f4a36b3c8941f5821864216da9cb3ce1a11f056565a3d +y 9dfed86048acd45ec0009c1ba3b20a1ba645ec141070fd8ae41d25e159bbce9f +z 84873123455e26c2233fae1a10168a04b2db992d066a9f28eafceb0efd9a8b1d + +x 854ba91672ae1b8f6c29395dcfa4f3514ed97dc2c9e1e419f926825619fac55b +y 7a700653ad355caf17f89045ecfb3ee821194b54048e55d8eed41fea2b0a22ab +z f8daa2c3c478bfdf5431a817e3a8b4692cc0326ec5538f410a52626cedefa330 + +x 0c66b3d8c3916940b70d381d232ba8aecfe27e3ae63fa6cbb287216708f224f0 +y 477186656245c4083dff93a95c6e5deb707916e52cd74abbd522743c24c53088 +z c5f42c73614ca5377a0ea473c6bc4ac35e696855b9685b10dd64ad2ae42cf467 + +###-------------------------------------------------------------------------- +test condswap + +x 14e55571df646a69a8280bf8dbf8e9afc15bf5558bb8b8236ebcaa19a96053bd +y 8bef5021598a8175565e1f2b522ed1c4306fef4e0e973b50d3a03db1fcf11a43 +m 0xffffffff +xx 8bef5021598a8175565e1f2b522ed1c4306fef4e0e973b50d3a03db1fcf11a43 +yy 27e55571df646a69a8280bf8dbf8e9afc15bf5558bb8b8236ebcaa19a960533d + +x 53d8c54864e18f8fc742b2cb996f1d7595122ca9c90de9f49485cf5a5ef05058 +y 9aa95be655b6704a3dd482e8424f82d17443ae26ab41092fad95df9cac678787 +m 0x00000000 +xx 53d8c54864e18f8fc742b2cb996f1d7595122ca9c90de9f49485cf5a5ef05058 +yy ada95be655b6704a3dd482e8424f82d17443ae26ab41092fad95df9cac678707 + +x 8c7b4ffbf50edf7edcf8d69b67796de38b56a5d4e3a9fb2201354cca0b1b7c57 +y 856e707988c37e59fc6689d024b98bc01b71034484ba194ec7f45106267cb7f6 +m 0xffffffff +xx 986e707988c37e59fc6689d024b98bc01b71034484ba194ec7f45106267cb776 +yy 8c7b4ffbf50edf7edcf8d69b67796de38b56a5d4e3a9fb2201354cca0b1b7c57 + +x c8cb24a636f6d8f2c045c8441b21314884a71d55c73d4ef7ad65620ac0d86616 +y 02b47be53df7c8521d57589256e69b8bbeb1e838d84c090287c04a25d5c08e1a +m 0x00000000 +xx c8cb24a636f6d8f2c045c8441b21314884a71d55c73d4ef7ad65620ac0d86616 +yy 02b47be53df7c8521d57589256e69b8bbeb1e838d84c090287c04a25d5c08e1a + +x 7d96f47612fb7135edfa71dd4526d8b4c944d74ddf004e1653d3af52485168b4 +y a4e83162602d20cf71a279c1071038ecf94f38be11ad1191927b3f480d393e1d +m 0x00000000 +xx 9096f47612fb7135edfa71dd4526d8b4c944d74ddf004e1653d3af5248516834 +yy a4e83162602d20cf71a279c1071038ecf94f38be11ad1191927b3f480d393e1d + +x c3a3d4462091b36bd6fd494e70c3166478be0a65bca7f7361246c52dda402981 +y 62d0ae1abbe5cb909328f59e71330269e4f2b1d3c664e7f1f0780e0a4774c262 +m 0xffffffff +xx 62d0ae1abbe5cb909328f59e71330269e4f2b1d3c664e7f1f0780e0a4774c262 +yy d6a3d4462091b36bd6fd494e70c3166478be0a65bca7f7361246c52dda402901 + +x 38c9b0d92be50270e29cc3181952e745cbf21c8d145ae0c0a6e59f25394ea59c +y caf4896a2d3666200741d817ee1dac661652b9a1741ea966d5ed7cbc4c76217a +m 0x00000000 +xx 4bc9b0d92be50270e29cc3181952e745cbf21c8d145ae0c0a6e59f25394ea51c +yy caf4896a2d3666200741d817ee1dac661652b9a1741ea966d5ed7cbc4c76217a + +x d637a72affa4112bbccd2878208ce34fae442e97175e1b39f43c00b14d312a2b +y 76209f8b1f152ba7e1e6294f707831021eb2ac03872ed3774ab8fc5e6a0e864f +m 0x00000000 +xx d637a72affa4112bbccd2878208ce34fae442e97175e1b39f43c00b14d312a2b +yy 76209f8b1f152ba7e1e6294f707831021eb2ac03872ed3774ab8fc5e6a0e864f + +x 12f3bd417fb3860b2a4fd04eb1c51c558a4c5a3dcc1ac457654a45a3cd45b0d4 +y 46f802836c7bde099775f3fb4f5f6345364a7e158bae9e16c4c99aee0cfa5e42 +m 0xffffffff +xx 46f802836c7bde099775f3fb4f5f6345364a7e158bae9e16c4c99aee0cfa5e42 +yy 25f3bd417fb3860b2a4fd04eb1c51c558a4c5a3dcc1ac457654a45a3cd45b054 + +x bf1809201f83a34cb07aa2e2372516631ba0513e600956e6702903e9084770c4 +y 414bbc77d13d7b4e706acc07406e8d624f2485463f9948d81b72268c1e086a14 +m 0xffffffff +xx 414bbc77d13d7b4e706acc07406e8d624f2485463f9948d81b72268c1e086a14 +yy d21809201f83a34cb07aa2e2372516631ba0513e600956e6702903e908477044 + +x bb8703f2ddaaaaa6ad19219684b1bde576b38bbe9065178b24c1bc55563fe525 +y 1cb3ca7846a3c584b1bc05b25ee91d4779ab9ac64ecef0fcbaea8d311b55d618 +m 0xffffffff +xx 1cb3ca7846a3c584b1bc05b25ee91d4779ab9ac64ecef0fcbaea8d311b55d618 +yy bb8703f2ddaaaaa6ad19219684b1bde576b38bbe9065178b24c1bc55563fe525 + +x a07c7110c32e362864a42cd2f371ff420bfd442d291cc15ec079d642b5c85bdf +y 497fa7867fcd0617c4cd765aa6f46b89390744b5b57d11ab732153e075fcb607 +m 0xffffffff +xx 497fa7867fcd0617c4cd765aa6f46b89390744b5b57d11ab732153e075fcb607 +yy b37c7110c32e362864a42cd2f371ff420bfd442d291cc15ec079d642b5c85b5f + +x 10fddb7f48015b394512257da026938b67f65dd0a84dace51417d68da003a913 +y ebd6706b7cd2ee2d97848ee1adaa990d8ddbfad48e43f51d7ef843fa7597410c +m 0xffffffff +xx ebd6706b7cd2ee2d97848ee1adaa990d8ddbfad48e43f51d7ef843fa7597410c +yy 10fddb7f48015b394512257da026938b67f65dd0a84dace51417d68da003a913 + +x 1dd835e2173b936a91da37b3aa11e848e4497964a9a78ea929a19105eb981a24 +y 3e6f1ab7d5c460dfb7ad1926c60b64a8dd48ed0115b0655a6d8619666b8c8dde +m 0xffffffff +xx 516f1ab7d5c460dfb7ad1926c60b64a8dd48ed0115b0655a6d8619666b8c8d5e +yy 1dd835e2173b936a91da37b3aa11e848e4497964a9a78ea929a19105eb981a24 + +x c4541b1380e796a333d88affdccb4d2bc68bc5a1b3890ef2fc1a2c38dbcac725 +y 6f6338ad8dc0562bc02e307743b81013ffff6c135fdf8603f9956b7f94eb55fa +m 0xffffffff +xx 826338ad8dc0562bc02e307743b81013ffff6c135fdf8603f9956b7f94eb557a +yy c4541b1380e796a333d88affdccb4d2bc68bc5a1b3890ef2fc1a2c38dbcac725 + +x d71f16494f041d1547e5dd9ed539e6b9c1506cebb66f6424e6c7aaf6d0ace080 +y 78c1e6cc0b6f64e161def3b2ede7465f21f6afe61299e9a3c52b1a7a080b9b26 +m 0x00000000 +xx ea1f16494f041d1547e5dd9ed539e6b9c1506cebb66f6424e6c7aaf6d0ace000 +yy 78c1e6cc0b6f64e161def3b2ede7465f21f6afe61299e9a3c52b1a7a080b9b26 + +x 4d90838ab9cc0a79f4e2aa6a860bf8cfbce5f834aab428d4a06f8ef4a2da582a +y 53124b302e7675ea5784e2e7d9fdecb38d9c8be158312dd81c51757bafb79b42 +m 0x00000000 +xx 4d90838ab9cc0a79f4e2aa6a860bf8cfbce5f834aab428d4a06f8ef4a2da582a +yy 53124b302e7675ea5784e2e7d9fdecb38d9c8be158312dd81c51757bafb79b42 + +x c8e764092ea695b0dd8f0ecbca5a4e02096c821b0f5cd57de8e3e50d8b2a40db +y db7fb38dfede5259a584dbcc697f259ce380110636e301acb308bf687449110e +m 0x00000000 +xx dbe764092ea695b0dd8f0ecbca5a4e02096c821b0f5cd57de8e3e50d8b2a405b +yy db7fb38dfede5259a584dbcc697f259ce380110636e301acb308bf687449110e + +x 34cf8e55b3d2494362a87a24907fbdab61cb4f452ef5a889a1aa40a22be6d976 +y 679c6d6f6dca1b71bb098e3854c63ffb8ddb76f1a1cb246ce956fd71d6477c20 +m 0x00000000 +xx 34cf8e55b3d2494362a87a24907fbdab61cb4f452ef5a889a1aa40a22be6d976 +yy 679c6d6f6dca1b71bb098e3854c63ffb8ddb76f1a1cb246ce956fd71d6477c20 + +x 9638ab322ced065068f98597cc61fc2bd846b5849dc39a881209b8efcbc95eec +y 32922ff2b62e968417225b765f2787387c8a42fcab1dbec3815298f53813a8cd +m 0xffffffff +xx 45922ff2b62e968417225b765f2787387c8a42fcab1dbec3815298f53813a84d +yy a938ab322ced065068f98597cc61fc2bd846b5849dc39a881209b8efcbc95e6c + +###-------------------------------------------------------------------------- +test mulconst + +x 8d517a8804d934ae93388e1d59748c3c22866d7be6cec58a357ec43f6dd029db +a -319312 +z 3f2fea85c9195f2246f4f6fd2e8d5de95c5065edbea45a174bc0d1ef3db4aa54 + +x 1b5d6a6c9cdd0dabd126e5f5ee2513f3d27c56dd3aad89c882fe9fd2d38a93b9 +a 499342 +z dd310555966ebe7f409dcce2933f91af8e14c8909f78e4f113606789dd7f504b + +x 9e03b44e93743e0cf5768f65bd3c0f255e001de330d5e1a863d6e4dbb11748a9 +a -284189 +z 6e8c7f8d0f1476cf2603f5702fe8e8bba5c01e86b6e008ac72987fdd6721183c + +x 9cc65e302736aab9bf02dd451c216ac3dd2066af299d7f6bb361eb3b36777f74 +a -15738 +z 8c067e5dccdafaf56301050be17b8895c07e7f13572bbc5ce1af8b5be043d91b + +x 7f36ff91ed165c6ee44aca261dc09e3e124c2ed8167064c20d9b84fa226e2555 +a 423857 +z dc7415db1ab5e5a5658d089ced49bf97718bccc55e2f15b83a28157cbe47e559 + +x e8852c80db69c7e55d476ed00ca7c0735052f7f72f81198a57236feb89a5903c +a -140934 +z 4923ee40bb01314c2fe9f2f87d0743823311b2d9265219eb7a6de5fdfd09a308 + +x 505ef65d294b77e260757bc867199c4b0922b5022dfd6a1fe7478ea27ec102c5 +a -307893 +z b14d72c991a0bfc22b1b95934bbe589b6a4a1f9c76a89d7012f8cb03379a8844 + +x e410c260dc8c1838f3e9658ae586425039b373ee2ab88c750a51853b012af0af +a 471420 +z 42ae337a920ee1b83768cbf0750f524cf1f9e98b99f195e869785f90a2356756 + +x e2d181914b54175190462d11402717f42efa37967b2fe0bc4433fd4c862fd646 +a 492178 +z 4c6e1ba6896d2d661fbf99b77f63e3095d3341f04bf258dc3e4f51e39c68f576 + +x 9cdda0d7da106ef5cfb34774f48308b64953e92869dab0ba804927080509d8a2 +a -312149 +z 4e75e56793563268480efaf6232ad702bc5aef6246bd44e3499ff437810b523b + +x 9dac4442858b8dcc324464911e6f23ed046e42612e8105dc3aa2b9eccea15dc8 +a -88818 +z ce52a0897600a05383df0a0b99a451f0d5568146b4323392fc164153715ecb0a + +x c9f92ceffa7027ffa71e64b714c36b28a6a18c3608f8170d11d51acbee3c62ba +a -259755 +z 89582517069925572219b2eec2a25029e8e1c78772ca8c50bf23220d02740763 + +x 8f8bcf28f4920465680c8e15befba4ebd23c1e27b71c224c98461f69caf76eb1 +a -430350 +z e96b93f0aab6ca70f7d2c1121110efc320aff34e1ec693d7bf17bce1a756d622 + +x 6f4d413a27388fe84a2585e809927bd470ba1b0dc749ae6e2dfa100617a5a7db +a 11486 +z 1cf1f5bd0770d949ee36df858e5842805d121722de30d2ef6bc2b82d021fc14b + +x e1d05a072d1ab70d895969271f44b7c9d1654171836cf234724d2f90434c04e6 +a 8057 +z e32b3c792cd3b6a770eaa2627ff8de8895873d73d734b961646fbce0643a443d + +x d8564ee3ff02c80f0bf3e9cdfce42cd8ac1012ad8ea74f8c0f5754b5775a8de5 +a -304373 +z 884266ea43a6a9b72d113b437dae63c664ef53884c893212fd864412f4e5e457 + +x bf66769ee0cf873764524e760ee654e8d5090aa774f2e96144d945f8da37af19 +a -159091 +z d7438999b3bdb99a46e2f3dc8492cbaf52b0a19c651cc382c384940861bccb6b + +x 72b7d02b1fe23adea87696864c0a9f0466db85e39db397f0eb428a50e277aa2a +a -521654 +z a611bd153336e178a7f3d912adc2fb39b342132458faeedbdb0a35973efae23e + +x ff5c39d4b7fff86810a7a3b14a58bc01e6ecf062116adaa78dac0d1bd3f6039b +a -140759 +z eb9e32bf7d027cda198048da50aa79a11bc99f3b37a219a2104c78f4affb584f + +x a6f1f7f30e3f9e5467f180f92d2c94165fd9427d0c7d383b9077ca9a7e50dac5 +a -317637 +z 56a32847c50bc9609db9796e1650fbe97524aacea746d3cf285f0f2fced01a49 + +###-------------------------------------------------------------------------- +test mul + +## Easy multiplication. +x 0500000c00003800006000004000000009000006000048000090000040000000 +y 070000180000200000e00000800200000400000c000030000090000080020000 +z de200094610090df0020fe0180270700650d00dc2a00f84100e0340040570000 + +## Random tests. +x adcc6f10734dae2273304a6aa493ee8f96e05f2402341c0d997dce58ea57ff6f +y df3c8d5bb6380fa278d4ff2994c7865bcc146596d3c3126242f0dc3509b57449 +z 5ee2615b75a40367ced4ed4bf1578d13e7afa4d415f38f802b7e7b374365b627 + +x 054bc4d5e9b78b068fd20645eeb1f03aef2e89a1f56cb50e5f1170a86529526a +y f976ffa1d1b4a33d0fd866528897cea3eaffdc75e31aa65450a62ff765fe7985 +z 0210280745f6c29a04433f07f880bfd2eddd758d82996e79c65de817c30e7309 + +x e361c6fedbbe081b7cd683d23a2bf0ac889806be7230b56d9398959713a300ec +y c8121e53d78c2e9ba2ba7f51b7cb15cec970a63b4a642ac470aa1f2145f07bd0 +z b48bb1c7ddd26cd9e5a2cb73bb3885dbe4a47e03886d4dfd59e5729d544d566a + +x 463158a2077f931567d45e19deb4454a2ae77045db70a2c078e160ebdb74fd94 +y 3f311e3f8d225016448fbce3fbfbe84002736e3b0d5a90f57d705ede8706008f +z 44cd97e25c20ae2fe2ef4f2630981a1fe54c79ebd904bc40e39d9fa615ffa76c + +x 1c73fca52556e01204d4b957a01d1049f2247c8666d90c1d3703cff16a38c8bf +y e9afa0cc85577ec7eb1ac66d87260d5f3659936ff88cde8bd1c3fa1d499e8bcb +z 0979a8baf734c86a4f57ae400b7790c4985fba3088cb1b265dfc7a66c794121b + +x 6e2bab74e427b1a44f0cb181f9dedd6fed43cfd395d3708c4ae8fd2137215eb6 +y ef400834f2dad8763a1a5a58a37d1b36a78873860e4dac808d3166f13724942c +z 0d481adbce7bd82ebc5a3e5ed7a492e78a032ebf211a5bd2371c528c77954936 + +x cb3575b41d9521da5c85c6438af14903a8d6d9c3857aa8e101e5295fb277de7b +y 9f76715d2ae3c8ca182406553d3481fc36d67727ca2d51f5db37940aa3208d8d +z 0b2fa619265bd424b9e20d38bf4552ad63de8ab552166080d099edea5fbadf7f + +x abd66cf3b20dc4c5a866f1a3b965f794a726f96dd00f576d16ead66eea3a1177 +y 97f70fc92e0cda0e010f2a9d7608c33db954af18bc18ad55bf66e7d91ae31abd +z dcbb2cf34274971ef030827865b093a00761de3da90e46f00e18d0fd934a2b7f + +x 3b3c96ff9be8e17e0a0d3979ea5e5623fff5fa18914151abf79fe66639beef06 +y 1d29c361677805f1dd2b839e025e56208a10c0b8d9f2a8c490b0a892c0e27080 +z 0050873016bc67023d0c479fffa56a5a70512f9864d00b0a3e951f1e85c8b412 + +x b263d4a71b6d963e0a972819e5e5805b9522f142d3c0ff2738c51cce31e9f0d5 +y 64f3fbcff2195c297292df3e1cf900aae457e09864c5a6248ea21ef8efd557d9 +z 7e6f6f511cbf2743c0fc1c6431243908606cb257d20f8a8a0885e6ecd000e811 + +x 0df0497e1e01dbcc4a48d4865127d9cc31a9a0a56e90cc31619e65c1521b2369 +y 9277f0c6a5bcd7c7ed8dcf7182795f67a12e856b126d09966689834c43aada47 +z 798d270ae34aa2452694b4ff74049a6a5169d71c85bd1a9ac59625e9298cdf1b + +x 1dc64bef2189eb5349f5a8983c1854a40141a5390ea4bf8535a15aa71d0289b7 +y fb59dc9b08f9163881b10020ce040da296ed8c1a9a935c27ca0047a4d7f6342b +z 9fc23104cefd3014a469e6d3a0631338eaf91e24994ecd50bfc0b4547317317e + +x 975b108909e87803af98af9425d2a982865b6cc9c144985b32fe5bb842702e24 +y a69e9130dc40be50e827dc50dac05bf900946cf67ec35f1bb1705001314e4fcb +z 12d042e50d0cff7b43a5ede61ce827a99619bf84995d488fe9eb56a8de769164 + +x 39c0db5a4b161c368b0f71c7e8ef97dddc444e4a33181e0743519f2a879ae04f +y d3cc45ff509ed45998bd5f218408ad51f7457b35e8ad69d5431f174047d7c6e5 +z 96b877604f52782ff2a5b1a12d7db642371ca993b648c4971cbf593213503219 + +x f8c6715e4a327cbbdbb08d74121619abc73dc421d7267029e39b50c1510d2045 +y 63870a83cad4c1c64195ae7b92f3b19c830f35f1a3186815565d846c787c7ffc +z 286a0b8c6681a7b79a5f85426fb60819b7bd349e93c1e11943c41c8dfd57d00f + +x 49c9bcaf5434b8205a348df290a96da27df084f34047efbf91cf544057a50bde +y 54269f8b23c05b94c9c1cd74eae88d9227af12a6fb337548eb93c2a88a75a8a5 +z 1e3dcab5d7361f00e70198b52e8fb6d1fba74abd79d99480527f6711b21b833b + +x c7212b43ff0d10fc52d3a2a7e15bb9cf53856f7ce33b79df89e1d13f95a94511 +y 5213ec20bd054491a5485f665075835da609ad4f3dc005744f061480862ee602 +z e136339fa01067c6c0823a7ebe2f84d917600e244a9883191900bb95a3b59764 + +x a15d62c6308448f1f70602f43be1825696d228eb170bed55322a21d2b1afa915 +y 58afe65bc8adbe22807026aa1b0d68af330bca268fdc054406aa41c820960e71 +z 996c597e0a024c2ff0ffe289d8c7270e4ea1d38e294d7210eddeb2c0725a1305 + +x ea233ae033ca93034bc8fd8ea3c0625bbb15b00265264fdd61f62cc808b505fe +y 09e12ef9b3426991f7119c2e8349278342ed0072317c4ec7ab24561b61396b39 +z 1fd72191fe9f00b0cca6a635d14904bd0c1e0ccd1275e84ad0b7bde134866e2a + +x fe1fd3da05524af4ccd538f1d2ede09582101fc2a47c2e63758a546bed6cc5ec +y 523346406ef3df6ac9a455d0d2e7f732ad01c88245b07a888cc21c40fce11a76 +z de6cac8fdc878d9c4eda6b78f8b629ecf776980e49fed56bab936fc03924f44e + +###-------------------------------------------------------------------------- +test sqr + +x 4dc87ad85abe8938634492ce2ea10bf48dc4aa2fa37a6a0fde3e5a01e90dde2b +z 346297c756d77b8ea312ddc455223f4577aea2a2e8d944cb24adb487de143b46 + +x a33aed91165d7fd13a543760d3915c1b5d411a21895cde81b2f3640b87550cc9 +z f923e49da9d5f45e23a782f911fac1a6c2e67cbbc7b03ee4675a0c5fbec03641 + +x a1406e453db6c92ef808295d1919c5bb2491c0ce6d5326d276c57e57943e0acc +z 18425bbd92149991c4545e65495af0e6372289e9a32649c127122243204bdd73 + +x 70a56b8484234ed002a68c8d535a4e527a61c360f7d4ee5b4970c8ace1e12de0 +z bed1c435139f151d0650577e03c32428f63cdb7bc1920110b5fdbb27f08cb200 + +x 86c3236a6194f1585b4dbeb09d0247fb7d3ae08063ccf9fc4fde70fc23735710 +z 9b6509acadd5d31c4c843e91cec78be00aec4fdf7d86132965bd6f62f078f711 + +x 0e5e83c51a8c091673425c38785e0aa1d74c7261a035a891bf734cca8c8a3db3 +z 4efe5029e99438835a8a45d0180b8de357eac82ba9dd8e127baac0d758dfca1d + +x 31c39a5afc33f8a8d3c570b9dc5389bea6fdaaeeb44cd7524f6c445b9583a34c +z 359b7c8791cc87aa8b3c799c9d4d7e1f4062a4f64436d8c01071597e8c262127 + +x 5a06203c15d6c1db6ea0fcf468a1e3f09d68c4a0f64c3d7e30e70290545e708e +z 07f8b435ea322bedf613458b1eb420f1d6bc96741d69695899bd40f7eca6f72a + +x b1973433646474167b791b326827641260fb33d6a2c96d4e963a6b091f824505 +z 52a62396dbbceead62912f8adfed2707fc25edb51aac19b2a274c246f1209f26 + +x 96b157d71e107168fac206dd63007f10f4ae1225b0761c470ee18ecdb4fff20b +z 84ba2a84b156437cdcc39ecc8b1ad01bba934d8dfb7d504b9f2442db0ad01167 + +x 6167d77675e19785960c28df551b458e41dfd0dfe5e56e785b7367997d5eb0a6 +z 79a558436af4310d3eaee93f9a7cab72bd817fdf59d267e2c530ba8d667a005c + +x fb4b2ab08db932ce10dd62639aabbb266f9ce775fb5a5e0875864f18a3ee506c +z a6013661f2f0ab875739836039bff6bff4c993aefdda43dccecf4c404b9a612a + +x ea26bcf0bfc3e15d4df7ddbcac8b5b9e9a7215d74196d77c9e0524e861c6aeb4 +z 113e06861e3d338618695f4713464cea536c8019da77ff0dd9946f3b860df062 + +x b67b1ffffec757ef147e86cf60898c5dac515f080f43f4e120017caab4eee5ee +z 7d9748a1ff6ca9cdebeb3dd6668522767afb9ebf1c680fe7fb3f5848f7222036 + +x c122016f17f12e53f9ac031719fe428c826217b2b757ae44f2f33d1b8b1bb553 +z dc068d032b97c98eea6dd6c8bc42e9a0a6250c81a36a8f64615489e191287c72 + +x 1266ff0654c08e6183cd6c3cc760cc5c88d1f49b918f2f8f587b3edd4adea513 +z f07f17fadb2e2dbd282d296fe5a15cc5c2baf6b45f5fd5dc4692f252039bc862 + +x 4c4dd9c6e46fb2c096388583f2a0c969245452b23f16ea43e15064c45357ccef +z 5127fd4415a84115997b8b3ebe88a590efde9f8b53a43e86b1a4d60782c91025 + +x 095d149c2616212e5f770f133e719d285a8bc888414271296684e732feb5473f +z d8038bee551cac14d1c610bbc0960d943b01526072c589bc913ab51fd47bc848 + +x ad55f9f916d62bb13ceb1461b99e82d76b860c084ca408dd4a18f154b907754a +z e5c86ee6350c9ab736229f3f53e2ab852641bb8a62fdda609444df377e9ca04a + +x 2e4976f45acc671e38add93aa6a89669cdc9874975879b3134dd37c633c9eb14 +z c6513f1a11346d33b05ad65eca13f11125cf70bdcdd6e666a8a7b9c5b6098429 + +###-------------------------------------------------------------------------- +test inv + +x 344ff33a2bc801f861bd13575797da35352c8164808d27f51ea7ca46931b2b1f +z 07f678dfeef071b038d692bf825cb4e75bc1934bd3a6e3dfea99e78bdaeecf3a + +x 670097e2fbbecf6516e949d98f6d722d3f732c33bfb4e62512f9d28d94546b64 +z b2f5cbcd7d8c996ed33a813b1aa39c36f5826b436867bd89b4ce43a156c1e96b + +x 234f3bd8760cdc8ae7fac9457da418cd082e42906ffe59a13e52185a7845e61c +z 7488ff9231e4819684148e16ebc25440732ffe7d211eb3d3263db1af9f1d0513 + +x 22a39a35b1cabc6dfecd1b898593070f0c81bbd04b4b20f43a9c7c14b5dfe967 +z 892024fdbc8937b9b3aef794f57b8ed8517510b6de3f6088987b1310c1dc7932 + +x d850c118c69198268826d05650958c6bed55b181090cf1c96493ecc4635a913f +z 7aeae1b0dc5211f374872e78da8f225325f3f33f9c42bfdeff25d425dff7710f + +x 33ccdc0e39f7cd0a61782c87ac089eb7bbcabce4dd222f05088d3d6332efe959 +z 668f87e23239e965c80740d4daa9c913609388f291c11f950684f45e689a061d + +x 7c06f93b2f66001c74073b8ba7536049738e89b0a0d859a8a73710de3fadcf79 +z 52df0aa24bb4a7474e6ed9852ba542c1f4c5219372a7b5d60988890e2955491e + +x 9a0ce9ff4026bd58abcf8a128dbc55a19c446005834a143634452821d5f9f0ee +z 79eaa93b6287705c0ba564c31bab1854c7f4354845be065c4bf94d38a7a8b421 + +x a13a127490bd3443fdba99baf61d113f3aadd6966c9732cd16348f9fbed32e0e +z 67290b25e6bd7328dd804309a6203c02a75657f593c7e66e48c9192524e5b87b + +x 35f7ac3eaa36c4ed338388fe7eda61cf237eff6ddc0847cb0c95255bbaef8ddc +z 4950601d2cfe75eb9c4524e2f40f404fe82d0014c916dc43d9416cd2e274992d + +x 8a058593035986da3a19e63dacaf40fb3db4cf382205fc4e4802e0ff0c61c8d6 +z 6a23b743dc2fa4a4132780cf6edfed4c219760f3b31343b08710ea18d2c0fc43 + +x a10d03234e700ec92270b6105fdb787d8edd3f960fdd78ea2e169f49dc708d45 +z 101dad1720604d0b093831baaa97fd0701ce773b9c1be1db0403533ad4376c0a + +x 52d3b9e030a5ed574f7f9489c47e73f78ef88a39b570045f9ef73c9a3e65f425 +z 83da3e088dbc9a3cbe06496c5a52edc8d7abcbb8a0f839361762137b119d961a + +x 9928b5f14ec80a036479d7b08c128e601db880daebef36adde6fbd1f50f82629 +z 8dcaa9a2439b77cbe44928ac2877e09755c505f58df4d0ffb9b23fc256b12779 + +x 5a956523956f8ace6166ea6cb3c7421f8d1142d26084a81d615f00d578e03448 +z 658a3ee24ec5b5f1d2d12614e535247c9f2f259131b00f654e09b4517c63ea09 + +x 157492cd38a07802351ca0d1a5615d5c5f254692acce930fb6be351e9a52f088 +z 32fec1eab85ddf8d27a437876e7f5a07f012b02e7971869811c3c31230204164 + +x 2d07c109c332847567621ef4338e149b99c5bc3bf6e50943695da7fed5d8141e +z a81472d28a8235bff43ad5cc012d52e95ece3dbc5ba2962dc54cf9e7f81bee04 + +x 7e172f6c03415e83d4671e0191151d49e5257651ba73848254e68fad0a095c50 +z 1a8efdc57ae9d39ffa64afbc5d2dc1f25a29d365ac3dee0d8529977c14aa4415 + +x 1934546e37b0bac80319fa7f2f86c18e83de8da830b9d0b5019c26768974eda4 +z ffe55479771f20518d8fc6491055368b5dcce9b4e193d19897f1e116b9cdf946 + +x 90324ccfe0e34e9b08db1862be3bc17798a8581ee097be76545e3bf9d586a2e6 +z 0f5ccf4920d617c9b4f7fe6e2c9e95e89b5516555d5e3f5f9900485451d7425f + +###-------------------------------------------------------------------------- +test xdh + +## These are from Daniel J. Bernstein, `Cryptography in NaCl', 2009-03-10, +## https://cr.yp.to/highspeed/naclcrypto-20090310.pdf + +k 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a +X 0900000000000000000000000000000000000000000000000000000000000000 +Z 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a + +k 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb +X 0900000000000000000000000000000000000000000000000000000000000000 +Z de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f + +k 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a +X de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f +Z 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 + +k 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb +X 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a +Z 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 + +## These tests are from RFC7748. + +k a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4 +X e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c +Z c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552 + +k 4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d +X e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493 +Z 95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957 + +###-------------------------------------------------------------------------- +test xdh-mct + +## These tests are from RFC7748. + +k 0900000000000000000000000000000000000000000000000000000000000000 +X 0900000000000000000000000000000000000000000000000000000000000000 +n 1 +Z 422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079 + +k 0900000000000000000000000000000000000000000000000000000000000000 +X 0900000000000000000000000000000000000000000000000000000000000000 +n 1000 +Z 684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51 + +## This one takes aaaaages. +##k 0900000000000000000000000000000000000000000000000000000000000000 +##X 0900000000000000000000000000000000000000000000000000000000000000 +##n 1000000 +##Z 7c3911e0ab2586fd864497297e575e6f3bc601c0883c30df5f4dd2d24f665424 diff --git a/x25519.c b/x25519.c index 8e9649e..19f3518 100644 --- a/x25519.c +++ b/x25519.c @@ -1,3 +1,43 @@ +/* + * x25519.c: Bernstein's X25519 key-exchange function + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Remove the test rig code: a replacement is in a separate source file. + * + * * Ignore the top bit of the input public key: in Secnet, conformance + * with RFC7748 is more valuable than flexibility. + * + * * Strip out the key-management definitions. + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * The X25519 key-agreement algorithm @@ -27,7 +67,7 @@ /*----- Header files ------------------------------------------------------*/ -#include +#include "fake-mLib-bits.h" #include "montladder.h" #include "f25519.h" @@ -39,24 +79,6 @@ const octet x25519_base[32] = { 9, 0, /* ... */ }; #define A0 121665 -/*----- Key fetching ------------------------------------------------------*/ - -const key_fetchdef x25519_pubfetch[] = { - { "pub", offsetof(x25519_pub, pub), KENC_BINARY, 0 }, - { 0, 0, 0, 0 } -}; - -static const key_fetchdef priv[] = { - { "priv", offsetof(x25519_priv, priv), KENC_BINARY, 0 }, - { 0, 0, 0, 0 } -}; - -const key_fetchdef x25519_privfetch[] = { - { "pub", offsetof(x25519_priv, pub), KENC_BINARY, 0 }, - { "private", 0, KENC_STRUCT, priv }, - { 0, 0, 0, 0 } -}; - /*----- Main code ---------------------------------------------------------*/ /* --- @x25519@ --- * @@ -84,6 +106,7 @@ void x25519(octet zz[X25519_OUTSZ], const octet qx[X25519_PUBSZ]) { uint32 kw[8]; + uint8_t b[X25519_PUBSZ]; f25519 x1; /* Load and clamp the key. The low bits are cleared to kill the small @@ -96,8 +119,11 @@ void x25519(octet zz[X25519_OUTSZ], kw[6] = LOAD32_L(k + 24); kw[7] = LOAD32_L(k + 28); kw[0] &= 0xfffffff8; kw[7] = (kw[7]&0x3fffffff) | 0x40000000; + /* Copy the input point and clamp the top bit. */ + memcpy(b, qx, sizeof(b)); b[31] &= 0x7f; + f25519_load(&x1, b); + /* And run the ladder. */ - f25519_load(&x1, qx); #define MULA0(z, x) do { f25519_mulconst((z), (x), A0); } while (0) MONT_LADDER(f25519, MULA0, kw, 8, 32, &x1, &x1); #undef MULA0 diff --git a/x25519.h b/x25519.h index 56008df..b7b03e6 100644 --- a/x25519.h +++ b/x25519.h @@ -1,3 +1,38 @@ +/* + * x25519.h: Bernstein's X25519 key-exchange function + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Strip out the key-management definitions. + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * The X25519 key-agreement algorithm @@ -45,11 +80,7 @@ /*----- Header files ------------------------------------------------------*/ -#include - -#ifndef CATACOMB_KEY_H -# include "key.h" -#endif +#include "fake-mLib-bits.h" /*----- Important constants -----------------------------------------------*/ @@ -59,15 +90,6 @@ extern const octet x25519_base[32]; -/*----- Key fetching ------------------------------------------------------*/ - -typedef struct x25519_priv { key_bin priv, pub; } x25519_priv; -typedef struct x25519_pub { key_bin pub; } x25519_pub; - -extern const key_fetchdef x25519_pubfetch[], x25519_privfetch[]; -#define X25519_PUBFETCHSZ 3 -#define X25519_PRIVFETCHSZ 6 - /*----- Functions provided ------------------------------------------------*/ /* --- @x25519@ --- * diff --git a/x448-tests.in b/x448-tests.in index 0320af3..753ac8d 100644 --- a/x448-tests.in +++ b/x448-tests.in @@ -1,41 +1,669 @@ -### Tests for X448. - -x448 { - ## These are taken from RFC7748. - - 3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3 - 06fce640fa3487bfda5f6cf2d5263f8aad88334cbd07437f020f08f9814dc031ddbdc38c19c6da2583fa5429db94ada18aa7a7fb4ef8a086 - ce3e4ff95a60dc6697da1db1d85e6afbdf79b50a2412d7546d5f239fe14fbaadeb445fc66a01b0779d98223961111e21766282f73dd96b6f; - 203d494428b8399352665ddca42f9de8fef600908e0d461cb021f8c538345dd77c3e4806e25f46d3315c44e0a5b4371282dd2c8d5be3095f - 0fbcc2f993cd56d3305b0b7d9e55d4c1a8fb5dbb52f8e9a1e9b6201b165d015894e56c4d3570bee52fe205e28a78b91cdfbde71ce8d157db - 884a02576239ff7a2f2f63b2db6a9ff37047ac13568e1e30fe63c4a7ad1b3ee3a5700df34321d62077e63633c575c1c954514e99da7c179d; - - 9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b - 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0; - 1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d - 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609; - 9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b - 3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609 - 07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d; - 1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d - 9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0 - 07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d; -} - -x448-mct { - ## These are taken from RFC7748. - - 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 1 3f482c8a9f19b01e6c46ee9711d9dc14fd4bf67af30765c2ae2b846a4d23a8cd0db897086239492caf350b51f833868b9bc2b3bca9cf4113; - 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 1000 aa3b4749d55b9daf1e5b00288826c467274ce3ebbdd5c17b975e09d4af6c67cf10d087202db88286e2b79fceea3ec353ef54faa26e219f38; - - ## This one takes aaaaages. - 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 1000000 077f453681caca3693198420bbe515cae0002472519b3e67661a7e89cab94695c8f4bcd66e61b9b9c946da8d524de3d69bd9d9d66b997e37; -} +### Test cases for arithmetic mod 2^448 - 2^224 - 1. -*-conf-*- + +###-------------------------------------------------------------------------- +test add + +## Some easy ones. +x ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff +y 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +z ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff + +x fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff +y 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +z fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff + +x fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff +y 0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +z 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +## Random tests. +x 6b3944398448a0a5f6c4e1be9abfcbb082b8f68f1c831d51ef2244f6e1a4c4baaf0ada769c1261b8e14b4856de381d69961078ea1949d39c +y 62e933c5f93e57e042d66b89d3c72ee85441b1207732d888b3d6bc35f3bcef91a6f4564cb085fd3239191c2fe427dcdb0e81164d30ca8145 +z cd2278fe7d87f785399b4d486e87fa98d7f9a7b093b5f5d9a2f9002cd561b44c56ff30c34c985eeb1a656485c260f944a5918e374a1355e2 + +x 34938a406030a285024e9ff0a45987b53accc9d5d59828de8b8e07ba693b64d1dd2c7a190e708253a9ae57572e44fa458c8f8ac87cd96037 +y 9d05863131328886c7203fe70924761e56244d40a04d4b5592f1c6a457b9d94fe950fb8a865f9091ba9223479f3e46680fb78ccddc776bf2 +z d298107291622a0cca6eded7ae7dfdd390f0161676e673331e80ce5ec2f43d21c77d75a494cf12e563417b9ecd8240ae9b4617965951cc29 + +x 4e9cb6823482233daf59662d00212f2afe42183f8ce949b2e0ca5473e32ab647fe9bc1c472b2288715c0d5b118043fbc9aec782654363cdd +y 6c62329ec8eb576b6866cb6af702b891dd2cd72d21c354ada34221141381acca066fb46a8fbce28df44f0ac8062e38847067b8639be867f8 +z bbfee820fd6d7ba817c03198f723e7bbdb6fef6cadac9e5f840d7687f7ab6212050b762f026f0b150a10e0791f3277400b54318aef1ea4d5 + +x b46d33f24a69c2288bed34eb054d1fcd6244606cffca7d53ff4e68f113174655a9a72898ad2699fe49d069a0a84e077bf48205008dee04aa +y 9abc68911a75a6a376837cc6fc0e18c63cfb81747a59ba1314412f032f8b2a2fc5dde29176d141e71dbc11aeb2ecb9a336c8467882a175ea +z 4f2a9c8365de68cc0171b1b1025c37939f3fe2e079243867139097f443a270846e850b2a24f8dae5678c7b4e5b3bc11e2b4b4c780f907a94 + +x 1195eae69f2bad43b7b8330395e41c811bae2f753f0a6727b9decd2e553dce743dbb568b45140c3a464c8646db12b3af18df328a95640706 +y 8fc020ba693b4014fbf4e9c64223a8c3234e1361b8e2a745e3897f582537e20417831c159c107451fec49b88c4cde774330d8986430b39e0 +z a0550ba10967ed57b2ad1dcad707c5443ffc42d6f7ec0e6d9c684d877a74b079543e73a0e124808b441122cf9fe09a244cecbb10d96f40e6 + +x 4b25a323cba12b5d042369a065a3696c7613898205f7defd3ab15ec351ec9fe1ba453c8b9abf254ff793c92b1f77d5f23f7629c04ec5c70d +y b12ee8f930b029e2e4b79b808566b88b8087a510e5f80751ffc8f5426709bc2b40608e3e769dbd97d37dfe8a36fd25fbc1efb2cd9eda09f2 +z fc538b1dfc51553fe9da0421eb0922f8f69a2e93eaefe64e3a7a5406b9f55b0dfba5cac9105de3e6ca11c8b65574fbed0166dc8ded9fd1ff + +x c441e6cebc634bd7de7de356e855528d52f4affae7cdd585352d94218ca171929b17b8f49ea294f5151a277c116519de5ff92ce4e2f6ce0a +y 809617d4e40d53223f01887bfab5a7d2dc1eb4f680ae59981b33e11fe71345b3155f567cc867cd9e48c8b534870c7df49dff883c0900d8cd +z 44d8fda2a1719ef91d7f6bd2e20bfa5f2f1364f1687c2f1e5160754173b5b645b1760e71670a62945ee2dcb0987196d2fdf8b520ecf6a6d8 + +x a92361d9c458605877a6d9229128b1a52f7bab378d0d389568aae10d09d419b0e6436684b438abcaa3e1710efee5ecec1af06cf0c82b339d +y 74bc6cd43025234b1a6e15fe2d4fab520c874af6f896b82ecb096b0ec3cf73ecf04ef1d13ca612ef0981b8aca0a769ae60202eca36410b0e +z 1de0cdadf57d83a39114ef20bf775cf83b02f62d86a4f0c333b44c1ccca38d9cd7925756f1debdb9ad622abb9e8d569b7b109bbaff6c3eab + +x f0ed25db758767b83b1d5ab6f8bdbe8e263b18341ea296b2a5d27c0d928004d6c48695ac88af863ed12be6629d8a1b58ca83ddb4ff9c778b +y 44998d5a87e29ace239af04334451efca0d8bb88b441140caab3e79da9c73f1354df0c4e2a8148141bb44c33eb63f1c0025ec2b289390e06 +z 3487b335fd6902875fb74afa2c03dd8ac713d4bcd2e3aabe4f8664ab3b4844e91866a2fab230cf52ecdf329688ee0c19cde19f6789d68591 + +x 64429139cb6dd44a64984ac73cdf306354a32772da0724c647164d89218906de465c0c47f2841564fc69933d140088a02584bbeb7a138e7a +y 391d7bf04dd8082b6b196651c251737ba319720b66075f2e65a06023e1dc9697ee4c540b6fae20bdc333c9a95e69266b5ebeccf0b2aea18d +z 9e5f0c2a1946dd75cfb1b018ff30a4def7bc997d400f83f4acb6adac03669d7535a9605261333621c09d5ce77269ae0b844288dc2dc22f08 + +x 0bb7ca441d108e3d7a4c43025798eb1f1036e2d2200e2457aa93a631c068bf9e99805e8c69344d6f5fc063865f2e94bb954c20645f8b7003 +y 3f47bc6701604867acc3cf534d62c9847617954d860c34ac2bcacbfb1c24c99a7442a6170ea6539df0c98afaf6fc8f45dcaa77afebcc8290 +z 4afe86ac1e70d6a426101356a4fab4a4864d7720a71a5803d65d722ddd8c88390ec304a477daa00c508aee80562b240172f797134b58f393 + +x 93205ac6e814337d0d12f8e55f0b62a32ba948cbc6df03293d51e67a7aa7e1457d201991f3392f1cc4a4a9b6b2ed27407ac4e24a5b0e2664 +y c2d648607a99e6dccb9f9940ffed57de39928d9c3fcbabd79876ecf1a5476ff5a637d0052f04d82a2794bf0e31268fd6ff640b4aa1ac921f +z 55f7a22663ae195ad9b191265ff9b981653bd66706abaf00d6c7d26c20ef503b2458e996223e0747eb3869c5e313b7167a29ee94fcbab883 + +x 42bb562d81bac7f606d2157697f29f1799b3e5172f003f44785b80006fb56681b832ff6e7875d6a146b09a9a95f9f3cfb210f5b9aa545e0c +y e7cc109d2ea008a1c938c66e296911c0d7503b1a961f23edce9532c718e53518729dcc6f7e921f831c56d1d8ee7c5b4919f4030ce6703e68 +z 298867caaf5ad097d00adce4c05bb1d770042132c51f623147f1b2c7879a9c992ad0cbdef607f62463066c7384764f19cc04f9c590c59c74 + +x 4cfc133cf2b3e22f569340c3a59299087f9caf8b36562d418f2e18494769278c16a22641e4de8f675e9540d6fc0f8c210a64dd63c8d01453 +y f33b0a3beaad1fb12ba48d69ef999bb7a5af3bd2b977aaf518bc65a13caaa9d61cacbb7c5ce6173a282d341cf83c86a458c8d2d10a1c1ac2 +z 40381e77dc6102e18137ce2c952c35c0244ceb5df0cdd736a8ea7dea8413d162334ee2bd40c5a7a186c274f2f44c12c6622cb035d3ec2e15 + +x fc64ef657d34477c17b0674b697cc5a4bc8e665ba1dee02e5afd0d2f57e0a64abb2bc428215d9e8ece95c5283e4233d483201c286e4997cb +y ed4af51625762548e95f32e7042f07bb260f734fb9ba43301daddff9a863990d79791d5db1bbbdbad75c09ce313d93638c219c989702c5ed +z eaafe47ca2aa6cc400109a326eabcc5fe39dd9aa5a99245f77aaed280144405834a5e185d2185c49a6f2cef66f7fc6371042b8c0054c5cb9 + +x 2fa4cdcae0b01f3f3aa28d4ff311054c73683c09749eb312cd4ff7cf018fa647a66b44477459cab757b9149623ecf9064dba16d5601eafb7 +y b378045a6652eea3cc9a8530dea6361daa86866f038e579670f2d50e072417342f1887827335a0a041d1411b24a68d8f190edd8a251ac3c7 +z e31cd22447030ee3063d1380d1b83b691defc278772c0ba93d42cdde09b3bd7bd583cbc9e78e6a58998a56b14792879666c8f35f8638727f + +x 5107c636bcd6bc59ec9c7fcf04efbf90fdde936bff7e221be660d542f74fcccb8b49220b93744203bdb7b026f1bb9fd9a64c0187fd3d99a7 +y ee48bc6d5c231bd7be253ed69171d2525157d0d8fe12fdafa6e7a3285f0d966fd4c570928f61850138489fca5cb540444c24b602d9025899 +z 405082a418fad730abc2bda5966092e34e366444fe911fcb8c48796b575d623b600f939d22d6c704f5ff4ff14d71e01df370b789d640f140 + +x 475e593758fa8506baa94e1b6070aeaff278d905af67f9e5a5273ae0737825d220c02ae7a89f39998f98895c83e51e7bd0cc0c9126273792 +y 3f724d7bbb27bf8b2f4e328bd865e412ed6207802703def28b9b64567b15f7648c1f96ca5092400e32427f9880c95fa0a83f7fbdd6b2d2b7 +z 87d0a6b213224592e9f780a638d692c2dfdbe085d66ad7d831c39e36f08d1c37addfc0b1f9317aa7c1da08f503af7e1b790c8c4efdd9094a + +x fb7923d1a8666b372b41792749ae312903e1b1a8198970a5da6d85dc19a4326bcde206ee841a2bf106c95e99b42fa7eb3fa559b4b88d31c2 +y 45e467dafaee144bbd614028c0ea4d3a37b4ef99ded5c9e44b7526916218202401233364bffadac9424143bac99b4c2d89ceea71c3fd0ea4 +z 415e8baba3558082e8a2b94f09997f633a95a142f85e3a8a26e3ab6d7dbc528fce053a52441506bb490aa2537ecbf318c97344267c8b4066 + +x 2212850af1b191227fc4875e981ee15968832cb6898243af481b62d91ae5cb26fdcd72e45a54cbbbd9efc5e1739f8683d8ab318586b51e7c +y 6b7b3294bfd31a11644924c988b0b19cfc1db66d8e674040ee21537b54aed4e1e217f0b3427d7d4d9dc7d9dcbcda8c2c47c5348b9eaa7ddb +z 8e8db79eb085ac33e30dac2721cf92f664a1e22318ea83ef363db5547093a008e0e562989dd1480977b79fbe307a13b01f71661025609c57 + +###-------------------------------------------------------------------------- +test sub + +x 890e734c6f4af5b1c62cf6fdd0facf76af535bdc9781396c59a6cd8c37cc96aac97fa61bef07c60c69dfb633049014868473d28481385ba1 +y 0a06a622804bfe9041259a435be8c40aa56d1be10dd3c4261157c16c0d0d99d11b0f5dce0b164a2e6d4c53813242954830a39f2c894fb315 +z 7f08cd29effef62085075cba75120b6c0ae63ffb89ae7445484f0c202abffdd8ad70494de3f17bdefb9263b2d14d7f3d54d03258f8e8a78b + +x 17935b9768cf9ecdc3b3a4c3c87ee20f766bca820f620c1852a48d680f445f1a28ee6a9a18fbdcdb9f35846bc6f0bbb1687b227bcadd4c3a +y 9f913b62023a48e577ac9aaa6d06bb5cf46ea3acc2946a80f66fba02859837491a31b6740a5ed1178c8b6faf4198ac836419deb8aa439c0d +z 78012035669556e84b070a195b7827b381fc26d64ccda1975b34d3658aab27d10dbdb4250e9d0bc413aa14bc84580f2e046244c21f9ab02c + +x b1689e72355c7305d5cab07e2d672e7b92872c115f03f9b45fe7c9d3354ea0d3702f4f915900085ec44e816dcd731086c999c0e97ce52b40 +y a85e9b5cbe9f628049f91b9adcc1db63f19e8f7c37b92e43015d0f76f188c1cfe89c86910afb82c2c6f1f7197562b919380a1b32b2439006 +z 090a031677bc10858bd194e450a55217a1e89c94274aca715e8aba5d44c5de038892c8ff4e05859bfd5c89535811576c918fa5b7caa19b39 + +x 8f952f2233cdba45ccaafcb8e6d17b38529a44ff49e8ac8dc6378710d5e5af052c460e2758e3ee28f5866e71737c9b6e7731c03d11d21cd6 +y 5bc41fd436b58032dd4f50cd0c57bda1127a3033c2183d8133cb9c40760ea41bb42f48f36b6a2f3bcd0dbc60b5bef5e4b712308ca0f2b443 +z 34d10f4efc173a13ef5aacebd97abe963f2014cc87cf6f0c936ceacf5ed70bea7716c633ec78bfed2779b210bebda589bf1e90b170df6792 + +x 708939d3a13fe996dd90b1128231b7da3593c12d9ab880a4da9febe7f12bfefe72aab1608145911fdfa1e3f1f59b426a06dee253d4d3eeb6 +y 008929e61e53becf9bc6dcbf6414f3a71e9f134fcab293cd42e096fef3d87a472a79ed1ce623708aee31e12f5bef9bc6d0aa470ce2a52f80 +z 700010ed82ec2ac741cad4521d1dc43217f4addecf05edd697bf54e9fd5283b74831c4439b212195f06f02c29aaca6a335339b47f22dbf36 + +x a7996b0ae1d8ad5856ae5cf3abc8fc61c4b3579d951b632b9af67dce957365759fb5a6f54965a86b1dcccc9439eebdeb04f616c3fb4db382 +y 2df8e6cf52e985d0e20f4f5e9bbaf1b8bd7d7b982da05568b7ea82fd2a5c0302d0ce9feec5e135eca886fd30827905eae204a51e498a173d +z 7aa1843a8eef2788739e0d95100e0ba90636dc04687b0dc3e20bfbd06a176273cfe606078483727f7445cf63b774b80122f171a4b2c39b45 + +x 74179531aaf2ee4e7a309350982fc9ce501ad18c650f0adacce5da9b520ce27c04ca69dca0e719713d4d10db532401bee26b7ff9819bf532 +y 6a3554898f2951ed005bc4ac74dfd0ef124cffbb52301109d8414719473dc17a602a3b530195c383efa22dd6da87414395886e4b9dd5b5f3 +z 09e240a81ac99d6179d5cea32350f8de3dced1d012dff8d0f4a393820acf2002a49f2e899f5256ed4daae204799cbf7a4de310aee4c53f3f + +x e7c145e38ca66fd86991538ab11231abb60af8b0ab7460e047f7b5b69bbe4a3a56c28c14131c35621f4014d541ffabd642c774bc1a5c66c7 +y 9ca047c2251cc6012bd734198e4b2c6ca0d50a85db601659b8380510fc6c1d08a27fa5fb8eb3c9e5622185f83fba6ed128d153cc9563e1d6 +z 4a21fe20678aa9d63eba1e7123c7043f1635ed2bd0134a878fbeb0a69e512d32b442e71884686b7cbc1e8fdc01453d051af620f084f884f0 + +x 8f01ab3bbedf7ac443423793a422910a54dd73f121ce6f52270d7953386bf2b0eb228b2560b7103aa94f3190e80038505f2b21a9f138c414 +y 44a6b845b4b3b6d9c55478664fa2134df50e7ff4c5184aa57bcc8d01da42cdbb78da3898fd92287b604b6a369c06d695241c48605b57808f +z 4a5bf2f5092cc4ea7dedbe2c55807dbd5ecef4fc5bb525adab40eb515d2825f57248528d6224e8be4804c7594cfa61ba3a0fd94896e14385 + +x 1b6f84c1ad9ec3d008f345a19305aa35e5b55efeb535024b0fc9aee4be1c031bb070655fc5e672ea75b5db98cff0dcfb5427e21e5ffc4fa9 +y ad5d4e308c69186e87ac97551e9ec34f2d1746d5f6712b126c3415346ac2271450aca96fc6b9e82ef7e2f3fad60df4f184e34dff8fb53b02 +z 6e1136912135ab628146ae4b7567e6e5b79e1829bfc3d638a39499b0545adb0660c4bbeffe2c8abb7ed2e79df8e2e809d043941fcf4614a7 + +x 25ce194230be078d7f35b85d68706d768fec7994654fcd3f63f3d32eaf59f17bc87a617d41f76b7d0c78b63377a203e43194f0b056d26b0b +y 76266bea72a15cdc355867a490e775c909b7b6cfc833107e7c6b7dbaed2c8491c6d000b2d7d2beb72d72937285aa1bceff18aa35d0c52158 +z aea7ae57bd1cabb049dd50b9d788f7ac8535c3c49c1bbdc1e6875674c02c6dea01aa60cb6924adc5de0523c1f1f7e715327b467b860c4ab3 + +x c010bfa3d130f868f2b975318139c2a847c69014b76164192b437fd7e26b892a5a2425670fe3e8fd9efdfa250f57579d1af2d24f8eb6ce92 +y bfe65616e278b6ce46b295600131bf5ea092451a87f6bc3adf1c86f2fe717351b073062ced1394a14051bb33f3874cca569aae8ba97605f9 +z 002a688defb7419aab07e0d07f08034aa7334bfa2f6ba7de4b26f9e4e2f915d9a9b01e3b22cf545c5eac3ff21bcf0ad3c35724c4e43fc999 + +x b2f21992b1f2155b7afc3a1d731b52c03cf14208e634b7da123888d652afcd919e9f5f0bea8b9986c71a7ba08fefe58ee0402d9a23b95f2c +y ae241fa6292c63f3c09301255a866825b39c9645512ea123486f9a873cacab567cd169c463fb1cf0417633a7055d831d23fd1d58dd42e726 +z 04cefaeb87c6b267b96839f81895e99a8954acc2940616b7cac8ed4e1603223b22cef54686907c9685a447f989926271bd430f4246767805 + +x b714b60b2614ab6ce63bf8eae621357f2e921f79de94982fcd5f524015db3faa52b15ff042733958fa202786f61bfed0b9fb5d5873619aec +y 0c99e1da4c747ad1a625321cf9359b1d823544d1eacfddc38e4bfd729ed2f9fb37760242340f7986843fb8fa0435bcb5cffdf11453caebcf +z ab7bd430d99f309b3f16c6ceedeb9961ac5cdba7f3c4ba6b3e1455cd760846ae1a3b5dae0e64c0d175e16e8bf1e6411beafd6b432097ae1c + +x c5425daf8f7089def2ff910e256d9496fc109d2698cf15dec1ce3f8116231969c5ed327626362b0658c60e74023a3cae5ef128fb5d27cad7 +y bc4e49fbf095f73894c4d623a210475cb7ba78ebbcbee8ab55a851162f789fb21e72de95afe4ddd45b90289f94f6d02b5f5a4b90c603ea31 +z 09f413b49eda91a55e3bbbea825c4d3a4556243bdb102d326c26ee6ae7aa79b6a67b54e076514d31fc35e6d46d436b82ff96dd6a9723e0a5 + +x 9aa20b4259efd3a701a63347181fa63f56f42a97ef836bf3aab88d30bbf28a91bbf713a0170024e6057e2281ac113f9b58cb13d63e850ea7 +y 09e7104367d8c0441d811ecc619af04def9236752c2d47bc508b0de3c3b29c74533d8eb9fee13279aed8d58247e4010206c697d9b72bab43 +z 91bbfafef1161363e424157bb684b5f16661f421c35624375a2d804df73fee1c68ba85e6181ef16c57a54cfe642d3d9952057cfc86596363 + +x e8ead9316aeb8f56d43418cd3bb1a71234c9e20b4a6dc1604ffdfdbcaacebe73b71d18c2c167544304d895d67e2daa2538a4ad0708cd9acf +y ff3603f0960bb7a92f2b7fbfe242b467164e0ca72e89bcab6c467b5391166d05c601b38de40643f04d5b50ff8ec62b18c69e9df74f01babe +z e9b3d641d3dfd8aca409990d596ef3aa1d7bd6641be404b5e2b6826919b8516ef11b6534dd601153b67c45d7ef667e0d72051010b8cbe010 + +x f37b41d9950036d560f02b8befd6f5c73096b8995850b9fc563291fba59fd994916744fbd4c1dd5d17a9e5ecd4ec4a658dfdae1ba7024bc6 +y eeda58ba400f16a946381fb11f0ac0db895957236bcc629ce9d1ea425eef8412ea73af488b97f1afa950736f26c3cace887417b699cc3410 +z 05a1e81e55f11f2c1ab80cdacfcc35eca63c6176ed8356606d60a6b847b05482a7f394b2492aecad6d58727dae298096048997650d3616b6 + +x 2bdb71a053047c4173718ce104e5b8671fbd61c59bfe8b20b890ceda15a69d24eec3775f4ce8a9c16d36e50626bc334e0fc1be492d800c06 +y b1ccd0dac33ac46b2709f9626ed70136f98dfbc705ad93ea8f1b325d644daf2c0180cb83bfdbb7398d3f58c0f6600056a174850b9db91ed4 +z 790ea1c58fc9b7d54b68937e960db731262f66fd9551f83528759c7db058eef7ec43acdb8c0cf287e0f68c462f5b33f86d4c393e90c6ed31 + +x 8f3fd6346c7f2dacf0d7cdb88a5bca3b222a895a07b169d0bcd0af0a9aa634876ae1a939262dd75bd12b5a97127155a015e00acac7d5cbc8 +y 0e9c03c5a06accdddd0d8613e41a00f2b586e297e366987e02e7536e0ca1b4c2c75fed619655acddffe8585c7a828432d90575731a4c8519 +z 81a3d26fcb1461ce12ca47a5a640ca496ca3a6c2234ad151bae95b9c8d0580c4a281bcd78fd72a7ed142013b98eed06d3cda9556ad8946af + +###-------------------------------------------------------------------------- +test condswap + +x db0be3ccfda1e2f8492bffb5d3344f1856ff1896b6a067d2fa064423ac5b05b669db1c9b51899c44a7f470be4173856d9aa3d1cd10cb8c9b +y 3005560f89232a97cebf6808e7493dd0f17e572556b53723b57faee51d8a0a45c7fb51aeb916f59c74ea6041494483b2fdce72189d1bd031 +m 0xffffffff +xx 3005560f89232a97cebf6808e7493dd0f17e572556b53723b57faee51d8a0a45c7fb51aeb916f59c74ea6041494483b2fdce72189d1bd031 +yy db0be3ccfda1e2f8492bffb5d3344f1856ff1896b6a067d2fa064423ac5b05b669db1c9b51899c44a7f470be4173856d9aa3d1cd10cb8c9b + +x ea009751f6a7045ec7d6d46b16cbe663f5a78fca3835626c79864bec4030443bb9349654d52b2edab92b8f4aa876a97e868aa6267a54e6b1 +y 8c6f864ef7f664f4985ed8c1ea0c63bd7ab355b5321c2712791b610a2dadddc90a65ca8d5c25ff199b011193796b08f96420934615103b7b +m 0x00000000 +xx ea009751f6a7045ec7d6d46b16cbe663f5a78fca3835626c79864bec4030443bb9349654d52b2edab92b8f4aa876a97e868aa6267a54e6b1 +yy 8c6f864ef7f664f4985ed8c1ea0c63bd7ab355b5321c2712791b610a2dadddc90a65ca8d5c25ff199b011193796b08f96420934615103b7b + +x dc3aa7d363058993cbdc54e95f3c972a2cea17cdf9370fccdfedfa1ba939ca35f762c5c6283f84348282fd56d83539804427eabe3bd6170d +y 8c47a0990eccf7300986232dbc8ee26e8996c3bb4b73663ec5525312bea8975221c9f49039840c181d042654a8c1806bb86702ac7d0b80f4 +m 0x00000000 +xx dc3aa7d363058993cbdc54e95f3c972a2cea17cdf9370fccdfedfa1ba939ca35f762c5c6283f84348282fd56d83539804427eabe3bd6170d +yy 8c47a0990eccf7300986232dbc8ee26e8996c3bb4b73663ec5525312bea8975221c9f49039840c181d042654a8c1806bb86702ac7d0b80f4 + +x 69b45538513af2148e0a2903539bc5e20fca4da447278bf5967091d2e781121080c14a41989f9ee5218c444d3a42989ba890c7be7faae5d3 +y 935eadbde0c571c29deb4d8404dd39a8cca177ced36c359abfa7a6cafe6075422e1d79cba8d81cdbdfa4a5144faf37b19ca22b2b40fe1a0b +m 0x00000000 +xx 69b45538513af2148e0a2903539bc5e20fca4da447278bf5967091d2e781121080c14a41989f9ee5218c444d3a42989ba890c7be7faae5d3 +yy 935eadbde0c571c29deb4d8404dd39a8cca177ced36c359abfa7a6cafe6075422e1d79cba8d81cdbdfa4a5144faf37b19ca22b2b40fe1a0b + +x de30072f175127ad4200a08099f4d0df0edfa40eb02e21a03c5628dcb2f70da8bce9ebbb1ebed2aca391e73a4114c06bcdbf762bf28777cf +y 5eaf3aecf1f7d1fd3b43be8fa450163c79f162b0c6eaa4b1ad39baaf3a4c36564e001c935fdce38e90789151beff0f3cc4fdfc2d86dcb587 +m 0x00000000 +xx de30072f175127ad4200a08099f4d0df0edfa40eb02e21a03c5628dcb2f70da8bce9ebbb1ebed2aca391e73a4114c06bcdbf762bf28777cf +yy 5eaf3aecf1f7d1fd3b43be8fa450163c79f162b0c6eaa4b1ad39baaf3a4c36564e001c935fdce38e90789151beff0f3cc4fdfc2d86dcb587 + +x 1bb20a5a05b190737ad6b2bc5bc2b9259fa7e36eac8f3032a7c56ed59c1510baaea32bba898b329b0c64fadbe454095b9f82b366bfae3d8b +y cf0a87c8befed020caf82f37b4c5f17d2aa9ff8ab75baa156cfe2716ac1eaabf9bc760c2ddcd66a9d02a8384ad1db9e8f857b151d126e0ef +m 0x00000000 +xx 1bb20a5a05b190737ad6b2bc5bc2b9259fa7e36eac8f3032a7c56ed59c1510baaea32bba898b329b0c64fadbe454095b9f82b366bfae3d8b +yy cf0a87c8befed020caf82f37b4c5f17d2aa9ff8ab75baa156cfe2716ac1eaabf9bc760c2ddcd66a9d02a8384ad1db9e8f857b151d126e0ef + +x c186531a219344dc485cd5dad6500616ac8e0653693168573cb9be590b02dfb1ddc5d87d27f2d9fa46ffeda955a6285b7ef2b9bf84825d06 +y 91f3be7eb2e0be38d92974d81be5126ef40d358f242d23aa4863fb16ba3e8844e02edc87c0206e211587886ed532da0ab148cfcf64e9b58d +m 0x00000000 +xx c186531a219344dc485cd5dad6500616ac8e0653693168573cb9be590b02dfb1ddc5d87d27f2d9fa46ffeda955a6285b7ef2b9bf84825d06 +yy 91f3be7eb2e0be38d92974d81be5126ef40d358f242d23aa4863fb16ba3e8844e02edc87c0206e211587886ed532da0ab148cfcf64e9b58d + +x 9f2476d6db424d19ee0cba4ed091da5b44ca63caf2f711eaeb7edcc75f49e0d0c367c1f2817b6bb39460f897432901064cabed7f6a03b1f0 +y 66e7dcd34d76a19e3285685112b7619f9a3557764a918922faf1370bb97c2b2fa845dd34662cfe7299ab702c68fd43b5f6f15a0af6625f2e +m 0xffffffff +xx 66e7dcd34d76a19e3285685112b7619f9a3557764a918922faf1370bb97c2b2fa845dd34662cfe7299ab702c68fd43b5f6f15a0af6625f2e +yy 9f2476d6db424d19ee0cba4ed091da5b44ca63caf2f711eaeb7edcc75f49e0d0c367c1f2817b6bb39460f897432901064cabed7f6a03b1f0 + +x f124ac31d304a29cdd94bdc0611c61064a7c5f09cf6847bccd52fc7a7b77ede73b42b1ef75f000de4361028e0fb63896f4ef5ad3bc1b9c90 +y 6629084a230c793086e469b9a01e052ad7a5680d6955667e0dfb19a250f447d9e238695400dc4ecaeefcebed44d374e57ec4e414f5629e63 +m 0x00000000 +xx f124ac31d304a29cdd94bdc0611c61064a7c5f09cf6847bccd52fc7a7b77ede73b42b1ef75f000de4361028e0fb63896f4ef5ad3bc1b9c90 +yy 6629084a230c793086e469b9a01e052ad7a5680d6955667e0dfb19a250f447d9e238695400dc4ecaeefcebed44d374e57ec4e414f5629e63 + +x b64f2952510827bef3d32ef6347251274c7241d9913268a7a6a5c360a4b29e7ed04d09a9ee5aa83235eaf8c0582b076b21d78b7062952773 +y 77897028a9a81fd54362a6085aa2c2fd6fdd44589f447c7310b9b3b5a29b54ed15c57e2c9fbff16f20129a4dbd43640a0d1037e277ca5c93 +m 0xffffffff +xx 77897028a9a81fd54362a6085aa2c2fd6fdd44589f447c7310b9b3b5a29b54ed15c57e2c9fbff16f20129a4dbd43640a0d1037e277ca5c93 +yy b64f2952510827bef3d32ef6347251274c7241d9913268a7a6a5c360a4b29e7ed04d09a9ee5aa83235eaf8c0582b076b21d78b7062952773 + +x 4d75efd204a66aed323456e6f55cb891ee7a31d739ae89726e0ea84532f9c740d1b647b117094fb85da2c62da04f3b9cb13db6b840046b7c +y 0afd07bb073a150e7b82711e1f42f7b0789af8192ea6b4e1b24a3d48de7f8b802875aca5a02a9d24deca0b58c895992a449d01026495b96c +m 0x00000000 +xx 4d75efd204a66aed323456e6f55cb891ee7a31d739ae89726e0ea84532f9c740d1b647b117094fb85da2c62da04f3b9cb13db6b840046b7c +yy 0afd07bb073a150e7b82711e1f42f7b0789af8192ea6b4e1b24a3d48de7f8b802875aca5a02a9d24deca0b58c895992a449d01026495b96c + +x 1ff4eb5f0280744f0c909cede8be29cccb8ae43e4626018a9a1d352a97d987678863ba34bdeb183bb5e9347e96760665f5881570778a2e19 +y 49cd390a9edc7fad6c84c2e44ce09e490161094d2dc6cad30759fbef10aa30e5aa6474bc46571188418f3e4a2b19ecfc379a1f94e3a44e48 +m 0x00000000 +xx 1ff4eb5f0280744f0c909cede8be29cccb8ae43e4626018a9a1d352a97d987678863ba34bdeb183bb5e9347e96760665f5881570778a2e19 +yy 49cd390a9edc7fad6c84c2e44ce09e490161094d2dc6cad30759fbef10aa30e5aa6474bc46571188418f3e4a2b19ecfc379a1f94e3a44e48 + +x e96c0316baf01c25ef8a41c02e99aa84c82f8eecd3249be268834afb5f7e95f0ad10bfad4160bb335c30ffd6a1090c91c57eb6ac7a7a5e66 +y 115e6f115bc4e19af60710f3dd821fb58cb680a32d6973eae9ea3e48f1928dc1d9f684a8c8de80affc59bc0fb342bb040f89d2d46b8ff8fc +m 0x00000000 +xx e96c0316baf01c25ef8a41c02e99aa84c82f8eecd3249be268834afb5f7e95f0ad10bfad4160bb335c30ffd6a1090c91c57eb6ac7a7a5e66 +yy 115e6f115bc4e19af60710f3dd821fb58cb680a32d6973eae9ea3e48f1928dc1d9f684a8c8de80affc59bc0fb342bb040f89d2d46b8ff8fc + +x 71bd8f5036da4c33f6940348ea448c2f9bccb152dab40b410bd695923a9e255b33aaf361055be4bb9a570e201dce784cc1ccb0f89faca85f +y 971b2f6569ddd9099a87ec4086d8218abcfbe81579f25f03634e471170a5088f48a6cfd09ed9e389ca37b780165c00b206304229135b6044 +m 0xffffffff +xx 971b2f6569ddd9099a87ec4086d8218abcfbe81579f25f03634e471170a5088f48a6cfd09ed9e389ca37b780165c00b206304229135b6044 +yy 71bd8f5036da4c33f6940348ea448c2f9bccb152dab40b410bd695923a9e255b33aaf361055be4bb9a570e201dce784cc1ccb0f89faca85f + +x 0f1165e19968f3e6159e9f7f843c1b849e5c3917af4e2798869112c6efca9993ed339c8495eec8c54b286820bf7befdc8ae344e4d309c077 +y 7ce5a2ae66b9bddd30c98d9aa9fcdd6ef90d244d10115d15cf5d81e9e389f6852b153a42c642447043fcfd278166b92c624508973449b0e8 +m 0xffffffff +xx 7ce5a2ae66b9bddd30c98d9aa9fcdd6ef90d244d10115d15cf5d81e9e389f6852b153a42c642447043fcfd278166b92c624508973449b0e8 +yy 0f1165e19968f3e6159e9f7f843c1b849e5c3917af4e2798869112c6efca9993ed339c8495eec8c54b286820bf7befdc8ae344e4d309c077 + +x 6dd07b4891d8f45ad1ee64da38383ec50d6f29634767607eca19a547cadc3c157ebe7d86a28d4d2fa2d40f2c5402d8b338cfd8d30aeadb6a +y 63da9a5a0cd51e58168ddb305c0e70a2f898279dae6394e1b3e1ef3a0763847d5d2f15be493114360204d037d7d3c3a9e746d27dcb544ded +m 0xffffffff +xx 63da9a5a0cd51e58168ddb305c0e70a2f898279dae6394e1b3e1ef3a0763847d5d2f15be493114360204d037d7d3c3a9e746d27dcb544ded +yy 6dd07b4891d8f45ad1ee64da38383ec50d6f29634767607eca19a547cadc3c157ebe7d86a28d4d2fa2d40f2c5402d8b338cfd8d30aeadb6a + +x d91228b648f75350d775432af35be9aa283e9729fcd3b689f0c7ee02ea67efd33493980ae5eec92ad6ab42ccd253a7aab5a62c26be275278 +y 07c5d1b4f9b8db88cd4187b1ae5e175bf703af12b26d066c1d55dd367569d3e23e3d0470f3c47e6761746ce7de39cf563500d026a6791980 +m 0xffffffff +xx 07c5d1b4f9b8db88cd4187b1ae5e175bf703af12b26d066c1d55dd367569d3e23e3d0470f3c47e6761746ce7de39cf563500d026a6791980 +yy d91228b648f75350d775432af35be9aa283e9729fcd3b689f0c7ee02ea67efd33493980ae5eec92ad6ab42ccd253a7aab5a62c26be275278 + +x f9e764e20657319802b53ee29df43b0d83d994d9049b9820fc0c31b631265c49f6613923a042eadce5902fb81753784ff5a9c0de2c4f6b12 +y 6ab2f8279e82aa65e8326e5c60bfa067e4967b3ea67d0369853282e5429736529a43eeee3fdf24ebbe5ca85b59647994fc99c90da83c6229 +m 0xffffffff +xx 6ab2f8279e82aa65e8326e5c60bfa067e4967b3ea67d0369853282e5429736529a43eeee3fdf24ebbe5ca85b59647994fc99c90da83c6229 +yy f9e764e20657319802b53ee29df43b0d83d994d9049b9820fc0c31b631265c49f6613923a042eadce5902fb81753784ff5a9c0de2c4f6b12 + +x 772289865ac905fac203e4654b258890ddb91cac71c6d2af3826e3acfebfa222c937b40069ce3a757e2ffd960b5821ed1ad54e4ad2e3c6fd +y 58dbf838ab81a754533c7f80fea48cbc981f724e4c150ddbb0afb5c711a8e21079446f77c427f7eb1892c096fa3eae5e2b070413611cd184 +m 0xffffffff +xx 58dbf838ab81a754533c7f80fea48cbc981f724e4c150ddbb0afb5c711a8e21079446f77c427f7eb1892c096fa3eae5e2b070413611cd184 +yy 772289865ac905fac203e4654b258890ddb91cac71c6d2af3826e3acfebfa222c937b40069ce3a757e2ffd960b5821ed1ad54e4ad2e3c6fd + +x 0bd6656d68c41bfc5389db274367f69191754919435ba58d2256017b5bc595d102c6f4f745b3ceb0c32bd0a6cdadded3a3dc925ef2b5c73c +y 1d903009c74d3d135a192bd42466cd28303f482626a7d10832f1f6eae72c3b051b0373e62300a71226011475034f0bfc6c9a65601bb83993 +m 0xffffffff +xx 1d903009c74d3d135a192bd42466cd28303f482626a7d10832f1f6eae72c3b051b0373e62300a71226011475034f0bfc6c9a65601bb83993 +yy 0bd6656d68c41bfc5389db274367f69191754919435ba58d2256017b5bc595d102c6f4f745b3ceb0c32bd0a6cdadded3a3dc925ef2b5c73c + +###-------------------------------------------------------------------------- +test mulconst + +x cb908747a1af81f52715ef8440aed06aaacbcd7903c99cdecef5ec54e7845bedaad6475028b0cbdb0d53b6eeb71843f900fefd398a083d5a +a -417895 +z e95e64fd1b2e2e79d1bfef5c96942eaf7ca5d40b1af774ed9c4ea2351c8ae81013f896bafd1f0b0e3a3c2ca3347c6cf88f988877af5e009b + +x 46b23d83c0848e79af947191cb76b087483beec6224af749e59c0c5ae27ff8abada31da895f8132aae0457f5ddc30d18a8d52046fbe6ef55 +a 384370 +z 31c9bf2f3bdfd3c1dc115db96d7a1c15e2a9ae67dfebccddc9408a0dcd147d9aa62ce4a55a2d6ad54542317756a08d6be3b959bf132624e2 + +x 53e19751de62909506bebf74411d359014ec4b6afbb8ce14eeed8a3938013f0fee6897e3cc3adcbc90d7df321c4caa1941d0e5909551335d +a -49682 +z 82fb902a8992ec1032a6837cec56189c45d1c1fdc47748e17dd9ecabc807a52eb537d6411f99f4d3b328e7ca76475924f90506a8adeb908e + +x 7ff3b9b3d8ee248a48d0c8d308d8c3658374acc92303143061a46656ae2b35094ed7b5b27d23366c0e42ee0a9471a4355d81cda0e4390348 +a 131908 +z adbb3dd21e634dfe2c41593c65249f03a048338037d4a107892df36f10e3ff68402d6f48e74bc7a7858f2c3650fd2a10acdfd4213850529e + +x f532f4f5ab5447b083ee4225246aaa4448696e4fc8bcf5b0ec1b52df88354e5327d7a3cf6e15db9945205968c275755ea3906a27437d29ed +a 383911 +z 1f42b3585a2553ab19b14639c3e3aca636d88053c70fb758962713783bcd824b729fb4d01dd56a344d991bf2d32a2967acf470b39bee88a6 + +x ef0e2a829097e50575eae6b1ad3fa10b8e417b0363654e0cb07a563a905c02e367c6f1ad7be1469b9f5295e3db0726853adffb820715f7d1 +a -226220 +z a7c5387af1b9f61f09d628feac1a050173021386775c9f534557b8841b812155325e3632eee7a2302ef8af0b4746575d6c2bcf3b29f674b0 + +x 3b4655b1c22542ca413f76bc24751a01cdab6b385b50301d67fd62ba31ad132150e38e12a849405112c4742e93b92849bd8b872c29edb2f9 +a -89924 +z b51c0dfa2407a89435fedbcfd7835b6e0849d8626995fd00974f44c49d794d3c5dc16028e9fdee45bbcd269035e8bdba695a6653028d4d59 + +x 48bdc2073bff25ae9bf7fcc368d65602a71e48c343bc7181c361331f108867d56c588f698aa5b91222f5dbbc859bce656f2607b053222fc7 +a 66432 +z e845dfe65d563884074ffeecaa325706df4a129b73b056cab6ad999588216d72525222ce00ce4d2ffb09fcf6f010a6eeb2eb753fefd44b47 + +x 98a26f23f83673a480076b2fc7ccfef07fbbe70c4160d5af638c345f7d17b00931efff543fd47b7b8b362a70657a458566ada4aefd1c5eaf +a 492192 +z 0ef483482255b5ca0f8338317f6eaf9c4fbf8bde8b8b04e26d2cdc0632186f1e62a9c3a1be23e8dc444ce50783135aeca614c884bdb77a30 + +x 6ebf7c4e06837120cc852a077945656046e64c2d88ce440bdfc8d38736a4d510a722bc8b0d225f11df0e704e4b04c48bf481da68fd1e150e +a -7098 +z 8d4e2cd12323b5744442fe4e4fc21748b344d7f94794398ec187f0f986ee743cd733a7a16bd4495818ab033103f020c794c988c5d2c1628a + +x 94e49f2bb473a7273abed94363c4dc3d13db159e3c3698a62ce5f321252aa03c7f63dd6eff9529c985f43abc7283d11140cb44ff6fd0f3d3 +a -392951 +z 58a606cdc1bf1d5646fc08c7a6b3336fbe532c823c70242ea7536cc6dcdde7c4f492306e39ac0fb88367e41d63a8305d69fab57a52c8c284 + +x cd262298ce3b73294bfb523c30206fc3771144890a0ebcef19e02e5085973a6aeefabdf8cb7186d57be38ee84b114b9a7a22556c0cf88df1 +a -237681 +z 7553420c53b255fb909d6e9008f043e7af25a2a9c29b177b830ff1ae6f6fdcb6aefb8386465f24634fb04c6078322ac691586f91cf7928bd + +x cc9bd2e72ce15dd50877f95812b65c65cf09b14e2817784a5b296c123e498c532362180a932a455b2ddb75e26335dbcb21eb94a90ebb6940 +a 246794 +z 8838e720b6e497d9cde9fbddc2333c13cb5bdbbbe5afe41ffd61f5035c8c4987fddb8036c25b0505765bf1a5aa369c6bf7723c65278584a8 + +x d8ab6b8f3523e98f49140e051c0b744bb0068d20f499c0763aa28ec1d1dd7e86356f357149c317376be96cd520b3ae04a2c4d468d74745e8 +a -360296 +z 4c0bc5f6fc52c6302b74c790d57ccc8fae59f2aeebb59c3393c56e70060f4d170ea41354f5040804a6e8dcb4a7c585ee71a6d90454e701de + +x 6036fbfb9fcc223a1776ec67c9424788aabe553a7d6a0472159edc747ebaf97e99f7263ece635ef0b702a3610aef32e17f59fae503e18d74 +a -5433 +z f6fa9a49b55077330fcda976a19ba7cfd98e44fa54044840df0ae9e19710193e684703f7fadbcbbc534e7be3adec0cae0d95ea414494f368 + +x a3433dfc89ec4d6d858bb5b018e2d474b7de7604ed4491957fe16453d3793740ef88136814f59b19ed3610252e74cbc3a36571d02e57913b +a 237641 +z 7a01a802b7a5aca44675887d9cf94d04d4893e2dc5d7474090cb32798fa370690255f57d18dce2a57126bb5883672b5a74a1c780f48f7bd8 + +x c17ecc6099e9630a4ec20f4199abe1c10d414f6d734014ada1e6f097090a2bb4e638fb52d9bf56080d77c2b535f52cb091cbaad3c65072e8 +a 517226 +z 708adeac4ff99cac4c3eb649d55276f58a7d21a0507af176a53893c567050d352af501a9c242baf53121e8b56f5679b175dc01538350b644 + +x 134263fd765e5f1da64900df5643c5241d4fa8a9e96ee59f01667b64f9122e85e995b90d4bf5d5fe9f68825dfa6edd19d8ce009270ae2984 +a 390674 +z 2ffbda7ccbeecd8dc4600965679146753c496d35bfa546e13edbbaa259065b024c8aaa3a17a3384f4f14d5ee01371ac55fb50a153b4ac1c0 + +x 54326fffef9f0fe1207a07c8ac063d64b3fe81528e005f857319a74da2c3423a552b05f8c465908b028a2dcf15cb7158c99a1d2bdfd890da +a -255467 +z e554e875e480c68c4fd780425ff8fb50f18bbafd0536a09489bc7cf197fdcb80dd4c7e31447a1a862066b6761ea39ea3b8c3002039c86b40 + +x 5c30f73ec3addb2d27e0e79579063f2d30fa9fb47c2b6a3a32553120a047cad83abc901e5a5b4a65f8e51144f7eb0abec9a4d105236b2618 +a -466309 +z 5ec894f6abe2d88971da11b982c3322d1f533a326057816f6273585bfa186a7f569ddf93c27e8e74719ddb515689d5935c56e6b86936f22b + +###-------------------------------------------------------------------------- +test mul + +## Easy tests. +x 0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +y 0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +z 0600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +x f7ffffdfffffff00000050000000000000a0ffffff03000090fffffffbffffafffffff00000020000000fdffff9ffffffff9ffff7fffffff +y ffffffffffffff01000030000000ffffff2f00000002000030000000ffffff5f000000fbfffffffffffffcffff4f000000ffffffefffffff +z bfffff6f02000083ffff5f010000a1ffff9ffcffffc0ffff6ffdffffc4ffffff02000082ffff8f03000089ffff6ffaffff7cffffff000000 + +x f8ff7ffeff5f00001000000800000300000100a0ffffafffff130000fbffff0100000000e0ffffebffffffff7ffffffffeff1f0000080000 +y f7ff7f0200e0ffffefffff070000faff7ffefffffefffffffff7ffff040080ffff1fffff8ffffff7ffff0500800200000000f0fffffbffff +z 0a0100240020f5ff7ffdff4fffff4100003a00201400400300a8feff030180e6fffff9ff8f02003001002c0000f0ff9f0600d0f8ff670200 + +## Random tests. +x 94aa99eaba90c5eb2efd7101c8efeffc1e44c8fcd84ccb8ef27b9792ae12534c0a250e5400407177bd655e51c343f776a3fd26474da4dc74 +y 284a0f7df2d7d7c760cc57b1606625884c1643020230a9eecca7de6098f5338ddf9297daecae8a07e199494cb6db91c2c683566bf79545d2 +z 213a31ed7e494f470736ded872f2c4f3675562a7b42bf01ea246be0ecaae2a61ae500690df9f99ea9fa8e5e1b9ccf3614bc34148b7693c91 + +x a434abefb0de3c7f5e33f9230ead871bb3f06888c0d568b9a74fa32b676dc600fed2d54a042e1b97340852c4d6ef796a18561884d760d4ad +y 99d4c85f047d3dd8e530c50ae7d80815a30ec6ba820316f5da922cfa7a51ab45290ac2ab8a53082716a6d7f77ac5a285fac298eca4fd9c52 +z 97b2991fcc858d5667d3674484db9435ba71ab0c836c534efb823c123f9e94d0d3445257c55c73e8bd62f1d7acf1d75fea5eea669bfb9912 + +x fe9911abbe57f1ddd61acd062d59637b129a1571af65fb70169db0d8b12b498a66d1eefcf9c8cbea01179f113afef0ae192550828885689c +y e371e9a11f662e38caff28cf4cf5ca8cdfe4a8b99fa12a33765a22ae25506874fdcd85388ed406a955d293320e01957f119027ec4803c2a9 +z 171b49441f9891d927d2f6436eee1dc59e7872730be496638017b42151cdf00e9abb212bafc47c05a4e185bf7cf21ccd97b0c8ea426e4381 + +x 1c300df44d28406d070b10c1920e01ea8b9056d9e1d6f9704dbda3f6328c26a28e9e4aa07dc79e03c09c5639cf8b8c783c8b430b9d8c21a8 +y c565b0357a1e8aff3b3a6164ff34c9598a1c15a1551224fb38d25dfa3b0627c9d992dbd215910236aeeed23f4efd99640054b6648946346c +z f7871e06efb6f737cb4e04f708827092e94e3c70faee57f70096b9d674d0ac5b228824924bb705de49de9f9c0e834462093a9a5551fc7d5d + +x 9014dd22854f1f21fa1475d74eba669101c871c2a21ffd5d10f0792e3cc5d34f15b4735759575dda169e2dd868a5ae64dbeaa2a654cfde5c +y c6f59ecf6add5ff92813cd6f37de9c6f8d3ae9cd33e4f3236ff43127f463f297c3067493868adf7823bc285a3d609a57d9b0b841a9b628a1 +z cbebe67e30ed82acb0de699a5d874121257b78c2b0642583713b58fdcd089a6277a5c5e571538e4af9025dfc63cd78931be51780055dfb2f + +x c8fc23a431d744e45e8bcd2dd2ca612db40b26287970aa878a5cf6283c51b2bd4edb76f705f29bc3911a9aee8fb7272009520f3590ac4c4a +y c1015900ea58d6305b8b558c992bff50a8614843cd3d11274830dff6e1db405f8b268100fbc5e44c477cc2a9e83f825c7840e560fc2b2920 +z 6ecf49d92efb60a15a9de38ff37d3b23b339d889ad8b11cb332df260b9c49fd28b287a559fa5a5edf732b3bd1014711fb7d088a37cf6ef72 + +x daaea5c9549776d866be36a032027a65eb8325b1684d3c37cba068e69aad7d4f104ff47c14f669883cdef5dae9a0c7840379631ef97e6bc3 +y f8dc00891a9c55481a224309a8024ea257850b2bc62ab10bb5ea5b836776cd46994900d6656b7f7e0d9092fd824b16d20ea14528a0de7729 +z 83d3eb62429c2ece396cd7069dfa2985630da2fb0949b52f1df9231c82f32022543d4a2302241d0146b4db97f44ec5342b6444f463ad056f + +x 786f4ebb20161c96f93ffe3ee2b0cae50fc454d910b3fae4fbd8454b8ab7975c6cab8f6a1b593996b24b22603137a52ee732f9d19f9a6e43 +y d78d3df4f455c8f5d98baaa17200d4c94056e21768c4ca783188bf15c28dc86c581fd9c150f923f905becba19361ca94f7434d8a74744669 +z e857a2020e1877b50151772bcf06763285c1d8b2b5ffdb63e13ef4985ccc3b965fdb053305f16feea4a3ac0edad21423c80ef847181bdff7 + +x 6b48bf18ec4557e745cad3e106511bd5a9bbe136c77cf639745f891f54bb16c11e19770eb5112df8bb6755b97cb1e23c9c7efe589693764e +y 95c2a38f889c451f792c3d5d8b3237eed3f99e2b4857bfc48f75d7c0de3f293d2cfa7f97d65d75e0e3df633d84931973ac542ce07ba974b1 +z 2fdfb1146b569ac98b0811e600e2d8e578023024ed704f97c7f7d56a2b4a33ac6ec68d14f0789441a904d175fbf8b91603c532ecdffd27e4 + +x 1fbba059c333843e3cf0cff19bec99bd0cfc89c3b390200165680b742fe540b32042959022e7393c9e13ef7fa3f1dd5ac46595803210c536 +y c723bb3649b1d95647636abffd325e363931782f02002ad6d75d2082c980a7a2c5e1d51045880b36d4f62c16250faffcb2acb824d8d3d5d4 +z 97041eef8892ecaaa97c4effb8c69160b3878fd302bc5f0862bfe4894bf23193738d8dd95c9eee9539e23fff67243372b97f02c3a3934555 + +x 26f5bc0c2c49899690fa423478ab1cf7000be27609bf683896a6ce3f619510b061ca04debb6c64540e724d113cd4b8ff3485337851367700 +y b8540188b9ca77a82899c7fd26412dcbd6a3c9b45be595f63bce7426d7c16eb20c3a2dc86afe9064edc19840f75f05de828c276e98451ee5 +z d973580e88abb6c83defc009607082ffbdcae6ce9d577218580459711682f8708a15de9c62e3ca3b50e91a7bf5781deee152ac801a64fe81 + +x 6c044d6556abb8efdf5b180695293464a8bc4b9cab201822053c7295973ea0a8866425629cfff1d372a48f51dbc6a7f828691194c32c2c5c +y da28b84dfd48f206972fe282449991597bc7f0734916b6f7a253897fca2ccd6b80aa477cfd08549b6d25bd18932128e59889e2dcfaf76157 +z a599fabf997468487b9376500b58a51e0e00c86d9eac6f50157aa1017d99ac8b95e7842b36071a192784ef72433c06a1dd042990b71ffe8f + +x 50378c6ac56816962d428ea523a0cf87121fb3c53b37bac6d3a05fcbdfb8a5fb20aa014f1e1b01a3963534d403baeb7c436f72cf3cc5db58 +y 78901fa015c6f0d3e1072aa87d865579fa405615691a3f27945f9b1431ee8bce8ac9965a1f9b0f42ff10bc77c43cc93566eee9a9b79866ed +z 00127644003ed4b518f04abbd058a46015fb328883b92070bc5cf0fd98d7307dfabbc65f3e8551c622792efabe55f03953e498e360410790 + +x 5db2f6db35af2e1c84ab6832b967bf987cd03adea7113fb8806ce8fb3ffa426dc10997e13afcd39cf5cd65f65f8a09e650fad8e5f6ef2648 +y b063695bc97a18d6ccb0785ee4588951dcbee420ce8e37b25cce325352968015c94f9bb784f3a2bfa34c6a1edf710b63f139fff6d4f7b2f3 +z 999284a309482f67ab6460e73ad1ad267052b59fe50cd58a245e22079e2b50b119e312ff60a65037cf9faeaa259d22f689eaedd7924f1093 + +x d5baefaae7fc9000e0d55f287f740dfb1899ba6e9e36338959a16ac5e5f45442a37086b5519a0b439f38b129328aebf468dec4b59c89a249 +y 4febc8666dcf2b150faec9902a5f57e97275e7b122724c2b77d9b78655b455d424db93f859b8de6b09c4bad6d5ba68349c65c41caca67f8b +z 19e6ed86dc819e6b4368d196679328710f63bf1fcba6652265508b509ecd0e3e8b8bf17f8f1eeb361af107ef684a729a3635cb55de3f8605 + +x 9974be322a0f471cfe0855456104219d8037ca1cb5aacb9ff5da86a047ce159430cfd92f67e764244996668ac44d8d9787dc1b5754d215c1 +y 78c00f878fb41fdb0cd22c026881d5022fc470755e6261945b9bfcc3868f591f08288e4d64a65c9f3d0b05d3ab7f27d801aef29e5e98caf8 +z fd51b84f21b06377054dc879b8a176a7799951d5669486b210e4528b9f52bd60f88c2a068f722d85fa12761a4caf2f05bcdeecb7ed62646e + +x f4048d4a1602eeec43cdf20c3ac9f7b359935bae3648070276faf07a5c58fdf79771ba6c077ddeae47617971e2145f4960587637e7028822 +y 32635c7425108f5d19e35e4d91a4bdf3310bc884c9061d0697556ae25e17cd611e090c1179ca9a68225b283c8ab98a7b1e97508592c60c66 +z 8d6a91d016aaa7a0da03b06f5876ce8e8a71d1e5e5eb430d6c5ae16e1d6d9b61e77179b4f6fe43ce37cae27689983d41923f3b30e9d9f930 + +x 9023c019bf7ef6df45e0e44111903c622220bd3dde046679540302451d001e47a153b0ac7dcfb9831e2d262d8e27002197d9640900e4c1cc +y 1f5e2ca612ec6f14df4b528cc35001e763b9414a81381a1a3c7008c0cc525bdb00aea94ce2348f380dda43b5edf4fec7c8cf5ea2f5fec4b8 +z bf2c241efc180988232b83cda91e12dd0aec0d22ab68353c9841c4ea0547fd1b377fbca125f8cf92c426f8eb859f85a3853516ec104d9b6e + +x bbdecfafa9284e3067081b7d1bd7ce0e488829859628a8f6a38bc1a3ca6ec3130dbc1345b69abb7224b047fd3f2dadcf9cc11a8ec46a6436 +y 49a956ee69cdfecf29440d60fde9db1edd94619af97f625d45dc83c64994fe6c1ac858150cb526ca3c58a9fdc09d409ee3ed0b0cbcdb711c +z 7abfd47fdfcceb278c917afd059e335110bec63fea48dedf7f8275da8922201ea06be39e3d1bccea2d38f5eb7d7aa5ef4e6fe6792a9f0ce0 + +x a9483d4f0c94eac273adc392c3f425be610206683cbb6806dca47be3b54ad142fa2c54a7a473675556bcc8cfd50649af3c58d7a91e84b428 +y b986365aa08f088fe04aaaf2e00468af3fb41cda961b56ece5bedfd83cf9a0fb959ae70c23d9b27cd1eaf8b611d9e578aa0b9d899b81d5f1 +z 4af529627637ad3f3f1269319f4fd426d31e276287ee525d0c64974e55fca1cd58694eadf47e44dc3e843e01c36b22f9717067a907840ca1 + +###-------------------------------------------------------------------------- +test sqr + +## Easy tests. +x 0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +z 0900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +x f7ffffdfffffff00000050000000000000a0ffffff03000090fffffffbffffafffffff00000020000000fdffff9ffffffff9ffff7fffffff +z 8c000040010000f3ffffff040000f4000040120000ff0000800a000099000060060000030000000a0000e7010000180000290200800b0000 + +## Random tests. +x 776cf7ee39df23538f76e6be87ecbb1ed78477b858e3520f24b2b36f09a7dd61daf7bd5990af13c11b1419d8215eb69c30efc3917097797b +z 870001f8ff173e02ce682526a513ff99c6e9688cbec13839ecbf0fbc11d8f84f6cf53041b5bdcbc624f9787db9babe61cd477cb9395590d1 + +x 1e5ef8dd68207b3c3d3c670acee7ecb277ee6bc10be9fa3f3d800e1414bf402298ca443de6fd57ca899188c884a93d4b9c9d1b00a7c9ce44 +z 4a6d6da8002b6a0f3f5c3a9631254ccc62cf66c93279c4b77dda55d32514c8b388b543002f8055321c7195ce1fd26f51f48732e664cdc62f + +x e02eba6cd5ec1cc39ab92db439896520e50a5f9e9ed6d31ad37d00ebb2a54cb68f1c0ae537006ec2ffb14aaad2de16ff06194929b702b95a +z 95632fd74045a49782f6f9d0c86d554cf6efd07f9eef57d669828c77537d4c3a69138d755855640064f5e9bc8fbe0eca96fb04053f565431 + +x bad2a1348fc0b54791f9f2875009c8be2d30f14526fbbc22c439c1ae2b865436cd74f428766e4e676b795fe9333312f6334d4e4ec2378e26 +z d87a8f7ca45620b4646fad2c22792538bd16f37879dbc4d87c21cafa60c282f6415fde2fb6293a8b8a6e5b3901f88d75f9243023b68f41d3 + +x d6d221f2bf71eba62e49db570e13ca69f4a8a33543298619cda7c8d2524c9446b11ae7b7d301579f047565b7044b5286c2478896800ad992 +z fdb163312b884bc6d74c4c269011311388ead9c069884f48487f9ac0d62b39aa175e81976fb599716aaa68db4c02985a6f0ffe522b0fb21b + +x 20cc05120202e684981bce1db74af493d218ed8e0f5e76fad46bfeb98c69e504113b0eb91771c602cb422ae09846fbfef7c47afd09689277 +z b07d84ff34dc5f0cbcc60037400ee04ba09f34d1d7a0c6a80672a3f6c1da630681d4207ce1325d301b36f0acaafd7579a108646f5a26b755 + +x 72c4c3e4fcfd36389f558e0d4016f3f088145be47b2de85ee7ab963fcd8c7adf449d5b7c37ad8a32cf97ea9bde5c220fc896cf1b91633e19 +z 1e8f68736c3b259b661c0c1ec065a642e717f9e4d86003411b8e15ff89537d8e129c116d2f8a9e7e1b46879deedd66fa6ce2b60ab680cfb0 + +x 8c524f059e7ebcf3af3072dbd2f76ebc530adba6d26240c8675b5451d5558db648e7a61fefb1369cf2939ba1fadcf8e40385db5d57cacace +z a19188e6821f5cc2c53b7e59ae6f70e95fb929c0f282627ccfa2c6d9cb59dc871e9dcf3e2a8d6d66b7a6907d4d36c9de03c3d74325d8c1f1 + +x dd47eb6f4f68cd3a9abd6af401bd6f3c795d89474dd41a89025b24c8349a0de417c3676bb6ee36002d7c8ff6b4fb4491e693cfa617e079f8 +z 871f46c93dea48a0d937b3f1f724f66615daa9200f0b48cee01c3b20e4a05dd6ce01bd7b2713e096cc2bd1c5ce7ca0c075aed0fc1ef6fa51 + +x 577870fdb83454eed0711eb51d7bd91f9843769737566823e41d0668fad45c82fe069347769244af7230e6fbc40f5a71151279ae65e9893a +z efabd464218df4a490b9870d541c45e9b7ab29bae25d9e976539a553995ded0edc5610916883642a032eae4e96eb9e4e1443f747dec98135 + +x 8ba84194db2aad7b46005423b1251555ea931b933e0083fee76b9863fb528927f27a4a0617b8d75de306103b592a0fbd51b72bfbb051ee2d +z 3a29e940174d846df65d51070295f535a03e988fc401ef62f5dd2456cf52668390e61e7b6912186d6d5260f6d6977004003bb106abbdaf02 + +x 9f17e0943b4e39051abfd8f4512ef177fd5c368ebdf4b0af49df2e1d89e30c4e68ec474d81203964bfe9c1fecc1279e5e4f598ac97b48cb0 +z d794adb47cff3f7666dd0a934896015e59f278d9b1d6dc7a06328da96d6e6520670598129b7e1b26f9537216364199cf5c0010f23692ec90 + +x a6b51625066e4cccb7d45dff5b182e2a6bf4b1cce7090a187d38dd39f08afad6f868c0277bf70d5fb88b6e67432526e4feb39ae707e34990 +z 67315efb85e16a1e97130092cc351759d9c18261845329f63eba1e77d91ad2c7df51ffa50b655de81bc807ea2b3e137214a2b08b400f2b7a + +x 28a0fe53cf73a0419fdb4cb493c6425be8aa812c3693411816c90621097a9d5687feb16ebf874a30ec849297742b7aab5921427d7b474190 +z 69300770a5bc2c9c599431e5f879ef3f3ec065e3a2cfe82e3499018add58acada581e9e81d40799fc74674b9721da018a64138519abdb108 + +x fad58259395fd5bbcfca35b095253a3a121b62f1694e14cd9e2f85bd08e8a15d1dff98e3b81eeec678821a1ee9d6192c8351bde45ce0581f +z bee7e0d6d4de419981ba2aa3964adfc7545e21b72b65c774b2029c22e06f251cebf04cdffd23e2051b57f986cbf7e56f047050714a275e72 + +x 91e548171a8136d2d26e6bea02cb16ec9591e9cd5b913184b22b43d1029bdb214ef737f6e45f473f7d95b8fde075645c3b0c2dd2bd224278 +z abe2936ecf2ac3012455dcac906f691f2d96490539c9621658fd7f66790bbfe0d2df07165ea80e0c3282642d45b63b7db476b53e4f94f1c5 + +x a52c855daa9ede16ea8de7c681436d5d31eda6ca5b441f972e5cf5639a1c56f689fcb411965271853de2893f22b81d7d0facafdb49292e39 +z 382480e92d44199fe5f7c357ad2e5a7277beab1a3055d48e679516151ca85ee3cb498b172087d588738daac2ec1da9638552d76be97626ad + +x c65888cdc1a575fc9a06dce8800607f56fe88839948b7e4e2713aae44b0ae6b7c6b68786b11b430d22766e9e4d76af118a972729c67c06b7 +z 31311e4ff9600089b533cdac6c05de3ddfe6a450ee7fc90cde1bb297e2deb750336ac3ed2f6fa9b88ece846be6f6aeb392f6753eb6fa475e + +x a61c81d621df61ece4b7274f63ae4e9f2e2df1d603fc9303ee361962b2d70bd783ff1b5d8f3ed27f17e7773b2b1c85af7fbd70387bdef5d3 +z a014ef20adc291c0238be3759ceb9f9645524b961761c8a991ce67efbddda568359fe36e762980d75a58a7ba10b803c9f883fe4d2239a08b + +x 96ced952366c324c5fccd48ac5d475cc1944e7e455dc093f0d9680d6d6abf1e45c76a286ac46acb4de061b9eb673a2d3124e6c3b921ad71f +z 6debaeff6a7d2bb2c1389cb3338fc87b2a32e651ecb8d43fc012efc9b9c59c79487b742f0b30d0b64ac283af0d3b877102c6a7ff0f606eb9 + +###-------------------------------------------------------------------------- +test inv + +x d665678f17043846f953fb09c88295d7fd0a53bc70ec7d396aff56e7dfa376f3a338f0da0af9e07b66d3ff7443e3829b541bd667201999d4 +z 6839ab730bf666c6ca987d254d83bf32b981b466c147f04b823981da75e12c9ded469a0a462861a987c13f05739f47596401fec25a5eee5c + +x bb8d567f6163a92603a388405121bd58abfcf05c596bf0624bf65b6a8fe03e6940648382fe01e5ab58e37ce235f4acbfb9e02624001c49da +z 3f60d0fa0036da2db915e232bd841d09f006d4ba018c1d268af86d36990579d669ee63393b95c202645dcb1225fe9e64d14270905e63eb79 + +x d456692d8e00bf9cd86d22a9f4ad9e9879e6298274854ae82729ebbdb0cc46877caeb381506dbb097b10c180d615661189da65d431e3003b +z 6e0f5a173fb60be882a2b570200515dc7ad473e2192470ba89e6dda6cfdd6ff77026a1d76acdded7b5881a54d68605140a4ffceae70906d5 + +x 359ab073b7465de1358a5772aef79db09118541c062421cb30a972525a351f16b5545daed5f9ce8e91a283818df6cdbf443831fbe5f3e848 +z 2b0ea74e6f4533498eb3f34247a9674f3a2cf2ab0e4fde65ff11b0d1e756430bc5452ca4b85bd3a1f10f6e4e3b1874df8d19f390a9021757 + +x 3509fb8b7688f354738d4a8ca4091f66c880db794aacec6115e675090394ca77e1c83b955aaf4d8e75c6e4e9200be1ce5693532a561d970d +z cafa18317193054cff7884bada249422ba889c19693d66610fb774fb4bdfeac0e67a5ba6f84ace126c125c46b4cfd627ee777e231a6ffc1f + +x 42e2babc095d88b61caa8883e91fd045106db9c4eeb4d945703c1dee3229c58869e21f73909ae2f3c4437d301a2a3724d67f6ad310f63835 +z 28c43a594b6471412f504dc10fd79d2c04ec029a7723cfa0a90aef036991f1b56cf156e2cbc7533671086edb54036e9f4ddc9bfe2e3ffcda + +x 9c01d006213bcfda413517ec815e8cebc06707f5649398a9d14a5d64754375c1ded8aaefd838e8eba84746de07a0f9b32caa2325c4c8e540 +z 0a3b64374ac2149d602a9f0ee4fcf6d814c476f451531a086b04b0dd598287b1758f77780b7de08573326a9767e816309d871fb1962bb1a4 + +x 7bbd8a2de4bd2ffee4e93d0dd2fa9c5d4abcf9ab86c097921fe7d603b7ffdd07006c7d79d1a10267edce9b3069b134bed727c8f0ed1aca13 +z c909ffafbcc09a96723b9afba8ec0d00d5ce0c9d85de3c1e4de24cf44fb934bd0d2397b380885b7419cbbeac339fc85e2161f08c2f3515d7 + +x 6a64650ccf103604c3b030415f7114c88c7094fbd0fd2f2b6b907a27fe104ef4e0684c17ff9f26f15eee5e7442e679ecad3e49a0629cb5c3 +z 9db77e47433997640b4c0916c5123e8a4d9c7c0bcd12b2dafccbababd6c9dbc3f4ec7991ea68b3ad4ffc6f0be4920764c65d98bdeba8a811 + +x c3823c71f6c0f3679cb9c776e437e718f856c8fde038418942d062423113352aeb60ab84138f2bf73f268386cab0f2a1419660e966c24187 +z 558bff4fffa85d6f67ad44938f5b4473d250a87a120af9ff645a7db37a43808abe30c19c90bac94adb190840078214518e189d6c9fc5bef2 + +x 44bd920b0eaf47695f93d063cd85c43c58470c23796f4a106b298d5f2b091210d103e9575c369bb0be66b2323d89cc29602a8071697931c6 +z 67464f2dab3a95c9ac7c783017105df7d561d7ae499ad89c4698da2c0710a1654c89966a7bd30d2d5c0511ed9f020309cde84cecd66be8d0 + +x a6b12fc35e62532ea7c1fd49dd834bb7957da914ec3daf2e4f446b54916d016054cb59ffd4e3d9eecd4a18b08033ee8d9ff84db072cc4f86 +z cc70960f0bb743da1b23d11eb87530a820484a861abd68d2ed7079b487d88481d915b1b34c29d9938b5fa54d05c75cb1aebf0b722a6770b6 + +x 1773dc978cd9f94186b83fd5e10a456b48058acd9e3bbacbecee2cfd0f8303c64721ca64c2913d57764336ea055700c2fcafc60d9f4b817e +z 49e443096eb28c167ee62c63bfe4079418fa8e7f9e58757e13327680890b02ce7c9e5bbbc51366e0b3f5315edc456b6f65a09ea1b1a24438 + +x 552158406db36accc32edde2f0ce46e23a1d406f60e54ca6a789386df36a57434c826c9586c4b371df3179f675e5956fe7dc3022f785d9e0 +z e0025a1007d3dff5e44947a0292bee8db5abbd1a0fca1d3ab0a64a37925396cd96c21af54d36656eb0b60c63fd5651622ec5487d53f976e4 + +x 6b006d36f60750bb5c59f6eb31e2efe6098ab67de7a7a8a27201652380a295c408ec78351c2a799d62227dffd4731b7605e5c462dce2c1e8 +z 21785aae5f73da711f6144894728627824b685fac3d95068a9d0c4e0ee058301a8953322a5ee5be75452164a55477f1a987103a718bf98ca + +x 700cb76911e718ce8829f8d767c53e333dd2f7f20d2c020d1da3cc9ce96b9f6c7aad67450d5aab8f8c60e8ad77d4b5fdb86fae92a0ac30fe +z 257f202b457f19f27ceed047e6778204c2b71646fcc96e19c6f07518780bb5b1c456fd6e93ce2f1cb0aea1a225137511dc71e446c1fe22c3 + +x 0c909e0326649d4d375452c5b233a86e90b0fa88b20aa54e02685edd02b70aa022ed8af31e994b70b20101a5cfd8e16ba53c702840b4a16b +z 98c41073ea843b4b5ad6b0589699f48a1576e3d834f8e595b8859069b71bf5e16126aa93b20259ff0a03976ff6d7f78239ec1059f8cf1193 + +x 4529761361781e67037eae69c5ca9977b1e21468834eb83cd369471e5092249015cd263563bff9348a0f51e4a8517e27236ed1ecfe30a780 +z e20d5896be18bb273bb0ba84f6c070de45378bac6d793685e654764e5aa847d48403a68560b48dcb12573ac737366ae701072300615b4659 + +x 6fae83f7eadeaca22b6781f400b01f9de186b12e31fdf56e0ebe98a8420baacf5069ffdf26d0215c16b64027dd69ff29709a64cfe8f52dcb +z daa266a02c4500d989670eb63ab78219892d9c1ca2e17f4b5200cf1d920cfece5e80050be77f81a616de840bf19c23835ed17d57aeeea0f5 + +x 23ca16e8b4c15f8f2b216441d851368d185a7f8587f398b0cf775875678241094538708da0cb2260c5e056b59c003c30c8f84f5088d0c99c +z 9de1360b4718fc762e6ffab46827c5e4672a77d797aa608b31c132d1ad8138e7a64ba1f4278a07a6088f8cec9a01ea9bc1427c55241433c5 + +###-------------------------------------------------------------------------- +test xdh + +## These are taken from RFC7748. + +k 3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3 +X 06fce640fa3487bfda5f6cf2d5263f8aad88334cbd07437f020f08f9814dc031ddbdc38c19c6da2583fa5429db94ada18aa7a7fb4ef8a086 +Z ce3e4ff95a60dc6697da1db1d85e6afbdf79b50a2412d7546d5f239fe14fbaadeb445fc66a01b0779d98223961111e21766282f73dd96b6f + +k 203d494428b8399352665ddca42f9de8fef600908e0d461cb021f8c538345dd77c3e4806e25f46d3315c44e0a5b4371282dd2c8d5be3095f +X 0fbcc2f993cd56d3305b0b7d9e55d4c1a8fb5dbb52f8e9a1e9b6201b165d015894e56c4d3570bee52fe205e28a78b91cdfbde71ce8d157db +Z 884a02576239ff7a2f2f63b2db6a9ff37047ac13568e1e30fe63c4a7ad1b3ee3a5700df34321d62077e63633c575c1c954514e99da7c179d + + +k 9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b +X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Z 9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0 + +k 1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d +X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Z 3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609 + +k 9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b +X 3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609 +Z 07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d + +k 1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d +X 9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0 +Z 07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d + +###-------------------------------------------------------------------------- +test xdh-mct + +## These are taken from RFC7748. + +k 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +n 1 +Z 3f482c8a9f19b01e6c46ee9711d9dc14fd4bf67af30765c2ae2b846a4d23a8cd0db897086239492caf350b51f833868b9bc2b3bca9cf4113 + +k 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +n 1000 +Z aa3b4749d55b9daf1e5b00288826c467274ce3ebbdd5c17b975e09d4af6c67cf10d087202db88286e2b79fceea3ec353ef54faa26e219f38 + +## This one takes aaaaages. +##k 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +##X 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +##n 1000000 +##Z 077f453681caca3693198420bbe515cae0002472519b3e67661a7e89cab94695c8f4bcd66e61b9b9c946da8d524de3d69bd9d9d66b997e37 diff --git a/x448.c b/x448.c index d766e5c..c58335a 100644 --- a/x448.c +++ b/x448.c @@ -1,3 +1,40 @@ +/* + * x448.c: Hamburg's X448 key-exchange function + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Remove the test rig code: a replacement is in a separate source file. + * + * * Strip out the key-management definitions. + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * The X448 key-agreement algorithm @@ -27,7 +64,7 @@ /*----- Header files ------------------------------------------------------*/ -#include +#include "fake-mLib-bits.h" #include "montladder.h" #include "fgoldi.h" @@ -39,24 +76,6 @@ const octet x448_base[56] = { 5, 0, /* ... */ }; #define A0 39081 -/*----- Key fetching ------------------------------------------------------*/ - -const key_fetchdef x448_pubfetch[] = { - { "pub", offsetof(x448_pub, pub), KENC_BINARY, 0 }, - { 0, 0, 0, 0 } -}; - -static const key_fetchdef priv[] = { - { "priv", offsetof(x448_priv, priv), KENC_BINARY, 0 }, - { 0, 0, 0, 0 } -}; - -const key_fetchdef x448_privfetch[] = { - { "pub", offsetof(x448_priv, pub), KENC_BINARY, 0 }, - { "private", 0, KENC_STRUCT, priv }, - { 0, 0, 0, 0 } -}; - /*----- Main code ---------------------------------------------------------*/ /* --- @x448@ --- * diff --git a/x448.h b/x448.h index f1b0f2c..ae1672f 100644 --- a/x448.h +++ b/x448.h @@ -1,3 +1,38 @@ +/* + * x448.h: Hamburg's X448 key-exchange function + */ +/* + * This file is Free Software. It has been modified to as part of its + * incorporation into secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute this file and/or modify it under the terms of + * the permissive licence shown below. + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ +/* + * Imported from Catacomb, and modified for Secnet (2017-04-30): + * + * * Use `fake-mLib-bits.h' in place of the real . + * + * * Strip out the key-management definitions. + * + * The file's original comment headers are preserved below. + */ /* -*-c-*- * * The X448 key-agreement algorithm @@ -46,20 +81,7 @@ /*----- Header files ------------------------------------------------------*/ -#include - -#ifndef CATACOMB_KEY_H -# include "key.h" -#endif - -/*----- Key fetching ------------------------------------------------------*/ - -typedef struct x448_priv { key_bin priv, pub; } x448_priv; -typedef struct x448_pub { key_bin pub; } x448_pub; - -extern const key_fetchdef x448_pubfetch[], x448_privfetch[]; -#define X448_PUBFETCHSZ 3 -#define X448_PRIVFETCHSZ 6 +#include "fake-mLib-bits.h" /*----- Important constants -----------------------------------------------*/ diff --git a/xdh-test.c b/xdh-test.c new file mode 100644 index 0000000..016c8d2 --- /dev/null +++ b/xdh-test.c @@ -0,0 +1,367 @@ +/* + * xdh-test.c: test harness elliptic-curve Diffie--Hellman + * + * (The implementations originally came with different test arrangements, + * with complicated external dependencies. This file replicates the original + * tests, but without the dependencies.) + */ +/* + * This file is Free Software. It was originally written for secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * You may redistribute this file and/or modify it under the terms of + * the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later + * version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "secnet.h" + +#include "f25519.h" +#include "fgoldi.h" + +#include "x25519.h" +#include "x448.h" + +#define GLUE(x, y) GLUE_(x, y) +#define GLUE_(x, y) x##y +#define FIELDOP(op) GLUE(FIELD, _##op) + +#define f25519_FESZ 32u +#define fgoldi_FESZ 56u + +/* Define some global variables we shouldn't need. + * + * Annoyingly, `secnet.h' declares static pointers and initializes them to + * point to some external variables. At `-O0', GCC doesn't optimize these + * away, so there's a link-time dependency on these variables. Define them + * here, so that `f25519.c' and `f448.c' can find them. + * + * (Later GCC has `-Og', which optimizes without making debugging a + * nightmare, but I'm not running that version here. Note that `serpent.c' + * doesn't have this problem because it defines its own word load and store + * operations to cope with its endian weirdness, whereas the field arithmetic + * uses `unaligned.h' which manages to include `secnet.h'.) + */ +uint64_t now_global; +struct timeval tv_now_global; + +union reg { + long i; + unsigned long u; + uint8_t fe[FIELDOP(FESZ)]; +}; + +struct regty { + void (*parse)(union reg *r, char *p); + void (*dump)(FILE *fp, const union reg *r); + int (*eq)(const union reg *r, const union reg *rr); +}; + +struct regdef { + const char *name; + const struct regty *ty; + int r; +}; + +struct test { + const char *name; + void (*fn)(union reg *out, const union reg *in); + const struct regdef *regs; +}; + +static int lno; + +static void bail(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + fprintf(stderr, "unexpected error (line %d): ", lno); + vfprintf(stderr, msg, ap); + va_end(ap); + fputc('\n', stderr); + exit(3); +} + +static void parse_hex(uint8_t *b, size_t sz, char *p) +{ + size_t n = strlen(p); + unsigned i; + char bb[3]; + + if (n%2) bail("bad hex (odd number of nibbles)"); + else if (n/2 != sz) bail("bad hex (want %zu bytes, found %zu", sz, n/2); + while (sz) { + for (i = 0; i < 2; i++) { + if (!isxdigit((unsigned char)p[i])) + bail("bad hex digit `%c'", p[i]); + bb[i] = p[i]; + } + bb[2] = 0; + p += 2; + *b++ = strtoul(bb, 0, 16); sz--; + } +} + +static void dump_hex(FILE *fp, const uint8_t *b, size_t sz) + { while (sz--) fprintf(fp, "%02x", *b++); fputc('\n', fp); } + +static void parse_int(union reg *r, char *p) +{ + char *q; + + errno = 0; + r->i = strtol(p, &q, 0); + if (*q || errno) bail("bad integer `%s'", p); +} + +static void dump_int(FILE *fp, const union reg *r) + { fprintf(fp, "%ld\n", r->i); } + +static int eq_int(const union reg *r, const union reg *rr) + { return (r->i == rr->i); } + +static const struct regty regty_int = { parse_int, dump_int, eq_int }; + +static void parse_uint(union reg *r, char *p) +{ + char *q; + + errno = 0; + r->u = strtoul(p, &q, 0); + if (*q || errno) bail("bad integer `%s'", p); +} + +static void dump_uint(FILE *fp, const union reg *r) + { fprintf(fp, "%lu\n", r->u); } + +static int eq_uint(const union reg *r, const union reg *rr) + { return (r->u == rr->u); } + +static const struct regty regty_uint = { parse_uint, dump_uint, eq_uint }; + +static void parse_fe(union reg *r, char *p) + { parse_hex(r->fe, sizeof(r->fe), p); } + +static void dump_fe(FILE *fp, const union reg *r) + { dump_hex(fp, r->fe, sizeof(r->fe)); } + +static int eq_fe(const union reg *r, const union reg *rr) + { return (memcmp(r->fe, rr->fe, sizeof(r->fe)) == 0); } + +static const struct regty regty_fe = { parse_fe, dump_fe, eq_fe }; + +enum { + RZ, RXX = RZ, RYY, NROUT, + RX = NROUT, RY, RA = RY, RK = RY, RM, RN = RM, NREG +}; + +#define BINOP(op) \ + static void test_##op(union reg *out, const union reg *in) \ + { \ + FIELD x, y, z; \ + \ + FIELDOP(load)(&x, in[RX].fe); \ + FIELDOP(load)(&y, in[RY].fe); \ + FIELDOP(op)(&z, &x, &y); \ + FIELDOP(store)(out[RZ].fe, &z); \ + } + +#define UNOP(op) \ + static void test_##op(union reg *out, const union reg *in) \ + { \ + FIELD x, z; \ + \ + FIELDOP(load)(&x, in[RX].fe); \ + FIELDOP(op)(&z, &x); \ + FIELDOP(store)(out[RZ].fe, &z); \ + } + +BINOP(add) +BINOP(sub) +BINOP(mul) +UNOP(sqr) +UNOP(inv) + +static void test_mulconst(union reg *out, const union reg *in) +{ + FIELD x, z; + + FIELDOP(load)(&x, in[RX].fe); + FIELDOP(mulconst)(&z, &x, in[RA].i); + FIELDOP(store)(out[RZ].fe, &z); +} + +static void test_condswap(union reg *out, const union reg *in) +{ + FIELD x, y; + + FIELDOP(load)(&x, in[RX].fe); + FIELDOP(load)(&y, in[RY].fe); + FIELDOP(condswap)(&x, &y, in[RM].u); + FIELDOP(store)(out[RXX].fe, &x); + FIELDOP(store)(out[RYY].fe, &y); +} + +static void test_xdh(union reg *out, const union reg *in) + { XDH(out[RZ].fe, in[RK].fe, in[RX].fe); } + +static void test_xdhmct(union reg *out, const union reg *in) +{ + uint8_t b0[FIELDOP(FESZ)], b1[FIELDOP(FESZ)], *k = b0, *x = b1, *t; + unsigned long i, n; + + memcpy(b0, in[RK].fe, sizeof(b0)); + memcpy(b1, in[RX].fe, sizeof(b1)); + n = in[RM].u; + for (i = 0; i < n; i++) { + XDH(x, k, x); + t = x; x = k; k = t; + } + memcpy(out[RZ].fe, k, sizeof(b0)); +} + +#define REG_X { "x", ®ty_fe, RX } +#define REG_Y { "y", ®ty_fe, RY } +#define REG_A { "a", ®ty_int, RA } +#define REG_M { "m", ®ty_uint, RM } +#define REG_XX { "xx", ®ty_fe, RXX } +#define REG_YY { "yy", ®ty_fe, RYY } +#define REG_Z { "z", ®ty_fe, RZ } +#define REG_BIGX { "X", ®ty_fe, RX } +#define REG_BIGZ { "Z", ®ty_fe, RZ } +#define REG_K { "k", ®ty_fe, RK } +#define REG_N { "n", ®ty_uint, RN } +#define REGLIST_END { 0 } +static const struct regdef + unop_regs[] = { REG_X, REG_Z, REGLIST_END }, + binop_regs[] = { REG_X, REG_Y, REG_Z, REGLIST_END }, + mulconst_regs[] = { REG_X, REG_A, REG_Z, REGLIST_END }, + condswap_regs[] = { REG_X, REG_Y, REG_M, REG_XX, REG_YY, REGLIST_END }, + xdh_regs[] = { REG_K, REG_BIGX, REG_BIGZ, REGLIST_END }, + xdhmct_regs[] = { REG_K, REG_BIGX, REG_N, REG_BIGZ, REGLIST_END }; + +static const struct test tests[] = { + { "add", test_add, binop_regs }, + { "sub", test_sub, binop_regs }, + { "condswap", test_condswap, condswap_regs }, + { "mulconst", test_mulconst, mulconst_regs }, + { "mul", test_mul, binop_regs }, + { "sqr", test_sqr, unop_regs }, + { "inv", test_inv, unop_regs }, + { "xdh", test_xdh, xdh_regs }, + { "xdh-mct", test_xdhmct, xdhmct_regs }, + { 0 } +}; + +static int check(const struct test *test, unsigned iat, + union reg *out, const union reg *in) +{ + const struct regdef *rdef; + int ok = 1; + + if (!iat) return (0); + assert(test); + for (rdef = test->regs; rdef->name; rdef++) + if (!(iat & (1 << rdef->r))) + bail("register `%s' not set", rdef->name); + test->fn(out, in); + for (rdef = test->regs; rdef->name; rdef++) { + if (rdef->r >= NROUT) continue; + if (!rdef->ty->eq(&in[rdef->r], &out[rdef->r])) ok = 0; + } + if (ok) return (0); + + fprintf(stderr, "failed `%s'\n", test->name); + for (rdef = test->regs; rdef->name; rdef++) { + if (rdef->r >= NROUT) { + fprintf(stderr, "\tinput `%s' = ", rdef->name); + rdef->ty->dump(stderr, &in[rdef->r]); + } else { + fprintf(stderr, "\texpected `%s' = ", rdef->name); + rdef->ty->dump(stderr, &in[rdef->r]); + fprintf(stderr, "\tcomputed `%s' = ", rdef->name); + rdef->ty->dump(stderr, &out[rdef->r]); + } + } + return (-1); +} + +int main(void) +{ + char linebuf[256]; + char *p; + const char *q; + size_t n; + unsigned iat = 0, rbit; + const struct test *test = 0; + union reg in[NREG], out[NROUT]; + const struct regdef *rdef; + int rc = 0; + + lno = 0; + while (fgets(linebuf, sizeof(linebuf), stdin)) { + lno++; + n = strlen(linebuf); assert(n); + if (linebuf[n - 1] != '\n') bail("line too long"); + linebuf[n - 1] = 0; + p = linebuf; + while (isspace((unsigned char)*p)) p++; + if (*p == '#') continue; + if (!*p) { + if (check(test, iat, out, in)) rc = 2; + iat = 0; + continue; + } + q = p; + while (*p && !isspace((unsigned char)*p)) p++; + if (!*p) bail("missing argument"); + *p++ = 0; + while (isspace((unsigned char)*p)) p++; + if (strcmp(q, "test") == 0) { + if (check(test, iat, out, in)) rc = 2; + iat = 0; + for (test = tests; test->name; test++) + if (strcmp(p, test->name) == 0) goto found_test; + bail("unknown test `%s'", p); + found_test: + continue; + } + if (!test) bail("no test defined yet"); + for (rdef = test->regs; rdef->name; rdef++) + if (strcmp(q, rdef->name) == 0) goto found_reg; + bail("unknown register `%s'", q); + found_reg: + rbit = 1 << rdef->r; + if (iat & rbit) + bail("register `%s' already set", rdef->name); + rdef->ty->parse(&in[rdef->r], p); + iat |= rbit; + } + if (check(test, iat, out, in)) rc = 2; + return (rc); +}