diff options
author | Peter Eisentraut <peter@eisentraut.org> | 2021-11-05 13:59:42 +0100 |
---|---|---|
committer | Peter Eisentraut <peter@eisentraut.org> | 2021-11-05 14:06:59 +0100 |
commit | db7d1a7b0530e8cbd045744e1c75b0e63fb6916f (patch) | |
tree | a03045045b1bd83cabc6bd2994c156c93c5b65a7 | |
parent | a5b336b8b9e04a93e7c8526302504d2e5201eb80 (diff) | |
download | postgresql-db7d1a7b0530e8cbd045744e1c75b0e63fb6916f.tar.gz postgresql-db7d1a7b0530e8cbd045744e1c75b0e63fb6916f.zip |
pgcrypto: Remove non-OpenSSL support
pgcrypto had internal implementations of some encryption algorithms,
as an alternative to calling out to OpenSSL. These were rarely used,
since most production installations are built with OpenSSL. Moreover,
maintaining parallel code paths makes the code more complex and
difficult to maintain.
This patch removes these internal implementations. Now, pgcrypto is
only built if OpenSSL support is configured.
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/flat/0b42f1df-8cba-6a30-77d7-acc241cc88c1%40enterprisedb.com
-rw-r--r-- | contrib/Makefile | 5 | ||||
-rw-r--r-- | contrib/pgcrypto/Makefile | 73 | ||||
-rw-r--r-- | contrib/pgcrypto/blf.c | 499 | ||||
-rw-r--r-- | contrib/pgcrypto/blf.h | 46 | ||||
-rw-r--r-- | contrib/pgcrypto/imath.c | 3588 | ||||
-rw-r--r-- | contrib/pgcrypto/imath.h | 445 | ||||
-rw-r--r-- | contrib/pgcrypto/internal-sha2.c | 206 | ||||
-rw-r--r-- | contrib/pgcrypto/internal.c | 585 | ||||
-rw-r--r-- | contrib/pgcrypto/pgp-mpi-internal.c | 304 | ||||
-rw-r--r-- | contrib/pgcrypto/rijndael.c | 677 | ||||
-rw-r--r-- | contrib/pgcrypto/rijndael.h | 59 | ||||
-rw-r--r-- | contrib/pgcrypto/rijndael.tbl | 1138 | ||||
-rw-r--r-- | doc/src/sgml/pgcrypto.sgml | 113 | ||||
-rw-r--r-- | src/tools/msvc/Mkvcbuild.pm | 39 | ||||
-rw-r--r-- | src/tools/msvc/vcregress.pl | 7 |
15 files changed, 42 insertions, 7742 deletions
diff --git a/contrib/Makefile b/contrib/Makefile index f27e458482e..87bf87ab90f 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -36,7 +36,6 @@ SUBDIRS = \ pg_stat_statements \ pg_surgery \ pg_trgm \ - pgcrypto \ pgrowlocks \ pgstattuple \ pg_visibility \ @@ -52,9 +51,9 @@ SUBDIRS = \ vacuumlo ifeq ($(with_ssl),openssl) -SUBDIRS += sslinfo +SUBDIRS += pgcrypto sslinfo else -ALWAYS_SUBDIRS += sslinfo +ALWAYS_SUBDIRS += pgcrypto sslinfo endif ifneq ($(with_uuid),no) diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile index c0b4f1fcf68..7fb59f51b72 100644 --- a/contrib/pgcrypto/Makefile +++ b/contrib/pgcrypto/Makefile @@ -1,48 +1,38 @@ # contrib/pgcrypto/Makefile -INT_SRCS = internal.c internal-sha2.c blf.c rijndael.c \ - pgp-mpi-internal.c imath.c -INT_TESTS = sha2 - -OSSL_SRCS = openssl.c pgp-mpi-openssl.c -OSSL_TESTS = sha2 des 3des cast5 - ZLIB_TST = pgp-compression ZLIB_OFF_TST = pgp-zlib-DISABLED -CF_SRCS = $(if $(subst openssl,,$(with_ssl)), $(INT_SRCS), $(OSSL_SRCS)) -CF_TESTS = $(if $(subst openssl,,$(with_ssl)), $(INT_TESTS), $(OSSL_TESTS)) CF_PGP_TESTS = $(if $(subst no,,$(with_zlib)), $(ZLIB_TST), $(ZLIB_OFF_TST)) -SRCS = \ - $(CF_SRCS) \ - crypt-blowfish.c \ - crypt-des.c \ - crypt-gensalt.c \ - crypt-md5.c \ - mbuf.c \ - pgcrypto.c \ - pgp-armor.c \ - pgp-cfb.c \ - pgp-compress.c \ - pgp-decrypt.c \ - pgp-encrypt.c \ - pgp-info.c \ - pgp-mpi.c \ - pgp-pgsql.c \ - pgp-pubdec.c \ - pgp-pubenc.c \ - pgp-pubkey.c \ - pgp-s2k.c \ - pgp.c \ - px-crypt.c \ - px-hmac.c \ - px.c +OBJS = \ + $(WIN32RES) \ + crypt-blowfish.o \ + crypt-des.o \ + crypt-gensalt.o \ + crypt-md5.o \ + mbuf.o \ + openssl.o \ + pgcrypto.o \ + pgp-armor.o \ + pgp-cfb.o \ + pgp-compress.o \ + pgp-decrypt.o \ + pgp-encrypt.o \ + pgp-info.o \ + pgp-mpi.o \ + pgp-mpi-openssl.o \ + pgp-pgsql.o \ + pgp-pubdec.o \ + pgp-pubenc.o \ + pgp-pubkey.o \ + pgp-s2k.o \ + pgp.o \ + px-crypt.o \ + px-hmac.o \ + px.o MODULE_big = pgcrypto -OBJS = \ - $(SRCS:.c=.o) \ - $(WIN32RES) EXTENSION = pgcrypto DATA = pgcrypto--1.3.sql pgcrypto--1.2--1.3.sql pgcrypto--1.1--1.2.sql \ @@ -50,7 +40,7 @@ DATA = pgcrypto--1.3.sql pgcrypto--1.2--1.3.sql pgcrypto--1.1--1.2.sql \ PGFILEDESC = "pgcrypto - cryptographic functions" REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \ - $(CF_TESTS) \ + sha2 des 3des cast5 \ crypt-des crypt-md5 crypt-blowfish crypt-xdes \ pgp-armor pgp-decrypt pgp-encrypt $(CF_PGP_TESTS) \ pgp-pubkey-decrypt pgp-pubkey-encrypt pgp-info @@ -77,12 +67,3 @@ SHLIB_LINK += $(filter -leay32, $(LIBS)) # those must be at the end SHLIB_LINK += -lws2_32 endif - -# Upstream uses a larger subset of C99. -imath.o: CFLAGS+=$(PERMIT_DECLARATION_AFTER_STATEMENT) - -rijndael.o: rijndael.tbl - -rijndael.tbl: - $(CC) $(CPPFLAGS) $(CFLAGS) -DPRINT_TABS rijndael.c -o gen-rtab - ./gen-rtab > rijndael.tbl diff --git a/contrib/pgcrypto/blf.c b/contrib/pgcrypto/blf.c deleted file mode 100644 index f8a2c63c9fd..00000000000 --- a/contrib/pgcrypto/blf.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Butchered version of sshblowf.c from putty-0.59. - * - * contrib/pgcrypto/blf.c - */ - -/* - * PuTTY is copyright 1997-2007 Simon Tatham. - * - * Portions copyright Robert de Bath, Joris van Rantwijk, Delian - * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, - * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus - * Kuhn, and CORE SDI S.A. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Blowfish implementation for PuTTY. - * - * Coded from scratch from the algorithm description. - */ - -#include "postgres.h" -#include "blf.h" - -#define GET_32BIT_MSB_FIRST(p) ( \ - ((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3]) ) - -#define PUT_32BIT_MSB_FIRST(p, v) do { \ - (p)[0] = v >> 24; \ - (p)[1] = v >> 16; \ - (p)[2] = v >> 8; \ - (p)[3] = v; \ -} while (0) - -/* - * The Blowfish init data: hex digits of the fractional part of pi. - * (ie pi as a hex fraction is 3.243F6A8885A308D3...) - */ -static const uint32 parray[] = { - 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, - 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, - 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B, -}; - -static const uint32 sbox0[] = { - 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, - 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, - 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, - 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, - 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, - 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, - 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, - 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, - 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, - 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, - 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, - 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, - 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, - 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, - 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, - 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, - 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, - 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, - 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, - 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, - 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, - 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, - 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, - 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, - 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, - 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, - 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8, - 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, - 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, - 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, - 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, - 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, - 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, - 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, - 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705, - 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, - 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, - 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, - 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, - 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, - 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, - 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, - 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A, -}; - -static const uint32 sbox1[] = { - 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, - 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, - 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, - 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, - 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, - 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, - 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, - 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, - 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, - 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, - 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, - 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, - 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, - 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, - 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, - 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, - 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, - 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, - 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, - 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, - 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, - 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, - 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, - 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, - 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, - 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, - 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, - 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, - 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, - 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, - 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, - 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, - 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, - 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, - 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, - 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, - 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, - 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, - 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, - 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, - 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, - 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, - 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7, -}; - -static const uint32 sbox2[] = { - 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, - 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, - 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF, - 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, - 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, - 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, - 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, - 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, - 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, - 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, - 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58, - 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, - 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, - 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, - 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, - 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, - 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, - 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, - 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, - 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, - 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, - 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, - 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, - 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, - 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, - 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, - 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086, - 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, - 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, - 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, - 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, - 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, - 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, - 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, - 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE, - 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, - 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, - 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, - 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, - 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, - 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, - 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, - 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0, -}; - -static const uint32 sbox3[] = { - 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, - 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, - 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, - 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, - 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, - 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, - 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, - 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, - 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, - 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, - 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, - 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, - 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, - 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, - 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, - 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, - 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, - 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, - 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, - 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, - 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, - 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, - 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, - 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, - 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, - 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, - 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, - 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, - 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, - 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, - 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, - 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, - 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, - 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, - 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, - 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, - 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, - 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, - 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, - 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, - 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, - 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, - 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6, -}; - -#define Fprime(a,b,c,d) ( ( (S0[a] + S1[b]) ^ S2[c] ) + S3[d] ) -#define F(x) Fprime( ((x>>24)&0xFF), ((x>>16)&0xFF), ((x>>8)&0xFF), (x&0xFF) ) -#define ROUND(n) ( xL ^= P[n], t = xL, xL = F(xL) ^ xR, xR = t ) - -static void -blowfish_encrypt(uint32 xL, uint32 xR, uint32 *output, - BlowfishContext *ctx) -{ - uint32 *S0 = ctx->S0; - uint32 *S1 = ctx->S1; - uint32 *S2 = ctx->S2; - uint32 *S3 = ctx->S3; - uint32 *P = ctx->P; - uint32 t; - - ROUND(0); - ROUND(1); - ROUND(2); - ROUND(3); - ROUND(4); - ROUND(5); - ROUND(6); - ROUND(7); - ROUND(8); - ROUND(9); - ROUND(10); - ROUND(11); - ROUND(12); - ROUND(13); - ROUND(14); - ROUND(15); - xL ^= P[16]; - xR ^= P[17]; - - output[0] = xR; - output[1] = xL; -} - -static void -blowfish_decrypt(uint32 xL, uint32 xR, uint32 *output, - BlowfishContext *ctx) -{ - uint32 *S0 = ctx->S0; - uint32 *S1 = ctx->S1; - uint32 *S2 = ctx->S2; - uint32 *S3 = ctx->S3; - uint32 *P = ctx->P; - uint32 t; - - ROUND(17); - ROUND(16); - ROUND(15); - ROUND(14); - ROUND(13); - ROUND(12); - ROUND(11); - ROUND(10); - ROUND(9); - ROUND(8); - ROUND(7); - ROUND(6); - ROUND(5); - ROUND(4); - ROUND(3); - ROUND(2); - xL ^= P[1]; - xR ^= P[0]; - - output[0] = xR; - output[1] = xL; -} - -void -blowfish_encrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx) -{ - uint32 xL, - xR, - out[2], - iv0, - iv1; - - Assert((len & 7) == 0); - - iv0 = ctx->iv0; - iv1 = ctx->iv1; - - while (len > 0) - { - xL = GET_32BIT_MSB_FIRST(blk); - xR = GET_32BIT_MSB_FIRST(blk + 4); - iv0 ^= xL; - iv1 ^= xR; - blowfish_encrypt(iv0, iv1, out, ctx); - iv0 = out[0]; - iv1 = out[1]; - PUT_32BIT_MSB_FIRST(blk, iv0); - PUT_32BIT_MSB_FIRST(blk + 4, iv1); - blk += 8; - len -= 8; - } - - ctx->iv0 = iv0; - ctx->iv1 = iv1; -} - -void -blowfish_decrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx) -{ - uint32 xL, - xR, - out[2], - iv0, - iv1; - - Assert((len & 7) == 0); - - iv0 = ctx->iv0; - iv1 = ctx->iv1; - - while (len > 0) - { - xL = GET_32BIT_MSB_FIRST(blk); - xR = GET_32BIT_MSB_FIRST(blk + 4); - blowfish_decrypt(xL, xR, out, ctx); - iv0 ^= out[0]; - iv1 ^= out[1]; - PUT_32BIT_MSB_FIRST(blk, iv0); - PUT_32BIT_MSB_FIRST(blk + 4, iv1); - iv0 = xL; - iv1 = xR; - blk += 8; - len -= 8; - } - - ctx->iv0 = iv0; - ctx->iv1 = iv1; -} - -void -blowfish_encrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx) -{ - uint32 xL, - xR, - out[2]; - - Assert((len & 7) == 0); - - while (len > 0) - { - xL = GET_32BIT_MSB_FIRST(blk); - xR = GET_32BIT_MSB_FIRST(blk + 4); - blowfish_encrypt(xL, xR, out, ctx); - PUT_32BIT_MSB_FIRST(blk, out[0]); - PUT_32BIT_MSB_FIRST(blk + 4, out[1]); - blk += 8; - len -= 8; - } -} - -void -blowfish_decrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx) -{ - uint32 xL, - xR, - out[2]; - - Assert((len & 7) == 0); - - while (len > 0) - { - xL = GET_32BIT_MSB_FIRST(blk); - xR = GET_32BIT_MSB_FIRST(blk + 4); - blowfish_decrypt(xL, xR, out, ctx); - PUT_32BIT_MSB_FIRST(blk, out[0]); - PUT_32BIT_MSB_FIRST(blk + 4, out[1]); - blk += 8; - len -= 8; - } -} - -void -blowfish_setkey(BlowfishContext *ctx, - const uint8 *key, short keybytes) -{ - uint32 *S0 = ctx->S0; - uint32 *S1 = ctx->S1; - uint32 *S2 = ctx->S2; - uint32 *S3 = ctx->S3; - uint32 *P = ctx->P; - uint32 str[2]; - int i; - - Assert(keybytes > 0 && keybytes <= (448 / 8)); - - for (i = 0; i < 18; i++) - { - P[i] = parray[i]; - P[i] ^= ((uint32) key[(i * 4 + 0) % keybytes]) << 24; - P[i] ^= ((uint32) key[(i * 4 + 1) % keybytes]) << 16; - P[i] ^= ((uint32) key[(i * 4 + 2) % keybytes]) << 8; - P[i] ^= ((uint32) key[(i * 4 + 3) % keybytes]); - } - - for (i = 0; i < 256; i++) - { - S0[i] = sbox0[i]; - S1[i] = sbox1[i]; - S2[i] = sbox2[i]; - S3[i] = sbox3[i]; - } - - str[0] = str[1] = 0; - - for (i = 0; i < 18; i += 2) - { - blowfish_encrypt(str[0], str[1], str, ctx); - P[i] = str[0]; - P[i + 1] = str[1]; - } - - for (i = 0; i < 256; i += 2) - { - blowfish_encrypt(str[0], str[1], str, ctx); - S0[i] = str[0]; - S0[i + 1] = str[1]; - } - for (i = 0; i < 256; i += 2) - { - blowfish_encrypt(str[0], str[1], str, ctx); - S1[i] = str[0]; - S1[i + 1] = str[1]; - } - for (i = 0; i < 256; i += 2) - { - blowfish_encrypt(str[0], str[1], str, ctx); - S2[i] = str[0]; - S2[i + 1] = str[1]; - } - for (i = 0; i < 256; i += 2) - { - blowfish_encrypt(str[0], str[1], str, ctx); - S3[i] = str[0]; - S3[i + 1] = str[1]; - } -} - -void -blowfish_setiv(BlowfishContext *ctx, const uint8 *iv) -{ - ctx->iv0 = GET_32BIT_MSB_FIRST(iv); - ctx->iv1 = GET_32BIT_MSB_FIRST(iv + 4); -} diff --git a/contrib/pgcrypto/blf.h b/contrib/pgcrypto/blf.h deleted file mode 100644 index 84aba37ba86..00000000000 --- a/contrib/pgcrypto/blf.h +++ /dev/null @@ -1,46 +0,0 @@ -/* contrib/pgcrypto/blf.h */ -/* - * PuTTY is copyright 1997-2007 Simon Tatham. - * - * Portions copyright Robert de Bath, Joris van Rantwijk, Delian - * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, - * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus - * Kuhn, and CORE SDI S.A. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -typedef struct -{ - uint32 S0[256], - S1[256], - S2[256], - S3[256], - P[18]; - uint32 iv0, - iv1; /* for CBC mode */ -} BlowfishContext; - -void blowfish_setkey(BlowfishContext *ctx, const uint8 *key, short keybytes); -void blowfish_setiv(BlowfishContext *ctx, const uint8 *iv); -void blowfish_encrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx); -void blowfish_decrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx); -void blowfish_encrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx); -void blowfish_decrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx); diff --git a/contrib/pgcrypto/imath.c b/contrib/pgcrypto/imath.c deleted file mode 100644 index 0bfa080fa55..00000000000 --- a/contrib/pgcrypto/imath.c +++ /dev/null @@ -1,3588 +0,0 @@ -/*------------------------------------------------------------------------- - * - * imath.c - * - * Last synchronized from https://github.com/creachadair/imath/tree/v1.29, - * using the following procedure: - * - * 1. Download imath.c and imath.h of the last synchronized version. Remove - * "#ifdef __cplusplus" blocks, which upset pgindent. Run pgindent on the - * two files. Filter the two files through "unexpand -t4 --first-only". - * Diff the result against the PostgreSQL versions. As of the last - * synchronization, changes were as follows: - * - * - replace malloc(), realloc() and free() with px_ versions - * - redirect assert() to Assert() - * - #undef MIN, #undef MAX before defining them - * - remove includes covered by c.h - * - rename DEBUG to IMATH_DEBUG - * - replace stdint.h usage with c.h equivalents - * - suppress MSVC warning 4146 - * - add required PG_USED_FOR_ASSERTS_ONLY - * - * 2. Download a newer imath.c and imath.h. Transform them like in step 1. - * Apply to these files the diff you saved in step 1. Look for new lines - * requiring the same kind of change, such as new malloc() calls. - * - * 3. Configure PostgreSQL using --without-openssl. Run "make -C - * contrib/pgcrypto check". - * - * 4. Update this header comment. - * - * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group - * - * IDENTIFICATION - * contrib/pgcrypto/imath.c - * - * Upstream copyright terms follow. - *------------------------------------------------------------------------- - */ - -/* - Name: imath.c - Purpose: Arbitrary precision integer arithmetic routines. - Author: M. J. Fromberger - - Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -#include "postgres.h" - -#include "imath.h" -#include "px.h" - -#undef assert -#define assert(TEST) Assert(TEST) - -const mp_result MP_OK = 0; /* no error, all is well */ -const mp_result MP_FALSE = 0; /* boolean false */ -const mp_result MP_TRUE = -1; /* boolean true */ -const mp_result MP_MEMORY = -2; /* out of memory */ -const mp_result MP_RANGE = -3; /* argument out of range */ -const mp_result MP_UNDEF = -4; /* result undefined */ -const mp_result MP_TRUNC = -5; /* output truncated */ -const mp_result MP_BADARG = -6; /* invalid null argument */ -const mp_result MP_MINERR = -6; - -const mp_sign MP_NEG = 1; /* value is strictly negative */ -const mp_sign MP_ZPOS = 0; /* value is non-negative */ - -static const char *s_unknown_err = "unknown result code"; -static const char *s_error_msg[] = {"error code 0", "boolean true", - "out of memory", "argument out of range", - "result undefined", "output truncated", -"invalid argument", NULL}; - -/* The ith entry of this table gives the value of log_i(2). - - An integer value n requires ceil(log_i(n)) digits to be represented - in base i. Since it is easy to compute lg(n), by counting bits, we - can compute log_i(n) = lg(n) * log_i(2). - - The use of this table eliminates a dependency upon linkage against - the standard math libraries. - - If MP_MAX_RADIX is increased, this table should be expanded too. - */ -static const double s_log2[] = { - 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* (D)(D) 2 3 */ - 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ - 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ - 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ - 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ - 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */ - 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ - 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ - 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ - 0.193426404, /* 36 */ -}; - -/* Return the number of digits needed to represent a static value */ -#define MP_VALUE_DIGITS(V) \ - ((sizeof(V) + (sizeof(mp_digit) - 1)) / sizeof(mp_digit)) - -/* Round precision P to nearest word boundary */ -static inline mp_size -s_round_prec(mp_size P) -{ - return 2 * ((P + 1) / 2); -} - -/* Set array P of S digits to zero */ -static inline void -ZERO(mp_digit *P, mp_size S) -{ - mp_size i__ = S * sizeof(mp_digit); - mp_digit *p__ = P; - - memset(p__, 0, i__); -} - -/* Copy S digits from array P to array Q */ -static inline void -COPY(mp_digit *P, mp_digit *Q, mp_size S) -{ - mp_size i__ = S * sizeof(mp_digit); - mp_digit *p__ = P; - mp_digit *q__ = Q; - - memcpy(q__, p__, i__); -} - -/* Reverse N elements of unsigned char in A. */ -static inline void -REV(unsigned char *A, int N) -{ - unsigned char *u_ = A; - unsigned char *v_ = u_ + N - 1; - - while (u_ < v_) - { - unsigned char xch = *u_; - - *u_++ = *v_; - *v_-- = xch; - } -} - -/* Strip leading zeroes from z_ in-place. */ -static inline void -CLAMP(mp_int z_) -{ - mp_size uz_ = MP_USED(z_); - mp_digit *dz_ = MP_DIGITS(z_) + uz_ - 1; - - while (uz_ > 1 && (*dz_-- == 0)) - --uz_; - z_->used = uz_; -} - -/* Select min/max. */ -#undef MIN -#undef MAX -static inline int -MIN(int A, int B) -{ - return (B < A ? B : A); -} -static inline mp_size -MAX(mp_size A, mp_size B) -{ - return (B > A ? B : A); -} - -/* Exchange lvalues A and B of type T, e.g. - SWAP(int, x, y) where x and y are variables of type int. */ -#define SWAP(T, A, B) \ - do { \ - T t_ = (A); \ - A = (B); \ - B = t_; \ - } while (0) - -/* Declare a block of N temporary mpz_t values. - These values are initialized to zero. - You must add CLEANUP_TEMP() at the end of the function. - Use TEMP(i) to access a pointer to the ith value. - */ -#define DECLARE_TEMP(N) \ - struct { \ - mpz_t value[(N)]; \ - int len; \ - mp_result err; \ - } temp_ = { \ - .len = (N), \ - .err = MP_OK, \ - }; \ - do { \ - for (int i = 0; i < temp_.len; i++) { \ - mp_int_init(TEMP(i)); \ - } \ - } while (0) - -/* Clear all allocated temp values. */ -#define CLEANUP_TEMP() \ - CLEANUP: \ - do { \ - for (int i = 0; i < temp_.len; i++) { \ - mp_int_clear(TEMP(i)); \ - } \ - if (temp_.err != MP_OK) { \ - return temp_.err; \ - } \ - } while (0) - -/* A pointer to the kth temp value. */ -#define TEMP(K) (temp_.value + (K)) - -/* Evaluate E, an expression of type mp_result expected to return MP_OK. If - the value is not MP_OK, the error is cached and control resumes at the - cleanup handler, which returns it. -*/ -#define REQUIRE(E) \ - do { \ - temp_.err = (E); \ - if (temp_.err != MP_OK) goto CLEANUP; \ - } while (0) - -/* Compare value to zero. */ -static inline int -CMPZ(mp_int Z) -{ - if (Z->used == 1 && Z->digits[0] == 0) - return 0; - return (Z->sign == MP_NEG) ? -1 : 1; -} - -static inline mp_word -UPPER_HALF(mp_word W) -{ - return (W >> MP_DIGIT_BIT); -} -static inline mp_digit -LOWER_HALF(mp_word W) -{ - return (mp_digit) (W); -} - -/* Report whether the highest-order bit of W is 1. */ -static inline bool -HIGH_BIT_SET(mp_word W) -{ - return (W >> (MP_WORD_BIT - 1)) != 0; -} - -/* Report whether adding W + V will carry out. */ -static inline bool -ADD_WILL_OVERFLOW(mp_word W, mp_word V) -{ - return ((MP_WORD_MAX - V) < W); -} - -/* Default number of digits allocated to a new mp_int */ -static mp_size default_precision = 8; - -void -mp_int_default_precision(mp_size size) -{ - assert(size > 0); - default_precision = size; -} - -/* Minimum number of digits to invoke recursive multiply */ -static mp_size multiply_threshold = 32; - -void -mp_int_multiply_threshold(mp_size thresh) -{ - assert(thresh >= sizeof(mp_word)); - multiply_threshold = thresh; -} - -/* Allocate a buffer of (at least) num digits, or return - NULL if that couldn't be done. */ -static mp_digit *s_alloc(mp_size num); - -/* Release a buffer of digits allocated by s_alloc(). */ -static void s_free(void *ptr); - -/* Insure that z has at least min digits allocated, resizing if - necessary. Returns true if successful, false if out of memory. */ -static bool s_pad(mp_int z, mp_size min); - -/* Ensure Z has at least N digits allocated. */ -static inline mp_result -GROW(mp_int Z, mp_size N) -{ - return s_pad(Z, N) ? MP_OK : MP_MEMORY; -} - -/* Fill in a "fake" mp_int on the stack with a given value */ -static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]); -static void s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]); - -/* Compare two runs of digits of given length, returns <0, 0, >0 */ -static int s_cdig(mp_digit *da, mp_digit *db, mp_size len); - -/* Pack the unsigned digits of v into array t */ -static int s_uvpack(mp_usmall v, mp_digit t[]); - -/* Compare magnitudes of a and b, returns <0, 0, >0 */ -static int s_ucmp(mp_int a, mp_int b); - -/* Compare magnitudes of a and v, returns <0, 0, >0 */ -static int s_vcmp(mp_int a, mp_small v); -static int s_uvcmp(mp_int a, mp_usmall uv); - -/* Unsigned magnitude addition; assumes dc is big enough. - Carry out is returned (no memory allocated). */ -static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, - mp_size size_b); - -/* Unsigned magnitude subtraction. Assumes dc is big enough. */ -static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, - mp_size size_b); - -/* Unsigned recursive multiplication. Assumes dc is big enough. */ -static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, - mp_size size_b); - -/* Unsigned magnitude multiplication. Assumes dc is big enough. */ -static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, - mp_size size_b); - -/* Unsigned recursive squaring. Assumes dc is big enough. */ -static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a); - -/* Unsigned magnitude squaring. Assumes dc is big enough. */ -static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a); - -/* Single digit addition. Assumes a is big enough. */ -static void s_dadd(mp_int a, mp_digit b); - -/* Single digit multiplication. Assumes a is big enough. */ -static void s_dmul(mp_int a, mp_digit b); - -/* Single digit multiplication on buffers; assumes dc is big enough. */ -static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a); - -/* Single digit division. Replaces a with the quotient, - returns the remainder. */ -static mp_digit s_ddiv(mp_int a, mp_digit b); - -/* Quick division by a power of 2, replaces z (no allocation) */ -static void s_qdiv(mp_int z, mp_size p2); - -/* Quick remainder by a power of 2, replaces z (no allocation) */ -static void s_qmod(mp_int z, mp_size p2); - -/* Quick multiplication by a power of 2, replaces z. - Allocates if necessary; returns false in case this fails. */ -static int s_qmul(mp_int z, mp_size p2); - -/* Quick subtraction from a power of 2, replaces z. - Allocates if necessary; returns false in case this fails. */ -static int s_qsub(mp_int z, mp_size p2); - -/* Return maximum k such that 2^k divides z. */ -static int s_dp2k(mp_int z); - -/* Return k >= 0 such that z = 2^k, or -1 if there is no such k. */ -static int s_isp2(mp_int z); - -/* Set z to 2^k. May allocate; returns false in case this fails. */ -static int s_2expt(mp_int z, mp_small k); - -/* Normalize a and b for division, returns normalization constant */ -static int s_norm(mp_int a, mp_int b); - -/* Compute constant mu for Barrett reduction, given modulus m, result - replaces z, m is untouched. */ -static mp_result s_brmu(mp_int z, mp_int m); - -/* Reduce a modulo m, using Barrett's algorithm. */ -static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2); - -/* Modular exponentiation, using Barrett reduction */ -static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); - -/* Unsigned magnitude division. Assumes |a| > |b|. Allocates temporaries; - overwrites a with quotient, b with remainder. */ -static mp_result s_udiv_knuth(mp_int a, mp_int b); - -/* Compute the number of digits in radix r required to represent the given - value. Does not account for sign flags, terminators, etc. */ -static int s_outlen(mp_int z, mp_size r); - -/* Guess how many digits of precision will be needed to represent a radix r - value of the specified number of digits. Returns a value guaranteed to be - no smaller than the actual number required. */ -static mp_size s_inlen(int len, mp_size r); - -/* Convert a character to a digit value in radix r, or - -1 if out of range */ -static int s_ch2val(char c, int r); - -/* Convert a digit value to a character */ -static char s_val2ch(int v, int caps); - -/* Take 2's complement of a buffer in place */ -static void s_2comp(unsigned char *buf, int len); - -/* Convert a value to binary, ignoring sign. On input, *limpos is the bound on - how many bytes should be written to buf; on output, *limpos is set to the - number of bytes actually written. */ -static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad); - -/* Multiply X by Y into Z, ignoring signs. Requires that Z have enough storage - preallocated to hold the result. */ -static inline void -UMUL(mp_int X, mp_int Y, mp_int Z) -{ - mp_size ua_ = MP_USED(X); - mp_size ub_ = MP_USED(Y); - mp_size o_ = ua_ + ub_; - - ZERO(MP_DIGITS(Z), o_); - (void) s_kmul(MP_DIGITS(X), MP_DIGITS(Y), MP_DIGITS(Z), ua_, ub_); - Z->used = o_; - CLAMP(Z); -} - -/* Square X into Z. Requires that Z have enough storage to hold the result. */ -static inline void -USQR(mp_int X, mp_int Z) -{ - mp_size ua_ = MP_USED(X); - mp_size o_ = ua_ + ua_; - - ZERO(MP_DIGITS(Z), o_); - (void) s_ksqr(MP_DIGITS(X), MP_DIGITS(Z), ua_); - Z->used = o_; - CLAMP(Z); -} - -mp_result -mp_int_init(mp_int z) -{ - if (z == NULL) - return MP_BADARG; - - z->single = 0; - z->digits = &(z->single); - z->alloc = 1; - z->used = 1; - z->sign = MP_ZPOS; - - return MP_OK; -} - -mp_int -mp_int_alloc(void) -{ - mp_int out = palloc(sizeof(mpz_t)); - - if (out != NULL) - mp_int_init(out); - - return out; -} - -mp_result -mp_int_init_size(mp_int z, mp_size prec) -{ - assert(z != NULL); - - if (prec == 0) - { - prec = default_precision; - } - else if (prec == 1) - { - return mp_int_init(z); - } - else - { - prec = s_round_prec(prec); - } - - z->digits = s_alloc(prec); - if (MP_DIGITS(z) == NULL) - return MP_MEMORY; - - z->digits[0] = 0; - z->used = 1; - z->alloc = prec; - z->sign = MP_ZPOS; - - return MP_OK; -} - -mp_result -mp_int_init_copy(mp_int z, mp_int old) -{ - assert(z != NULL && old != NULL); - - mp_size uold = MP_USED(old); - - if (uold == 1) - { - mp_int_init(z); - } - else - { - mp_size target = MAX(uold, default_precision); - mp_result res = mp_int_init_size(z, target); - - if (res != MP_OK) - return res; - } - - z->used = uold; - z->sign = old->sign; - COPY(MP_DIGITS(old), MP_DIGITS(z), uold); - - return MP_OK; -} - -mp_result -mp_int_init_value(mp_int z, mp_small value) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - - s_fake(&vtmp, value, vbuf); - return mp_int_init_copy(z, &vtmp); -} - -mp_result -mp_int_init_uvalue(mp_int z, mp_usmall uvalue) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(uvalue)]; - - s_ufake(&vtmp, uvalue, vbuf); - return mp_int_init_copy(z, &vtmp); -} - -mp_result -mp_int_set_value(mp_int z, mp_small value) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - - s_fake(&vtmp, value, vbuf); - return mp_int_copy(&vtmp, z); -} - -mp_result -mp_int_set_uvalue(mp_int z, mp_usmall uvalue) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(uvalue)]; - - s_ufake(&vtmp, uvalue, vbuf); - return mp_int_copy(&vtmp, z); -} - -void -mp_int_clear(mp_int z) -{ - if (z == NULL) - return; - - if (MP_DIGITS(z) != NULL) - { - if (MP_DIGITS(z) != &(z->single)) - s_free(MP_DIGITS(z)); - - z->digits = NULL; - } -} - -void -mp_int_free(mp_int z) -{ - assert(z != NULL); - - mp_int_clear(z); - pfree(z); /* note: NOT s_free() */ -} - -mp_result -mp_int_copy(mp_int a, mp_int c) -{ - assert(a != NULL && c != NULL); - - if (a != c) - { - mp_size ua = MP_USED(a); - mp_digit *da, - *dc; - - if (!s_pad(c, ua)) - return MP_MEMORY; - - da = MP_DIGITS(a); - dc = MP_DIGITS(c); - COPY(da, dc, ua); - - c->used = ua; - c->sign = a->sign; - } - - return MP_OK; -} - -void -mp_int_swap(mp_int a, mp_int c) -{ - if (a != c) - { - mpz_t tmp = *a; - - *a = *c; - *c = tmp; - - if (MP_DIGITS(a) == &(c->single)) - a->digits = &(a->single); - if (MP_DIGITS(c) == &(a->single)) - c->digits = &(c->single); - } -} - -void -mp_int_zero(mp_int z) -{ - assert(z != NULL); - - z->digits[0] = 0; - z->used = 1; - z->sign = MP_ZPOS; -} - -mp_result -mp_int_abs(mp_int a, mp_int c) -{ - assert(a != NULL && c != NULL); - - mp_result res; - - if ((res = mp_int_copy(a, c)) != MP_OK) - return res; - - c->sign = MP_ZPOS; - return MP_OK; -} - -mp_result -mp_int_neg(mp_int a, mp_int c) -{ - assert(a != NULL && c != NULL); - - mp_result res; - - if ((res = mp_int_copy(a, c)) != MP_OK) - return res; - - if (CMPZ(c) != 0) - c->sign = 1 - MP_SIGN(a); - - return MP_OK; -} - -mp_result -mp_int_add(mp_int a, mp_int b, mp_int c) -{ - assert(a != NULL && b != NULL && c != NULL); - - mp_size ua = MP_USED(a); - mp_size ub = MP_USED(b); - mp_size max = MAX(ua, ub); - - if (MP_SIGN(a) == MP_SIGN(b)) - { - /* Same sign -- add magnitudes, preserve sign of addends */ - if (!s_pad(c, max)) - return MP_MEMORY; - - mp_digit carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); - mp_size uc = max; - - if (carry) - { - if (!s_pad(c, max + 1)) - return MP_MEMORY; - - c->digits[max] = carry; - ++uc; - } - - c->used = uc; - c->sign = a->sign; - - } - else - { - /* Different signs -- subtract magnitudes, preserve sign of greater */ - int cmp = s_ucmp(a, b); /* magnitude comparision, sign ignored */ - - /* - * Set x to max(a, b), y to min(a, b) to simplify later code. A - * special case yields zero for equal magnitudes. - */ - mp_int x, - y; - - if (cmp == 0) - { - mp_int_zero(c); - return MP_OK; - } - else if (cmp < 0) - { - x = b; - y = a; - } - else - { - x = a; - y = b; - } - - if (!s_pad(c, MP_USED(x))) - return MP_MEMORY; - - /* Subtract smaller from larger */ - s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); - c->used = x->used; - CLAMP(c); - - /* Give result the sign of the larger */ - c->sign = x->sign; - } - - return MP_OK; -} - -mp_result -mp_int_add_value(mp_int a, mp_small value, mp_int c) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - - s_fake(&vtmp, value, vbuf); - - return mp_int_add(a, &vtmp, c); -} - -mp_result -mp_int_sub(mp_int a, mp_int b, mp_int c) -{ - assert(a != NULL && b != NULL && c != NULL); - - mp_size ua = MP_USED(a); - mp_size ub = MP_USED(b); - mp_size max = MAX(ua, ub); - - if (MP_SIGN(a) != MP_SIGN(b)) - { - /* Different signs -- add magnitudes and keep sign of a */ - if (!s_pad(c, max)) - return MP_MEMORY; - - mp_digit carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); - mp_size uc = max; - - if (carry) - { - if (!s_pad(c, max + 1)) - return MP_MEMORY; - - c->digits[max] = carry; - ++uc; - } - - c->used = uc; - c->sign = a->sign; - - } - else - { - /* Same signs -- subtract magnitudes */ - if (!s_pad(c, max)) - return MP_MEMORY; - mp_int x, - y; - mp_sign osign; - - int cmp = s_ucmp(a, b); - - if (cmp >= 0) - { - x = a; - y = b; - osign = MP_ZPOS; - } - else - { - x = b; - y = a; - osign = MP_NEG; - } - - if (MP_SIGN(a) == MP_NEG && cmp != 0) - osign = 1 - osign; - - s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); - c->used = x->used; - CLAMP(c); - - c->sign = osign; - } - - return MP_OK; -} - -mp_result -mp_int_sub_value(mp_int a, mp_small value, mp_int c) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - - s_fake(&vtmp, value, vbuf); - - return mp_int_sub(a, &vtmp, c); -} - -mp_result -mp_int_mul(mp_int a, mp_int b, mp_int c) -{ - assert(a != NULL && b != NULL && c != NULL); - - /* If either input is zero, we can shortcut multiplication */ - if (mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0) - { - mp_int_zero(c); - return MP_OK; - } - - /* Output is positive if inputs have same sign, otherwise negative */ - mp_sign osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG; - - /* - * If the output is not identical to any of the inputs, we'll write the - * results directly; otherwise, allocate a temporary space. - */ - mp_size ua = MP_USED(a); - mp_size ub = MP_USED(b); - mp_size osize = MAX(ua, ub); - - osize = 4 * ((osize + 1) / 2); - - mp_digit *out; - mp_size p = 0; - - if (c == a || c == b) - { - p = MAX(s_round_prec(osize), default_precision); - - if ((out = s_alloc(p)) == NULL) - return MP_MEMORY; - } - else - { - if (!s_pad(c, osize)) - return MP_MEMORY; - - out = MP_DIGITS(c); - } - ZERO(out, osize); - - if (!s_kmul(MP_DIGITS(a), MP_DIGITS(b), out, ua, ub)) - return MP_MEMORY; - - /* - * If we allocated a new buffer, get rid of whatever memory c was already - * using, and fix up its fields to reflect that. - */ - if (out != MP_DIGITS(c)) - { - if ((void *) MP_DIGITS(c) != (void *) c) - s_free(MP_DIGITS(c)); - c->digits = out; - c->alloc = p; - } - - c->used = osize; /* might not be true, but we'll fix it ... */ - CLAMP(c); /* ... right here */ - c->sign = osign; - - return MP_OK; -} - -mp_result -mp_int_mul_value(mp_int a, mp_small value, mp_int c) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - - s_fake(&vtmp, value, vbuf); - - return mp_int_mul(a, &vtmp, c); -} - -mp_result -mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c) -{ - assert(a != NULL && c != NULL && p2 >= 0); - - mp_result res = mp_int_copy(a, c); - - if (res != MP_OK) - return res; - - if (s_qmul(c, (mp_size) p2)) - { - return MP_OK; - } - else - { - return MP_MEMORY; - } -} - -mp_result -mp_int_sqr(mp_int a, mp_int c) -{ - assert(a != NULL && c != NULL); - - /* Get a temporary buffer big enough to hold the result */ - mp_size osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2); - mp_size p = 0; - mp_digit *out; - - if (a == c) - { - p = s_round_prec(osize); - p = MAX(p, default_precision); - - if ((out = s_alloc(p)) == NULL) - return MP_MEMORY; - } - else - { - if (!s_pad(c, osize)) - return MP_MEMORY; - - out = MP_DIGITS(c); - } - ZERO(out, osize); - - s_ksqr(MP_DIGITS(a), out, MP_USED(a)); - - /* - * Get rid of whatever memory c was already using, and fix up its fields - * to reflect the new digit array it's using - */ - if (out != MP_DIGITS(c)) - { - if ((void *) MP_DIGITS(c) != (void *) c) - s_free(MP_DIGITS(c)); - c->digits = out; - c->alloc = p; - } - - c->used = osize; /* might not be true, but we'll fix it ... */ - CLAMP(c); /* ... right here */ - c->sign = MP_ZPOS; - - return MP_OK; -} - -mp_result -mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) -{ - assert(a != NULL && b != NULL && q != r); - - int cmp; - mp_result res = MP_OK; - mp_int qout, - rout; - mp_sign sa = MP_SIGN(a); - mp_sign sb = MP_SIGN(b); - - if (CMPZ(b) == 0) - { - return MP_UNDEF; - } - else if ((cmp = s_ucmp(a, b)) < 0) - { - /* - * If |a| < |b|, no division is required: q = 0, r = a - */ - if (r && (res = mp_int_copy(a, r)) != MP_OK) - return res; - - if (q) - mp_int_zero(q); - - return MP_OK; - } - else if (cmp == 0) - { - /* - * If |a| = |b|, no division is required: q = 1 or -1, r = 0 - */ - if (r) - mp_int_zero(r); - - if (q) - { - mp_int_zero(q); - q->digits[0] = 1; - - if (sa != sb) - q->sign = MP_NEG; - } - - return MP_OK; - } - - /* - * When |a| > |b|, real division is required. We need someplace to store - * quotient and remainder, but q and r are allowed to be NULL or to - * overlap with the inputs. - */ - DECLARE_TEMP(2); - int lg; - - if ((lg = s_isp2(b)) < 0) - { - if (q && b != q) - { - REQUIRE(mp_int_copy(a, q)); - qout = q; - } - else - { - REQUIRE(mp_int_copy(a, TEMP(0))); - qout = TEMP(0); - } - - if (r && a != r) - { - REQUIRE(mp_int_copy(b, r)); - rout = r; - } - else - { - REQUIRE(mp_int_copy(b, TEMP(1))); - rout = TEMP(1); - } - - REQUIRE(s_udiv_knuth(qout, rout)); - } - else - { - if (q) - REQUIRE(mp_int_copy(a, q)); - if (r) - REQUIRE(mp_int_copy(a, r)); - - if (q) - s_qdiv(q, (mp_size) lg); - qout = q; - if (r) - s_qmod(r, (mp_size) lg); - rout = r; - } - - /* Recompute signs for output */ - if (rout) - { - rout->sign = sa; - if (CMPZ(rout) == 0) - rout->sign = MP_ZPOS; - } - if (qout) - { - qout->sign = (sa == sb) ? MP_ZPOS : MP_NEG; - if (CMPZ(qout) == 0) - qout->sign = MP_ZPOS; - } - - if (q) - REQUIRE(mp_int_copy(qout, q)); - if (r) - REQUIRE(mp_int_copy(rout, r)); - CLEANUP_TEMP(); - return res; -} - -mp_result -mp_int_mod(mp_int a, mp_int m, mp_int c) -{ - DECLARE_TEMP(1); - mp_int out = (m == c) ? TEMP(0) : c; - - REQUIRE(mp_int_div(a, m, NULL, out)); - if (CMPZ(out) < 0) - { - REQUIRE(mp_int_add(out, m, c)); - } - else - { - REQUIRE(mp_int_copy(out, c)); - } - CLEANUP_TEMP(); - return MP_OK; -} - -mp_result -mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - - s_fake(&vtmp, value, vbuf); - - DECLARE_TEMP(1); - REQUIRE(mp_int_div(a, &vtmp, q, TEMP(0))); - - if (r) - (void) mp_int_to_int(TEMP(0), r); /* can't fail */ - - CLEANUP_TEMP(); - return MP_OK; -} - -mp_result -mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r) -{ - assert(a != NULL && p2 >= 0 && q != r); - - mp_result res = MP_OK; - - if (q != NULL && (res = mp_int_copy(a, q)) == MP_OK) - { - s_qdiv(q, (mp_size) p2); - } - - if (res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK) - { - s_qmod(r, (mp_size) p2); - } - - return res; -} - -mp_result -mp_int_expt(mp_int a, mp_small b, mp_int c) -{ - assert(c != NULL); - if (b < 0) - return MP_RANGE; - - DECLARE_TEMP(1); - REQUIRE(mp_int_copy(a, TEMP(0))); - - (void) mp_int_set_value(c, 1); - unsigned int v = labs(b); - - while (v != 0) - { - if (v & 1) - { - REQUIRE(mp_int_mul(c, TEMP(0), c)); - } - - v >>= 1; - if (v == 0) - break; - - REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); - } - - CLEANUP_TEMP(); - return MP_OK; -} - -mp_result -mp_int_expt_value(mp_small a, mp_small b, mp_int c) -{ - assert(c != NULL); - if (b < 0) - return MP_RANGE; - - DECLARE_TEMP(1); - REQUIRE(mp_int_set_value(TEMP(0), a)); - - (void) mp_int_set_value(c, 1); - unsigned int v = labs(b); - - while (v != 0) - { - if (v & 1) - { - REQUIRE(mp_int_mul(c, TEMP(0), c)); - } - - v >>= 1; - if (v == 0) - break; - - REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); - } - - CLEANUP_TEMP(); - return MP_OK; -} - -mp_result -mp_int_expt_full(mp_int a, mp_int b, mp_int c) -{ - assert(a != NULL && b != NULL && c != NULL); - if (MP_SIGN(b) == MP_NEG) - return MP_RANGE; - - DECLARE_TEMP(1); - REQUIRE(mp_int_copy(a, TEMP(0))); - - (void) mp_int_set_value(c, 1); - for (unsigned ix = 0; ix < MP_USED(b); ++ix) - { - mp_digit d = b->digits[ix]; - - for (unsigned jx = 0; jx < MP_DIGIT_BIT; ++jx) - { - if (d & 1) - { - REQUIRE(mp_int_mul(c, TEMP(0), c)); - } - - d >>= 1; - if (d == 0 && ix + 1 == MP_USED(b)) - break; - REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); - } - } - - CLEANUP_TEMP(); - return MP_OK; -} - -int -mp_int_compare(mp_int a, mp_int b) -{ - assert(a != NULL && b != NULL); - - mp_sign sa = MP_SIGN(a); - - if (sa == MP_SIGN(b)) - { - int cmp = s_ucmp(a, b); - - /* - * If they're both zero or positive, the normal comparison applies; if - * both negative, the sense is reversed. - */ - if (sa == MP_ZPOS) - { - return cmp; - } - else - { - return -cmp; - } - } - else if (sa == MP_ZPOS) - { - return 1; - } - else - { - return -1; - } -} - -int -mp_int_compare_unsigned(mp_int a, mp_int b) -{ - assert(a != NULL && b != NULL); - - return s_ucmp(a, b); -} - -int -mp_int_compare_zero(mp_int z) -{ - assert(z != NULL); - - if (MP_USED(z) == 1 && z->digits[0] == 0) - { - return 0; - } - else if (MP_SIGN(z) == MP_ZPOS) - { - return 1; - } - else - { - return -1; - } -} - -int -mp_int_compare_value(mp_int z, mp_small value) -{ - assert(z != NULL); - - mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS; - - if (vsign == MP_SIGN(z)) - { - int cmp = s_vcmp(z, value); - - return (vsign == MP_ZPOS) ? cmp : -cmp; - } - else - { - return (value < 0) ? 1 : -1; - } -} - -int -mp_int_compare_uvalue(mp_int z, mp_usmall uv) -{ - assert(z != NULL); - - if (MP_SIGN(z) == MP_NEG) - { - return -1; - } - else - { - return s_uvcmp(z, uv); - } -} - -mp_result -mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c) -{ - assert(a != NULL && b != NULL && c != NULL && m != NULL); - - /* Zero moduli and negative exponents are not considered. */ - if (CMPZ(m) == 0) - return MP_UNDEF; - if (CMPZ(b) < 0) - return MP_RANGE; - - mp_size um = MP_USED(m); - - DECLARE_TEMP(3); - REQUIRE(GROW(TEMP(0), 2 * um)); - REQUIRE(GROW(TEMP(1), 2 * um)); - - mp_int s; - - if (c == b || c == m) - { - REQUIRE(GROW(TEMP(2), 2 * um)); - s = TEMP(2); - } - else - { - s = c; - } - - REQUIRE(mp_int_mod(a, m, TEMP(0))); - REQUIRE(s_brmu(TEMP(1), m)); - REQUIRE(s_embar(TEMP(0), b, m, TEMP(1), s)); - REQUIRE(mp_int_copy(s, c)); - - CLEANUP_TEMP(); - return MP_OK; -} - -mp_result -mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - - s_fake(&vtmp, value, vbuf); - - return mp_int_exptmod(a, &vtmp, m, c); -} - -mp_result -mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c) -{ - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - - s_fake(&vtmp, value, vbuf); - - return mp_int_exptmod(&vtmp, b, m, c); -} - -mp_result -mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, - mp_int c) -{ - assert(a && b && m && c); - - /* Zero moduli and negative exponents are not considered. */ - if (CMPZ(m) == 0) - return MP_UNDEF; - if (CMPZ(b) < 0) - return MP_RANGE; - - DECLARE_TEMP(2); - mp_size um = MP_USED(m); - - REQUIRE(GROW(TEMP(0), 2 * um)); - - mp_int s; - - if (c == b || c == m) - { - REQUIRE(GROW(TEMP(1), 2 * um)); - s = TEMP(1); - } - else - { - s = c; - } - - REQUIRE(mp_int_mod(a, m, TEMP(0))); - REQUIRE(s_embar(TEMP(0), b, m, mu, s)); - REQUIRE(mp_int_copy(s, c)); - - CLEANUP_TEMP(); - return MP_OK; -} - -mp_result -mp_int_redux_const(mp_int m, mp_int c) -{ - assert(m != NULL && c != NULL && m != c); - - return s_brmu(c, m); -} - -mp_result -mp_int_invmod(mp_int a, mp_int m, mp_int c) -{ - assert(a != NULL && m != NULL && c != NULL); - - if (CMPZ(a) == 0 || CMPZ(m) <= 0) - return MP_RANGE; - - DECLARE_TEMP(2); - - REQUIRE(mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)); - - if (mp_int_compare_value(TEMP(0), 1) != 0) - { - REQUIRE(MP_UNDEF); - } - - /* It is first necessary to constrain the value to the proper range */ - REQUIRE(mp_int_mod(TEMP(1), m, TEMP(1))); - - /* - * Now, if 'a' was originally negative, the value we have is actually the - * magnitude of the negative representative; to get the positive value we - * have to subtract from the modulus. Otherwise, the value is okay as it - * stands. - */ - if (MP_SIGN(a) == MP_NEG) - { - REQUIRE(mp_int_sub(m, TEMP(1), c)); - } - else - { - REQUIRE(mp_int_copy(TEMP(1), c)); - } - - CLEANUP_TEMP(); - return MP_OK; -} - -/* Binary GCD algorithm due to Josef Stein, 1961 */ -mp_result -mp_int_gcd(mp_int a, mp_int b, mp_int c) -{ - assert(a != NULL && b != NULL && c != NULL); - - int ca = CMPZ(a); - int cb = CMPZ(b); - - if (ca == 0 && cb == 0) - { - return MP_UNDEF; - } - else if (ca == 0) - { - return mp_int_abs(b, c); - } - else if (cb == 0) - { - return mp_int_abs(a, c); - } - - DECLARE_TEMP(3); - REQUIRE(mp_int_copy(a, TEMP(0))); - REQUIRE(mp_int_copy(b, TEMP(1))); - - TEMP(0)->sign = MP_ZPOS; - TEMP(1)->sign = MP_ZPOS; - - int k = 0; - - { /* Divide out common factors of 2 from u and v */ - int div2_u = s_dp2k(TEMP(0)); - int div2_v = s_dp2k(TEMP(1)); - - k = MIN(div2_u, div2_v); - s_qdiv(TEMP(0), (mp_size) k); - s_qdiv(TEMP(1), (mp_size) k); - } - - if (mp_int_is_odd(TEMP(0))) - { - REQUIRE(mp_int_neg(TEMP(1), TEMP(2))); - } - else - { - REQUIRE(mp_int_copy(TEMP(0), TEMP(2))); - } - - for (;;) - { - s_qdiv(TEMP(2), s_dp2k(TEMP(2))); - - if (CMPZ(TEMP(2)) > 0) - { - REQUIRE(mp_int_copy(TEMP(2), TEMP(0))); - } - else - { - REQUIRE(mp_int_neg(TEMP(2), TEMP(1))); - } - - REQUIRE(mp_int_sub(TEMP(0), TEMP(1), TEMP(2))); - - if (CMPZ(TEMP(2)) == 0) - break; - } - - REQUIRE(mp_int_abs(TEMP(0), c)); - if (!s_qmul(c, (mp_size) k)) - REQUIRE(MP_MEMORY); - - CLEANUP_TEMP(); - return MP_OK; -} - -/* This is the binary GCD algorithm again, but this time we keep track of the - elementary matrix operations as we go, so we can get values x and y - satisfying c = ax + by. - */ -mp_result -mp_int_egcd(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y) -{ - assert(a != NULL && b != NULL && c != NULL && (x != NULL || y != NULL)); - - mp_result res = MP_OK; - int ca = CMPZ(a); - int cb = CMPZ(b); - - if (ca == 0 && cb == 0) - { - return MP_UNDEF; - } - else if (ca == 0) - { - if ((res = mp_int_abs(b, c)) != MP_OK) - return res; - mp_int_zero(x); - (void) mp_int_set_value(y, 1); - return MP_OK; - } - else if (cb == 0) - { - if ((res = mp_int_abs(a, c)) != MP_OK) - return res; - (void) mp_int_set_value(x, 1); - mp_int_zero(y); - return MP_OK; - } - - /* - * Initialize temporaries: A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 - */ - DECLARE_TEMP(8); - REQUIRE(mp_int_set_value(TEMP(0), 1)); - REQUIRE(mp_int_set_value(TEMP(3), 1)); - REQUIRE(mp_int_copy(a, TEMP(4))); - REQUIRE(mp_int_copy(b, TEMP(5))); - - /* We will work with absolute values here */ - TEMP(4)->sign = MP_ZPOS; - TEMP(5)->sign = MP_ZPOS; - - int k = 0; - - { /* Divide out common factors of 2 from u and v */ - int div2_u = s_dp2k(TEMP(4)), - div2_v = s_dp2k(TEMP(5)); - - k = MIN(div2_u, div2_v); - s_qdiv(TEMP(4), k); - s_qdiv(TEMP(5), k); - } - - REQUIRE(mp_int_copy(TEMP(4), TEMP(6))); - REQUIRE(mp_int_copy(TEMP(5), TEMP(7))); - - for (;;) - { - while (mp_int_is_even(TEMP(4))) - { - s_qdiv(TEMP(4), 1); - - if (mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) - { - REQUIRE(mp_int_add(TEMP(0), TEMP(7), TEMP(0))); - REQUIRE(mp_int_sub(TEMP(1), TEMP(6), TEMP(1))); - } - - s_qdiv(TEMP(0), 1); - s_qdiv(TEMP(1), 1); - } - - while (mp_int_is_even(TEMP(5))) - { - s_qdiv(TEMP(5), 1); - - if (mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) - { - REQUIRE(mp_int_add(TEMP(2), TEMP(7), TEMP(2))); - REQUIRE(mp_int_sub(TEMP(3), TEMP(6), TEMP(3))); - } - - s_qdiv(TEMP(2), 1); - s_qdiv(TEMP(3), 1); - } - - if (mp_int_compare(TEMP(4), TEMP(5)) >= 0) - { - REQUIRE(mp_int_sub(TEMP(4), TEMP(5), TEMP(4))); - REQUIRE(mp_int_sub(TEMP(0), TEMP(2), TEMP(0))); - REQUIRE(mp_int_sub(TEMP(1), TEMP(3), TEMP(1))); - } - else - { - REQUIRE(mp_int_sub(TEMP(5), TEMP(4), TEMP(5))); - REQUIRE(mp_int_sub(TEMP(2), TEMP(0), TEMP(2))); - REQUIRE(mp_int_sub(TEMP(3), TEMP(1), TEMP(3))); - } - - if (CMPZ(TEMP(4)) == 0) - { - if (x) - REQUIRE(mp_int_copy(TEMP(2), x)); - if (y) - REQUIRE(mp_int_copy(TEMP(3), y)); - if (c) - { - if (!s_qmul(TEMP(5), k)) - { - REQUIRE(MP_MEMORY); - } - REQUIRE(mp_int_copy(TEMP(5), c)); - } - - break; - } - } - - CLEANUP_TEMP(); - return MP_OK; -} - -mp_result -mp_int_lcm(mp_int a, mp_int b, mp_int c) -{ - assert(a != NULL && b != NULL && c != NULL); - - /* - * Since a * b = gcd(a, b) * lcm(a, b), we can compute lcm(a, b) = (a / - * gcd(a, b)) * b. - * - * This formulation insures everything works even if the input variables - * share space. - */ - DECLARE_TEMP(1); - REQUIRE(mp_int_gcd(a, b, TEMP(0))); - REQUIRE(mp_int_div(a, TEMP(0), TEMP(0), NULL)); - REQUIRE(mp_int_mul(TEMP(0), b, TEMP(0))); - REQUIRE(mp_int_copy(TEMP(0), c)); - - CLEANUP_TEMP(); - return MP_OK; -} - -bool -mp_int_divisible_value(mp_int a, mp_small v) -{ - mp_small rem = 0; - - if (mp_int_div_value(a, v, NULL, &rem) != MP_OK) - { - return false; - } - return rem == 0; -} - -int -mp_int_is_pow2(mp_int z) -{ - assert(z != NULL); - - return s_isp2(z); -} - -/* Implementation of Newton's root finding method, based loosely on a patch - contributed by Hal Finkel <half@halssoftware.com> - modified by M. J. Fromberger. - */ -mp_result -mp_int_root(mp_int a, mp_small b, mp_int c) -{ - assert(a != NULL && c != NULL && b > 0); - - if (b == 1) - { - return mp_int_copy(a, c); - } - bool flips = false; - - if (MP_SIGN(a) == MP_NEG) - { - if (b % 2 == 0) - { - return MP_UNDEF; /* root does not exist for negative a with - * even b */ - } - else - { - flips = true; - } - } - - DECLARE_TEMP(5); - REQUIRE(mp_int_copy(a, TEMP(0))); - REQUIRE(mp_int_copy(a, TEMP(1))); - TEMP(0)->sign = MP_ZPOS; - TEMP(1)->sign = MP_ZPOS; - - for (;;) - { - REQUIRE(mp_int_expt(TEMP(1), b, TEMP(2))); - - if (mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0) - break; - - REQUIRE(mp_int_sub(TEMP(2), TEMP(0), TEMP(2))); - REQUIRE(mp_int_expt(TEMP(1), b - 1, TEMP(3))); - REQUIRE(mp_int_mul_value(TEMP(3), b, TEMP(3))); - REQUIRE(mp_int_div(TEMP(2), TEMP(3), TEMP(4), NULL)); - REQUIRE(mp_int_sub(TEMP(1), TEMP(4), TEMP(4))); - - if (mp_int_compare_unsigned(TEMP(1), TEMP(4)) == 0) - { - REQUIRE(mp_int_sub_value(TEMP(4), 1, TEMP(4))); - } - REQUIRE(mp_int_copy(TEMP(4), TEMP(1))); - } - - REQUIRE(mp_int_copy(TEMP(1), c)); - - /* If the original value of a was negative, flip the output sign. */ - if (flips) - (void) mp_int_neg(c, c); /* cannot fail */ - - CLEANUP_TEMP(); - return MP_OK; -} - -mp_result -mp_int_to_int(mp_int z, mp_small *out) -{ - assert(z != NULL); - - /* Make sure the value is representable as a small integer */ - mp_sign sz = MP_SIGN(z); - - if ((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) || - mp_int_compare_value(z, MP_SMALL_MIN) < 0) - { - return MP_RANGE; - } - - mp_usmall uz = MP_USED(z); - mp_digit *dz = MP_DIGITS(z) + uz - 1; - mp_small uv = 0; - - while (uz > 0) - { - uv <<= MP_DIGIT_BIT / 2; - uv = (uv << (MP_DIGIT_BIT / 2)) | *dz--; - --uz; - } - - if (out) - *out = (mp_small) ((sz == MP_NEG) ? -uv : uv); - - return MP_OK; -} - -mp_result -mp_int_to_uint(mp_int z, mp_usmall *out) -{ - assert(z != NULL); - - /* Make sure the value is representable as an unsigned small integer */ - mp_size sz = MP_SIGN(z); - - if (sz == MP_NEG || mp_int_compare_uvalue(z, MP_USMALL_MAX) > 0) - { - return MP_RANGE; - } - - mp_size uz = MP_USED(z); - mp_digit *dz = MP_DIGITS(z) + uz - 1; - mp_usmall uv = 0; - - while (uz > 0) - { - uv <<= MP_DIGIT_BIT / 2; - uv = (uv << (MP_DIGIT_BIT / 2)) | *dz--; - --uz; - } - - if (out) - *out = uv; - - return MP_OK; -} - -mp_result -mp_int_to_string(mp_int z, mp_size radix, char *str, int limit) -{ - assert(z != NULL && str != NULL && limit >= 2); - assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); - - int cmp = 0; - - if (CMPZ(z) == 0) - { - *str++ = s_val2ch(0, 1); - } - else - { - mp_result res; - mpz_t tmp; - char *h, - *t; - - if ((res = mp_int_init_copy(&tmp, z)) != MP_OK) - return res; - - if (MP_SIGN(z) == MP_NEG) - { - *str++ = '-'; - --limit; - } - h = str; - - /* Generate digits in reverse order until finished or limit reached */ - for ( /* */ ; limit > 0; --limit) - { - mp_digit d; - - if ((cmp = CMPZ(&tmp)) == 0) - break; - - d = s_ddiv(&tmp, (mp_digit) radix); - *str++ = s_val2ch(d, 1); - } - t = str - 1; - - /* Put digits back in correct output order */ - while (h < t) - { - char tc = *h; - - *h++ = *t; - *t-- = tc; - } - - mp_int_clear(&tmp); - } - - *str = '\0'; - if (cmp == 0) - { - return MP_OK; - } - else - { - return MP_TRUNC; - } -} - -mp_result -mp_int_string_len(mp_int z, mp_size radix) -{ - assert(z != NULL); - assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); - - int len = s_outlen(z, radix) + 1; /* for terminator */ - - /* Allow for sign marker on negatives */ - if (MP_SIGN(z) == MP_NEG) - len += 1; - - return len; -} - -/* Read zero-terminated string into z */ -mp_result -mp_int_read_string(mp_int z, mp_size radix, const char *str) -{ - return mp_int_read_cstring(z, radix, str, NULL); -} - -mp_result -mp_int_read_cstring(mp_int z, mp_size radix, const char *str, - char **end) -{ - assert(z != NULL && str != NULL); - assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); - - /* Skip leading whitespace */ - while (isspace((unsigned char) *str)) - ++str; - - /* Handle leading sign tag (+/-, positive default) */ - switch (*str) - { - case '-': - z->sign = MP_NEG; - ++str; - break; - case '+': - ++str; /* fallthrough */ - default: - z->sign = MP_ZPOS; - break; - } - - /* Skip leading zeroes */ - int ch; - - while ((ch = s_ch2val(*str, radix)) == 0) - ++str; - - /* Make sure there is enough space for the value */ - if (!s_pad(z, s_inlen(strlen(str), radix))) - return MP_MEMORY; - - z->used = 1; - z->digits[0] = 0; - - while (*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) - { - s_dmul(z, (mp_digit) radix); - s_dadd(z, (mp_digit) ch); - ++str; - } - - CLAMP(z); - - /* Override sign for zero, even if negative specified. */ - if (CMPZ(z) == 0) - z->sign = MP_ZPOS; - - if (end != NULL) - *end = unconstify(char *, str); - - /* - * Return a truncation error if the string has unprocessed characters - * remaining, so the caller can tell if the whole string was done - */ - if (*str != '\0') - { - return MP_TRUNC; - } - else - { - return MP_OK; - } -} - -mp_result -mp_int_count_bits(mp_int z) -{ - assert(z != NULL); - - mp_size uz = MP_USED(z); - - if (uz == 1 && z->digits[0] == 0) - return 1; - - --uz; - mp_size nbits = uz * MP_DIGIT_BIT; - mp_digit d = z->digits[uz]; - - while (d != 0) - { - d >>= 1; - ++nbits; - } - - return nbits; -} - -mp_result -mp_int_to_binary(mp_int z, unsigned char *buf, int limit) -{ - static const int PAD_FOR_2C = 1; - - assert(z != NULL && buf != NULL); - - int limpos = limit; - mp_result res = s_tobin(z, buf, &limpos, PAD_FOR_2C); - - if (MP_SIGN(z) == MP_NEG) - s_2comp(buf, limpos); - - return res; -} - -mp_result -mp_int_read_binary(mp_int z, unsigned char *buf, int len) -{ - assert(z != NULL && buf != NULL && len > 0); - - /* Figure out how many digits are needed to represent this value */ - mp_size need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; - - if (!s_pad(z, need)) - return MP_MEMORY; - - mp_int_zero(z); - - /* - * If the high-order bit is set, take the 2's complement before reading - * the value (it will be restored afterward) - */ - if (buf[0] >> (CHAR_BIT - 1)) - { - z->sign = MP_NEG; - s_2comp(buf, len); - } - - mp_digit *dz = MP_DIGITS(z); - unsigned char *tmp = buf; - - for (int i = len; i > 0; --i, ++tmp) - { - s_qmul(z, (mp_size) CHAR_BIT); - *dz |= *tmp; - } - - /* Restore 2's complement if we took it before */ - if (MP_SIGN(z) == MP_NEG) - s_2comp(buf, len); - - return MP_OK; -} - -mp_result -mp_int_binary_len(mp_int z) -{ - mp_result res = mp_int_count_bits(z); - - if (res <= 0) - return res; - - int bytes = mp_int_unsigned_len(z); - - /* - * If the highest-order bit falls exactly on a byte boundary, we need to - * pad with an extra byte so that the sign will be read correctly when - * reading it back in. - */ - if (bytes * CHAR_BIT == res) - ++bytes; - - return bytes; -} - -mp_result -mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit) -{ - static const int NO_PADDING = 0; - - assert(z != NULL && buf != NULL); - - return s_tobin(z, buf, &limit, NO_PADDING); -} - -mp_result -mp_int_read_unsigned(mp_int z, unsigned char *buf, int len) -{ - assert(z != NULL && buf != NULL && len > 0); - - /* Figure out how many digits are needed to represent this value */ - mp_size need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; - - if (!s_pad(z, need)) - return MP_MEMORY; - - mp_int_zero(z); - - unsigned char *tmp = buf; - - for (int i = len; i > 0; --i, ++tmp) - { - (void) s_qmul(z, CHAR_BIT); - *MP_DIGITS(z) |= *tmp; - } - - return MP_OK; -} - -mp_result -mp_int_unsigned_len(mp_int z) -{ - mp_result res = mp_int_count_bits(z); - - if (res <= 0) - return res; - - int bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; - - return bytes; -} - -const char * -mp_error_string(mp_result res) -{ - if (res > 0) - return s_unknown_err; - - res = -res; - int ix; - - for (ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix) - ; - - if (s_error_msg[ix] != NULL) - { - return s_error_msg[ix]; - } - else - { - return s_unknown_err; - } -} - -/*------------------------------------------------------------------------*/ -/* Private functions for internal use. These make assumptions. */ - -#if IMATH_DEBUG -static const mp_digit fill = (mp_digit) 0xdeadbeefabad1dea; -#endif - -static mp_digit * -s_alloc(mp_size num) -{ - mp_digit *out = palloc(num * sizeof(mp_digit)); - - assert(out != NULL); - -#if IMATH_DEBUG - for (mp_size ix = 0; ix < num; ++ix) - out[ix] = fill; -#endif - return out; -} - -static mp_digit * -s_realloc(mp_digit *old, mp_size osize, mp_size nsize) -{ -#if IMATH_DEBUG - mp_digit *new = s_alloc(nsize); - - assert(new != NULL); - - for (mp_size ix = 0; ix < nsize; ++ix) - new[ix] = fill; - memcpy(new, old, osize * sizeof(mp_digit)); -#else - mp_digit *new = repalloc(old, nsize * sizeof(mp_digit)); - - assert(new != NULL); -#endif - - return new; -} - -static void -s_free(void *ptr) -{ - pfree(ptr); -} - -static bool -s_pad(mp_int z, mp_size min) -{ - if (MP_ALLOC(z) < min) - { - mp_size nsize = s_round_prec(min); - mp_digit *tmp; - - if (z->digits == &(z->single)) - { - if ((tmp = s_alloc(nsize)) == NULL) - return false; - tmp[0] = z->single; - } - else if ((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL) - { - return false; - } - - z->digits = tmp; - z->alloc = nsize; - } - - return true; -} - -/* Note: This will not work correctly when value == MP_SMALL_MIN */ -static void -s_fake(mp_int z, mp_small value, mp_digit vbuf[]) -{ - mp_usmall uv = (mp_usmall) (value < 0) ? -value : value; - - s_ufake(z, uv, vbuf); - if (value < 0) - z->sign = MP_NEG; -} - -static void -s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]) -{ - mp_size ndig = (mp_size) s_uvpack(value, vbuf); - - z->used = ndig; - z->alloc = MP_VALUE_DIGITS(value); - z->sign = MP_ZPOS; - z->digits = vbuf; -} - -static int -s_cdig(mp_digit *da, mp_digit *db, mp_size len) -{ - mp_digit *dat = da + len - 1, - *dbt = db + len - 1; - - for ( /* */ ; len != 0; --len, --dat, --dbt) - { - if (*dat > *dbt) - { - return 1; - } - else if (*dat < *dbt) - { - return -1; - } - } - - return 0; -} - -static int -s_uvpack(mp_usmall uv, mp_digit t[]) -{ - int ndig = 0; - - if (uv == 0) - t[ndig++] = 0; - else - { - while (uv != 0) - { - t[ndig++] = (mp_digit) uv; - uv >>= MP_DIGIT_BIT / 2; - uv >>= MP_DIGIT_BIT / 2; - } - } - - return ndig; -} - -static int -s_ucmp(mp_int a, mp_int b) -{ - mp_size ua = MP_USED(a), - ub = MP_USED(b); - - if (ua > ub) - { - return 1; - } - else if (ub > ua) - { - return -1; - } - else - { - return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua); - } -} - -static int -s_vcmp(mp_int a, mp_small v) -{ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4146) -#endif - mp_usmall uv = (v < 0) ? -(mp_usmall) v : (mp_usmall) v; -#ifdef _MSC_VER -#pragma warning(pop) -#endif - - return s_uvcmp(a, uv); -} - -static int -s_uvcmp(mp_int a, mp_usmall uv) -{ - mpz_t vtmp; - mp_digit vdig[MP_VALUE_DIGITS(uv)]; - - s_ufake(&vtmp, uv, vdig); - return s_ucmp(a, &vtmp); -} - -static mp_digit -s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, - mp_size size_b) -{ - mp_size pos; - mp_word w = 0; - - /* Insure that da is the longer of the two to simplify later code */ - if (size_b > size_a) - { - SWAP(mp_digit *, da, db); - SWAP(mp_size, size_a, size_b); - } - - /* Add corresponding digits until the shorter number runs out */ - for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) - { - w = w + (mp_word) *da + (mp_word) *db; - *dc = LOWER_HALF(w); - w = UPPER_HALF(w); - } - - /* Propagate carries as far as necessary */ - for ( /* */ ; pos < size_a; ++pos, ++da, ++dc) - { - w = w + *da; - - *dc = LOWER_HALF(w); - w = UPPER_HALF(w); - } - - /* Return carry out */ - return (mp_digit) w; -} - -static void -s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, - mp_size size_b) -{ - mp_size pos; - mp_word w = 0; - - /* We assume that |a| >= |b| so this should definitely hold */ - assert(size_a >= size_b); - - /* Subtract corresponding digits and propagate borrow */ - for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) - { - w = ((mp_word) MP_DIGIT_MAX + 1 + /* MP_RADIX */ - (mp_word) *da) - - w - (mp_word) *db; - - *dc = LOWER_HALF(w); - w = (UPPER_HALF(w) == 0); - } - - /* Finish the subtraction for remaining upper digits of da */ - for ( /* */ ; pos < size_a; ++pos, ++da, ++dc) - { - w = ((mp_word) MP_DIGIT_MAX + 1 + /* MP_RADIX */ - (mp_word) *da) - - w; - - *dc = LOWER_HALF(w); - w = (UPPER_HALF(w) == 0); - } - - /* If there is a borrow out at the end, it violates the precondition */ - assert(w == 0); -} - -static int -s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, - mp_size size_b) -{ - mp_size bot_size; - - /* Make sure b is the smaller of the two input values */ - if (size_b > size_a) - { - SWAP(mp_digit *, da, db); - SWAP(mp_size, size_a, size_b); - } - - /* - * Insure that the bottom is the larger half in an odd-length split; the - * code below relies on this being true. - */ - bot_size = (size_a + 1) / 2; - - /* - * If the values are big enough to bother with recursion, use the - * Karatsuba algorithm to compute the product; otherwise use the normal - * multiplication algorithm - */ - if (multiply_threshold && size_a >= multiply_threshold && size_b > bot_size) - { - mp_digit *t1, - *t2, - *t3, - carry; - - mp_digit *a_top = da + bot_size; - mp_digit *b_top = db + bot_size; - - mp_size at_size = size_a - bot_size; - mp_size bt_size = size_b - bot_size; - mp_size buf_size = 2 * bot_size; - - /* - * Do a single allocation for all three temporary buffers needed; each - * buffer must be big enough to hold the product of two bottom halves, - * and one buffer needs space for the completed product; twice the - * space is plenty. - */ - if ((t1 = s_alloc(4 * buf_size)) == NULL) - return 0; - t2 = t1 + buf_size; - t3 = t2 + buf_size; - ZERO(t1, 4 * buf_size); - - /* - * t1 and t2 are initially used as temporaries to compute the inner - * product (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0 - */ - carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */ - t1[bot_size] = carry; - - carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */ - t2[bot_size] = carry; - - (void) s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1); /* t3 = t1 * t2 */ - - /* - * Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so - * that we're left with only the pieces we want: t3 = a1b0 + a0b1 - */ - ZERO(t1, buf_size); - ZERO(t2, buf_size); - (void) s_kmul(da, db, t1, bot_size, bot_size); /* t1 = a0 * b0 */ - (void) s_kmul(a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */ - - /* Subtract out t1 and t2 to get the inner product */ - s_usub(t3, t1, t3, buf_size + 2, buf_size); - s_usub(t3, t2, t3, buf_size + 2, buf_size); - - /* Assemble the output value */ - COPY(t1, dc, buf_size); - carry = s_uadd(t3, dc + bot_size, dc + bot_size, buf_size + 1, buf_size); - assert(carry == 0); - - carry = - s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, buf_size, buf_size); - assert(carry == 0); - - s_free(t1); /* note t2 and t3 are just internal pointers - * to t1 */ - } - else - { - s_umul(da, db, dc, size_a, size_b); - } - - return 1; -} - -static void -s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, - mp_size size_b) -{ - mp_size a, - b; - mp_word w; - - for (a = 0; a < size_a; ++a, ++dc, ++da) - { - mp_digit *dct = dc; - mp_digit *dbt = db; - - if (*da == 0) - continue; - - w = 0; - for (b = 0; b < size_b; ++b, ++dbt, ++dct) - { - w = (mp_word) *da * (mp_word) *dbt + w + (mp_word) *dct; - - *dct = LOWER_HALF(w); - w = UPPER_HALF(w); - } - - *dct = (mp_digit) w; - } -} - -static int -s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) -{ - if (multiply_threshold && size_a > multiply_threshold) - { - mp_size bot_size = (size_a + 1) / 2; - mp_digit *a_top = da + bot_size; - mp_digit *t1, - *t2, - *t3, - carry PG_USED_FOR_ASSERTS_ONLY; - mp_size at_size = size_a - bot_size; - mp_size buf_size = 2 * bot_size; - - if ((t1 = s_alloc(4 * buf_size)) == NULL) - return 0; - t2 = t1 + buf_size; - t3 = t2 + buf_size; - ZERO(t1, 4 * buf_size); - - (void) s_ksqr(da, t1, bot_size); /* t1 = a0 ^ 2 */ - (void) s_ksqr(a_top, t2, at_size); /* t2 = a1 ^ 2 */ - - (void) s_kmul(da, a_top, t3, bot_size, at_size); /* t3 = a0 * a1 */ - - /* Quick multiply t3 by 2, shifting left (can't overflow) */ - { - int i, - top = bot_size + at_size; - mp_word w, - save = 0; - - for (i = 0; i < top; ++i) - { - w = t3[i]; - w = (w << 1) | save; - t3[i] = LOWER_HALF(w); - save = UPPER_HALF(w); - } - t3[i] = LOWER_HALF(save); - } - - /* Assemble the output value */ - COPY(t1, dc, 2 * bot_size); - carry = s_uadd(t3, dc + bot_size, dc + bot_size, buf_size + 1, buf_size); - assert(carry == 0); - - carry = - s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, buf_size, buf_size); - assert(carry == 0); - - s_free(t1); /* note that t2 and t2 are internal pointers - * only */ - - } - else - { - s_usqr(da, dc, size_a); - } - - return 1; -} - -static void -s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a) -{ - mp_size i, - j; - mp_word w; - - for (i = 0; i < size_a; ++i, dc += 2, ++da) - { - mp_digit *dct = dc, - *dat = da; - - if (*da == 0) - continue; - - /* Take care of the first digit, no rollover */ - w = (mp_word) *dat * (mp_word) *dat + (mp_word) *dct; - *dct = LOWER_HALF(w); - w = UPPER_HALF(w); - ++dat; - ++dct; - - for (j = i + 1; j < size_a; ++j, ++dat, ++dct) - { - mp_word t = (mp_word) *da * (mp_word) *dat; - mp_word u = w + (mp_word) *dct, - ov = 0; - - /* Check if doubling t will overflow a word */ - if (HIGH_BIT_SET(t)) - ov = 1; - - w = t + t; - - /* Check if adding u to w will overflow a word */ - if (ADD_WILL_OVERFLOW(w, u)) - ov = 1; - - w += u; - - *dct = LOWER_HALF(w); - w = UPPER_HALF(w); - if (ov) - { - w += MP_DIGIT_MAX; /* MP_RADIX */ - ++w; - } - } - - w = w + *dct; - *dct = (mp_digit) w; - while ((w = UPPER_HALF(w)) != 0) - { - ++dct; - w = w + *dct; - *dct = LOWER_HALF(w); - } - - assert(w == 0); - } -} - -static void -s_dadd(mp_int a, mp_digit b) -{ - mp_word w = 0; - mp_digit *da = MP_DIGITS(a); - mp_size ua = MP_USED(a); - - w = (mp_word) *da + b; - *da++ = LOWER_HALF(w); - w = UPPER_HALF(w); - - for (ua -= 1; ua > 0; --ua, ++da) - { - w = (mp_word) *da + w; - - *da = LOWER_HALF(w); - w = UPPER_HALF(w); - } - - if (w) - { - *da = (mp_digit) w; - a->used += 1; - } -} - -static void -s_dmul(mp_int a, mp_digit b) -{ - mp_word w = 0; - mp_digit *da = MP_DIGITS(a); - mp_size ua = MP_USED(a); - - while (ua > 0) - { - w = (mp_word) *da * b + w; - *da++ = LOWER_HALF(w); - w = UPPER_HALF(w); - --ua; - } - - if (w) - { - *da = (mp_digit) w; - a->used += 1; - } -} - -static void -s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) -{ - mp_word w = 0; - - while (size_a > 0) - { - w = (mp_word) *da++ * (mp_word) b + w; - - *dc++ = LOWER_HALF(w); - w = UPPER_HALF(w); - --size_a; - } - - if (w) - *dc = LOWER_HALF(w); -} - -static mp_digit -s_ddiv(mp_int a, mp_digit b) -{ - mp_word w = 0, - qdigit; - mp_size ua = MP_USED(a); - mp_digit *da = MP_DIGITS(a) + ua - 1; - - for ( /* */ ; ua > 0; --ua, --da) - { - w = (w << MP_DIGIT_BIT) | *da; - - if (w >= b) - { - qdigit = w / b; - w = w % b; - } - else - { - qdigit = 0; - } - - *da = (mp_digit) qdigit; - } - - CLAMP(a); - return (mp_digit) w; -} - -static void -s_qdiv(mp_int z, mp_size p2) -{ - mp_size ndig = p2 / MP_DIGIT_BIT, - nbits = p2 % MP_DIGIT_BIT; - mp_size uz = MP_USED(z); - - if (ndig) - { - mp_size mark; - mp_digit *to, - *from; - - if (ndig >= uz) - { - mp_int_zero(z); - return; - } - - to = MP_DIGITS(z); - from = to + ndig; - - for (mark = ndig; mark < uz; ++mark) - { - *to++ = *from++; - } - - z->used = uz - ndig; - } - - if (nbits) - { - mp_digit d = 0, - *dz, - save; - mp_size up = MP_DIGIT_BIT - nbits; - - uz = MP_USED(z); - dz = MP_DIGITS(z) + uz - 1; - - for ( /* */ ; uz > 0; --uz, --dz) - { - save = *dz; - - *dz = (*dz >> nbits) | (d << up); - d = save; - } - - CLAMP(z); - } - - if (MP_USED(z) == 1 && z->digits[0] == 0) - z->sign = MP_ZPOS; -} - -static void -s_qmod(mp_int z, mp_size p2) -{ - mp_size start = p2 / MP_DIGIT_BIT + 1, - rest = p2 % MP_DIGIT_BIT; - mp_size uz = MP_USED(z); - mp_digit mask = (1u << rest) - 1; - - if (start <= uz) - { - z->used = start; - z->digits[start - 1] &= mask; - CLAMP(z); - } -} - -static int -s_qmul(mp_int z, mp_size p2) -{ - mp_size uz, - need, - rest, - extra, - i; - mp_digit *from, - *to, - d; - - if (p2 == 0) - return 1; - - uz = MP_USED(z); - need = p2 / MP_DIGIT_BIT; - rest = p2 % MP_DIGIT_BIT; - - /* - * Figure out if we need an extra digit at the top end; this occurs if the - * topmost `rest' bits of the high-order digit of z are not zero, meaning - * they will be shifted off the end if not preserved - */ - extra = 0; - if (rest != 0) - { - mp_digit *dz = MP_DIGITS(z) + uz - 1; - - if ((*dz >> (MP_DIGIT_BIT - rest)) != 0) - extra = 1; - } - - if (!s_pad(z, uz + need + extra)) - return 0; - - /* - * If we need to shift by whole digits, do that in one pass, then to back - * and shift by partial digits. - */ - if (need > 0) - { - from = MP_DIGITS(z) + uz - 1; - to = from + need; - - for (i = 0; i < uz; ++i) - *to-- = *from--; - - ZERO(MP_DIGITS(z), need); - uz += need; - } - - if (rest) - { - d = 0; - for (i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from) - { - mp_digit save = *from; - - *from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest)); - d = save; - } - - d >>= (MP_DIGIT_BIT - rest); - if (d != 0) - { - *from = d; - uz += extra; - } - } - - z->used = uz; - CLAMP(z); - - return 1; -} - -/* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z| - The sign of the result is always zero/positive. - */ -static int -s_qsub(mp_int z, mp_size p2) -{ - mp_digit hi = (1u << (p2 % MP_DIGIT_BIT)), - *zp; - mp_size tdig = (p2 / MP_DIGIT_BIT), - pos; - mp_word w = 0; - - if (!s_pad(z, tdig + 1)) - return 0; - - for (pos = 0, zp = MP_DIGITS(z); pos < tdig; ++pos, ++zp) - { - w = ((mp_word) MP_DIGIT_MAX + 1) - w - (mp_word) *zp; - - *zp = LOWER_HALF(w); - w = UPPER_HALF(w) ? 0 : 1; - } - - w = ((mp_word) MP_DIGIT_MAX + 1 + hi) - w - (mp_word) *zp; - *zp = LOWER_HALF(w); - - assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */ - - z->sign = MP_ZPOS; - CLAMP(z); - - return 1; -} - -static int -s_dp2k(mp_int z) -{ - int k = 0; - mp_digit *dp = MP_DIGITS(z), - d; - - if (MP_USED(z) == 1 && *dp == 0) - return 1; - - while (*dp == 0) - { - k += MP_DIGIT_BIT; - ++dp; - } - - d = *dp; - while ((d & 1) == 0) - { - d >>= 1; - ++k; - } - - return k; -} - -static int -s_isp2(mp_int z) -{ - mp_size uz = MP_USED(z), - k = 0; - mp_digit *dz = MP_DIGITS(z), - d; - - while (uz > 1) - { - if (*dz++ != 0) - return -1; - k += MP_DIGIT_BIT; - --uz; - } - - d = *dz; - while (d > 1) - { - if (d & 1) - return -1; - ++k; - d >>= 1; - } - - return (int) k; -} - -static int -s_2expt(mp_int z, mp_small k) -{ - mp_size ndig, - rest; - mp_digit *dz; - - ndig = (k + MP_DIGIT_BIT) / MP_DIGIT_BIT; - rest = k % MP_DIGIT_BIT; - - if (!s_pad(z, ndig)) - return 0; - - dz = MP_DIGITS(z); - ZERO(dz, ndig); - *(dz + ndig - 1) = (1u << rest); - z->used = ndig; - - return 1; -} - -static int -s_norm(mp_int a, mp_int b) -{ - mp_digit d = b->digits[MP_USED(b) - 1]; - int k = 0; - - while (d < (1u << (mp_digit) (MP_DIGIT_BIT - 1))) - { /* d < (MP_RADIX / 2) */ - d <<= 1; - ++k; - } - - /* These multiplications can't fail */ - if (k != 0) - { - (void) s_qmul(a, (mp_size) k); - (void) s_qmul(b, (mp_size) k); - } - - return k; -} - -static mp_result -s_brmu(mp_int z, mp_int m) -{ - mp_size um = MP_USED(m) * 2; - - if (!s_pad(z, um)) - return MP_MEMORY; - - s_2expt(z, MP_DIGIT_BIT * um); - return mp_int_div(z, m, z, NULL); -} - -static int -s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2) -{ - mp_size um = MP_USED(m), - umb_p1, - umb_m1; - - umb_p1 = (um + 1) * MP_DIGIT_BIT; - umb_m1 = (um - 1) * MP_DIGIT_BIT; - - if (mp_int_copy(x, q1) != MP_OK) - return 0; - - /* Compute q2 = floor((floor(x / b^(k-1)) * mu) / b^(k+1)) */ - s_qdiv(q1, umb_m1); - UMUL(q1, mu, q2); - s_qdiv(q2, umb_p1); - - /* Set x = x mod b^(k+1) */ - s_qmod(x, umb_p1); - - /* - * Now, q is a guess for the quotient a / m. Compute x - q * m mod - * b^(k+1), replacing x. This may be off by a factor of 2m, but no more - * than that. - */ - UMUL(q2, m, q1); - s_qmod(q1, umb_p1); - (void) mp_int_sub(x, q1, x); /* can't fail */ - - /* - * The result may be < 0; if it is, add b^(k+1) to pin it in the proper - * range. - */ - if ((CMPZ(x) < 0) && !s_qsub(x, umb_p1)) - return 0; - - /* - * If x > m, we need to back it off until it is in range. This will be - * required at most twice. - */ - if (mp_int_compare(x, m) >= 0) - { - (void) mp_int_sub(x, m, x); - if (mp_int_compare(x, m) >= 0) - { - (void) mp_int_sub(x, m, x); - } - } - - /* At this point, x has been properly reduced. */ - return 1; -} - -/* Perform modular exponentiation using Barrett's method, where mu is the - reduction constant for m. Assumes a < m, b > 0. */ -static mp_result -s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) -{ - mp_digit umu = MP_USED(mu); - mp_digit *db = MP_DIGITS(b); - mp_digit *dbt = db + MP_USED(b) - 1; - - DECLARE_TEMP(3); - REQUIRE(GROW(TEMP(0), 4 * umu)); - REQUIRE(GROW(TEMP(1), 4 * umu)); - REQUIRE(GROW(TEMP(2), 4 * umu)); - ZERO(TEMP(0)->digits, TEMP(0)->alloc); - ZERO(TEMP(1)->digits, TEMP(1)->alloc); - ZERO(TEMP(2)->digits, TEMP(2)->alloc); - - (void) mp_int_set_value(c, 1); - - /* Take care of low-order digits */ - while (db < dbt) - { - mp_digit d = *db; - - for (int i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) - { - if (d & 1) - { - /* The use of a second temporary avoids allocation */ - UMUL(c, a, TEMP(0)); - if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) - { - REQUIRE(MP_MEMORY); - } - mp_int_copy(TEMP(0), c); - } - - USQR(a, TEMP(0)); - assert(MP_SIGN(TEMP(0)) == MP_ZPOS); - if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) - { - REQUIRE(MP_MEMORY); - } - assert(MP_SIGN(TEMP(0)) == MP_ZPOS); - mp_int_copy(TEMP(0), a); - } - - ++db; - } - - /* Take care of highest-order digit */ - mp_digit d = *dbt; - - for (;;) - { - if (d & 1) - { - UMUL(c, a, TEMP(0)); - if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) - { - REQUIRE(MP_MEMORY); - } - mp_int_copy(TEMP(0), c); - } - - d >>= 1; - if (!d) - break; - - USQR(a, TEMP(0)); - if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) - { - REQUIRE(MP_MEMORY); - } - (void) mp_int_copy(TEMP(0), a); - } - - CLEANUP_TEMP(); - return MP_OK; -} - -/* Division of nonnegative integers - - This function implements division algorithm for unsigned multi-precision - integers. The algorithm is based on Algorithm D from Knuth's "The Art of - Computer Programming", 3rd ed. 1998, pg 272-273. - - We diverge from Knuth's algorithm in that we do not perform the subtraction - from the remainder until we have determined that we have the correct - quotient digit. This makes our algorithm less efficient that Knuth because - we might have to perform multiple multiplication and comparison steps before - the subtraction. The advantage is that it is easy to implement and ensure - correctness without worrying about underflow from the subtraction. - - inputs: u a n+m digit integer in base b (b is 2^MP_DIGIT_BIT) - v a n digit integer in base b (b is 2^MP_DIGIT_BIT) - n >= 1 - m >= 0 - outputs: u / v stored in u - u % v stored in v - */ -static mp_result -s_udiv_knuth(mp_int u, mp_int v) -{ - /* Force signs to positive */ - u->sign = MP_ZPOS; - v->sign = MP_ZPOS; - - /* Use simple division algorithm when v is only one digit long */ - if (MP_USED(v) == 1) - { - mp_digit d, - rem; - - d = v->digits[0]; - rem = s_ddiv(u, d); - mp_int_set_value(v, rem); - return MP_OK; - } - - /* - * Algorithm D - * - * The n and m variables are defined as used by Knuth. u is an n digit - * number with digits u_{n-1}..u_0. v is an n+m digit number with digits - * from v_{m+n-1}..v_0. We require that n > 1 and m >= 0 - */ - mp_size n = MP_USED(v); - mp_size m = MP_USED(u) - n; - - assert(n > 1); - /* assert(m >= 0) follows because m is unsigned. */ - - /* - * D1: Normalize. The normalization step provides the necessary condition - * for Theorem B, which states that the quotient estimate for q_j, call it - * qhat - * - * qhat = u_{j+n}u_{j+n-1} / v_{n-1} - * - * is bounded by - * - * qhat - 2 <= q_j <= qhat. - * - * That is, qhat is always greater than the actual quotient digit q, and - * it is never more than two larger than the actual quotient digit. - */ - int k = s_norm(u, v); - - /* - * Extend size of u by one if needed. - * - * The algorithm begins with a value of u that has one more digit of - * input. The normalization step sets u_{m+n}..u_0 = 2^k * u_{m+n-1}..u_0. - * If the multiplication did not increase the number of digits of u, we - * need to add a leading zero here. - */ - if (k == 0 || MP_USED(u) != m + n + 1) - { - if (!s_pad(u, m + n + 1)) - return MP_MEMORY; - u->digits[m + n] = 0; - u->used = m + n + 1; - } - - /* - * Add a leading 0 to v. - * - * The multiplication in step D4 multiplies qhat * 0v_{n-1}..v_0. We need - * to add the leading zero to v here to ensure that the multiplication - * will produce the full n+1 digit result. - */ - if (!s_pad(v, n + 1)) - return MP_MEMORY; - v->digits[n] = 0; - - /* - * Initialize temporary variables q and t. q allocates space for m+1 - * digits to store the quotient digits t allocates space for n+1 digits to - * hold the result of q_j*v - */ - DECLARE_TEMP(2); - REQUIRE(GROW(TEMP(0), m + 1)); - REQUIRE(GROW(TEMP(1), n + 1)); - - /* D2: Initialize j */ - int j = m; - mpz_t r; - - r.digits = MP_DIGITS(u) + j; /* The contents of r are shared with u */ - r.used = n + 1; - r.sign = MP_ZPOS; - r.alloc = MP_ALLOC(u); - ZERO(TEMP(1)->digits, TEMP(1)->alloc); - - /* Calculate the m+1 digits of the quotient result */ - for (; j >= 0; j--) - { - /* D3: Calculate q' */ - /* r->digits is aligned to position j of the number u */ - mp_word pfx, - qhat; - - pfx = r.digits[n]; - pfx <<= MP_DIGIT_BIT / 2; - pfx <<= MP_DIGIT_BIT / 2; - pfx |= r.digits[n - 1]; /* pfx = u_{j+n}{j+n-1} */ - - qhat = pfx / v->digits[n - 1]; - - /* - * Check to see if qhat > b, and decrease qhat if so. Theorem B - * guarantess that qhat is at most 2 larger than the actual value, so - * it is possible that qhat is greater than the maximum value that - * will fit in a digit - */ - if (qhat > MP_DIGIT_MAX) - qhat = MP_DIGIT_MAX; - - /* - * D4,D5,D6: Multiply qhat * v and test for a correct value of q - * - * We proceed a bit different than the way described by Knuth. This - * way is simpler but less efficent. Instead of doing the multiply and - * subtract then checking for underflow, we first do the multiply of - * qhat * v and see if it is larger than the current remainder r. If - * it is larger, we decrease qhat by one and try again. We may need to - * decrease qhat one more time before we get a value that is smaller - * than r. - * - * This way is less efficent than Knuth becuase we do more multiplies, - * but we do not need to worry about underflow this way. - */ - /* t = qhat * v */ - s_dbmul(MP_DIGITS(v), (mp_digit) qhat, TEMP(1)->digits, n + 1); - TEMP(1)->used = n + 1; - CLAMP(TEMP(1)); - - /* Clamp r for the comparison. Comparisons do not like leading zeros. */ - CLAMP(&r); - if (s_ucmp(TEMP(1), &r) > 0) - { /* would the remainder be negative? */ - qhat -= 1; /* try a smaller q */ - s_dbmul(MP_DIGITS(v), (mp_digit) qhat, TEMP(1)->digits, n + 1); - TEMP(1)->used = n + 1; - CLAMP(TEMP(1)); - if (s_ucmp(TEMP(1), &r) > 0) - { /* would the remainder be negative? */ - assert(qhat > 0); - qhat -= 1; /* try a smaller q */ - s_dbmul(MP_DIGITS(v), (mp_digit) qhat, TEMP(1)->digits, n + 1); - TEMP(1)->used = n + 1; - CLAMP(TEMP(1)); - } - assert(s_ucmp(TEMP(1), &r) <= 0 && "The mathematics failed us."); - } - - /* - * Unclamp r. The D algorithm expects r = u_{j+n}..u_j to always be - * n+1 digits long. - */ - r.used = n + 1; - - /* - * D4: Multiply and subtract - * - * Note: The multiply was completed above so we only need to subtract - * here. - */ - s_usub(r.digits, TEMP(1)->digits, r.digits, r.used, TEMP(1)->used); - - /* - * D5: Test remainder - * - * Note: Not needed because we always check that qhat is the correct - * value before performing the subtract. Value cast to mp_digit to - * prevent warning, qhat has been clamped to MP_DIGIT_MAX - */ - TEMP(0)->digits[j] = (mp_digit) qhat; - - /* - * D6: Add back Note: Not needed because we always check that qhat is - * the correct value before performing the subtract. - */ - - /* D7: Loop on j */ - r.digits--; - ZERO(TEMP(1)->digits, TEMP(1)->alloc); - } - - /* Get rid of leading zeros in q */ - TEMP(0)->used = m + 1; - CLAMP(TEMP(0)); - - /* Denormalize the remainder */ - CLAMP(u); /* use u here because the r.digits pointer is - * off-by-one */ - if (k != 0) - s_qdiv(u, k); - - mp_int_copy(u, v); /* ok: 0 <= r < v */ - mp_int_copy(TEMP(0), u); /* ok: q <= u */ - - CLEANUP_TEMP(); - return MP_OK; -} - -static int -s_outlen(mp_int z, mp_size r) -{ - assert(r >= MP_MIN_RADIX && r <= MP_MAX_RADIX); - - mp_result bits = mp_int_count_bits(z); - double raw = (double) bits * s_log2[r]; - - return (int) (raw + 0.999999); -} - -static mp_size -s_inlen(int len, mp_size r) -{ - double raw = (double) len / s_log2[r]; - mp_size bits = (mp_size) (raw + 0.5); - - return (mp_size) ((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT) + 1; -} - -static int -s_ch2val(char c, int r) -{ - int out; - - /* - * In some locales, isalpha() accepts characters outside the range A-Z, - * producing out<0 or out>=36. The "out >= r" check will always catch - * out>=36. Though nothing explicitly catches out<0, our caller reacts - * the same way to every negative return value. - */ - if (isdigit((unsigned char) c)) - out = c - '0'; - else if (r > 10 && isalpha((unsigned char) c)) - out = toupper((unsigned char) c) - 'A' + 10; - else - return -1; - - return (out >= r) ? -1 : out; -} - -static char -s_val2ch(int v, int caps) -{ - assert(v >= 0); - - if (v < 10) - { - return v + '0'; - } - else - { - char out = (v - 10) + 'a'; - - if (caps) - { - return toupper((unsigned char) out); - } - else - { - return out; - } - } -} - -static void -s_2comp(unsigned char *buf, int len) -{ - unsigned short s = 1; - - for (int i = len - 1; i >= 0; --i) - { - unsigned char c = ~buf[i]; - - s = c + s; - c = s & UCHAR_MAX; - s >>= CHAR_BIT; - - buf[i] = c; - } - - /* last carry out is ignored */ -} - -static mp_result -s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) -{ - int pos = 0, - limit = *limpos; - mp_size uz = MP_USED(z); - mp_digit *dz = MP_DIGITS(z); - - while (uz > 0 && pos < limit) - { - mp_digit d = *dz++; - int i; - - for (i = sizeof(mp_digit); i > 0 && pos < limit; --i) - { - buf[pos++] = (unsigned char) d; - d >>= CHAR_BIT; - - /* Don't write leading zeroes */ - if (d == 0 && uz == 1) - i = 0; /* exit loop without signaling truncation */ - } - - /* Detect truncation (loop exited with pos >= limit) */ - if (i > 0) - break; - - --uz; - } - - if (pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1))) - { - if (pos < limit) - { - buf[pos++] = 0; - } - else - { - uz = 1; - } - } - - /* Digits are in reverse order, fix that */ - REV(buf, pos); - - /* Return the number of bytes actually written */ - *limpos = pos; - - return (uz == 0) ? MP_OK : MP_TRUNC; -} - -/* Here there be dragons */ diff --git a/contrib/pgcrypto/imath.h b/contrib/pgcrypto/imath.h deleted file mode 100644 index 0e1676d04e9..00000000000 --- a/contrib/pgcrypto/imath.h +++ /dev/null @@ -1,445 +0,0 @@ -/* - Name: imath.h - Purpose: Arbitrary precision integer arithmetic routines. - Author: M. J. Fromberger - - Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -#ifndef IMATH_H_ -#define IMATH_H_ - -#include <limits.h> - -typedef unsigned char mp_sign; -typedef unsigned int mp_size; -typedef int mp_result; -typedef long mp_small; /* must be a signed type */ -typedef unsigned long mp_usmall; /* must be an unsigned type */ - - -/* Build with words as uint64 by default. */ -#ifdef USE_32BIT_WORDS -typedef uint16 mp_digit; -typedef uint32 mp_word; -#define MP_DIGIT_MAX (PG_UINT16_MAX * 1UL) -#define MP_WORD_MAX (PG_UINT32_MAX * 1UL) -#else -typedef uint32 mp_digit; -typedef uint64 mp_word; -#define MP_DIGIT_MAX (PG_UINT32_MAX * UINT64CONST(1)) -#define MP_WORD_MAX (PG_UINT64_MAX) -#endif - -typedef struct -{ - mp_digit single; - mp_digit *digits; - mp_size alloc; - mp_size used; - mp_sign sign; -} mpz_t , - - *mp_int; - -static inline mp_digit * -MP_DIGITS(mp_int Z) -{ - return Z->digits; -} -static inline mp_size -MP_ALLOC(mp_int Z) -{ - return Z->alloc; -} -static inline mp_size -MP_USED(mp_int Z) -{ - return Z->used; -} -static inline mp_sign -MP_SIGN(mp_int Z) -{ - return Z->sign; -} - -extern const mp_result MP_OK; -extern const mp_result MP_FALSE; -extern const mp_result MP_TRUE; -extern const mp_result MP_MEMORY; -extern const mp_result MP_RANGE; -extern const mp_result MP_UNDEF; -extern const mp_result MP_TRUNC; -extern const mp_result MP_BADARG; -extern const mp_result MP_MINERR; - -#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT) -#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT) -#define MP_SMALL_MIN LONG_MIN -#define MP_SMALL_MAX LONG_MAX -#define MP_USMALL_MAX ULONG_MAX - -#define MP_MIN_RADIX 2 -#define MP_MAX_RADIX 36 - -/** Sets the default number of digits allocated to an `mp_int` constructed by - `mp_int_init_size()` with `prec == 0`. Allocations are rounded up to - multiples of this value. `MP_DEFAULT_PREC` is the default value. Requires - `ndigits > 0`. */ -void mp_int_default_precision(mp_size ndigits); - -/** Sets the number of digits below which multiplication will use the standard - quadratic "schoolbook" multiplcation algorithm rather than Karatsuba-Ofman. - Requires `ndigits >= sizeof(mp_word)`. */ -void mp_int_multiply_threshold(mp_size ndigits); - -/** A sign indicating a (strictly) negative value. */ -extern const mp_sign MP_NEG; - -/** A sign indicating a zero or positive value. */ -extern const mp_sign MP_ZPOS; - -/** Reports whether `z` is odd, having remainder 1 when divided by 2. */ -static inline bool -mp_int_is_odd(mp_int z) -{ - return (z->digits[0] & 1) != 0; -} - -/** Reports whether `z` is even, having remainder 0 when divided by 2. */ -static inline bool -mp_int_is_even(mp_int z) -{ - return (z->digits[0] & 1) == 0; -} - -/** Initializes `z` with 1-digit precision and sets it to zero. This function - cannot fail unless `z == NULL`. */ -mp_result mp_int_init(mp_int z); - -/** Allocates a fresh zero-valued `mpz_t` on the heap, returning NULL in case - of error. The only possible error is out-of-memory. */ -mp_int mp_int_alloc(void); - -/** Initializes `z` with at least `prec` digits of storage, and sets it to - zero. If `prec` is zero, the default precision is used. In either case the - size is rounded up to the nearest multiple of the word size. */ -mp_result mp_int_init_size(mp_int z, mp_size prec); - -/** Initializes `z` to be a copy of an already-initialized value in `old`. The - new copy does not share storage with the original. */ -mp_result mp_int_init_copy(mp_int z, mp_int old); - -/** Initializes `z` to the specified signed `value` at default precision. */ -mp_result mp_int_init_value(mp_int z, mp_small value); - -/** Initializes `z` to the specified unsigned `value` at default precision. */ -mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue); - -/** Sets `z` to the value of the specified signed `value`. */ -mp_result mp_int_set_value(mp_int z, mp_small value); - -/** Sets `z` to the value of the specified unsigned `value`. */ -mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue); - -/** Releases the storage used by `z`. */ -void mp_int_clear(mp_int z); - -/** Releases the storage used by `z` and also `z` itself. - This should only be used for `z` allocated by `mp_int_alloc()`. */ -void mp_int_free(mp_int z); - -/** Replaces the value of `c` with a copy of the value of `a`. No new memory is - allocated unless `a` has more significant digits than `c` has allocated. */ -mp_result mp_int_copy(mp_int a, mp_int c); - -/** Swaps the values and storage between `a` and `c`. */ -void mp_int_swap(mp_int a, mp_int c); - -/** Sets `z` to zero. The allocated storage of `z` is not changed. */ -void mp_int_zero(mp_int z); - -/** Sets `c` to the absolute value of `a`. */ -mp_result mp_int_abs(mp_int a, mp_int c); - -/** Sets `c` to the additive inverse (negation) of `a`. */ -mp_result mp_int_neg(mp_int a, mp_int c); - -/** Sets `c` to the sum of `a` and `b`. */ -mp_result mp_int_add(mp_int a, mp_int b, mp_int c); - -/** Sets `c` to the sum of `a` and `value`. */ -mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c); - -/** Sets `c` to the difference of `a` less `b`. */ -mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); - -/** Sets `c` to the difference of `a` less `value`. */ -mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c); - -/** Sets `c` to the product of `a` and `b`. */ -mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); - -/** Sets `c` to the product of `a` and `value`. */ -mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c); - -/** Sets `c` to the product of `a` and `2^p2`. Requires `p2 >= 0`. */ -mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c); - -/** Sets `c` to the square of `a`. */ -mp_result mp_int_sqr(mp_int a, mp_int c); - -/** Sets `q` and `r` to the quotent and remainder of `a / b`. Division by - powers of 2 is detected and handled efficiently. The remainder is pinned - to `0 <= r < b`. - - Either of `q` or `r` may be NULL, but not both, and `q` and `r` may not - point to the same value. */ -mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r); - -/** Sets `q` and `*r` to the quotent and remainder of `a / value`. Division by - powers of 2 is detected and handled efficiently. The remainder is pinned to - `0 <= *r < b`. Either of `q` or `r` may be NULL. */ -mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r); - -/** Sets `q` and `r` to the quotient and remainder of `a / 2^p2`. This is a - special case for division by powers of two that is more efficient than - using ordinary division. Note that `mp_int_div()` will automatically handle - this case, this function is for cases where you have only the exponent. */ -mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r); - -/** Sets `c` to the remainder of `a / m`. - The remainder is pinned to `0 <= c < m`. */ -mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); - -/** Sets `c` to the value of `a` raised to the `b` power. - It returns `MP_RANGE` if `b < 0`. */ -mp_result mp_int_expt(mp_int a, mp_small b, mp_int c); - -/** Sets `c` to the value of `a` raised to the `b` power. - It returns `MP_RANGE` if `b < 0`. */ -mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c); - -/** Sets `c` to the value of `a` raised to the `b` power. - It returns `MP_RANGE`) if `b < 0`. */ -mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c); - -/** Sets `*r` to the remainder of `a / value`. - The remainder is pinned to `0 <= r < value`. */ -static inline -mp_result -mp_int_mod_value(mp_int a, mp_small value, mp_small *r) -{ - return mp_int_div_value(a, value, 0, r); -} - -/** Returns the comparator of `a` and `b`. */ -int mp_int_compare(mp_int a, mp_int b); - -/** Returns the comparator of the magnitudes of `a` and `b`, disregarding their - signs. Neither `a` nor `b` is modified by the comparison. */ -int mp_int_compare_unsigned(mp_int a, mp_int b); - -/** Returns the comparator of `z` and zero. */ -int mp_int_compare_zero(mp_int z); - -/** Returns the comparator of `z` and the signed value `v`. */ -int mp_int_compare_value(mp_int z, mp_small v); - -/** Returns the comparator of `z` and the unsigned value `uv`. */ -int mp_int_compare_uvalue(mp_int z, mp_usmall uv); - -/** Reports whether `a` is divisible by `v`. */ -bool mp_int_divisible_value(mp_int a, mp_small v); - -/** Returns `k >= 0` such that `z` is `2^k`, if such a `k` exists. If no such - `k` exists, the function returns -1. */ -int mp_int_is_pow2(mp_int z); - -/** Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`. - It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ -mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c); - -/** Sets `c` to the value of `a` raised to the `value` power, modulo `m`. - It returns `MP_RANGE` if `value < 0` or `MP_UNDEF` if `m == 0`. */ -mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c); - -/** Sets `c` to the value of `value` raised to the `b` power, modulo `m`. - It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ -mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c); - -/** Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`, - given a precomputed reduction constant `mu` defined for Barrett's modular - reduction algorithm. - - It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ -mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); - -/** Sets `c` to the reduction constant for Barrett reduction by modulus `m`. - Requires that `c` and `m` point to distinct locations. */ -mp_result mp_int_redux_const(mp_int m, mp_int c); - -/** Sets `c` to the multiplicative inverse of `a` modulo `m`, if it exists. - The least non-negative representative of the congruence class is computed. - - It returns `MP_UNDEF` if the inverse does not exist, or `MP_RANGE` if `a == - 0` or `m <= 0`. */ -mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); - -/** Sets `c` to the greatest common divisor of `a` and `b`. - - It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a` - and `b` are both zero. */ -mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); - -/** Sets `c` to the greatest common divisor of `a` and `b`, and sets `x` and - `y` to values satisfying Bezout's identity `gcd(a, b) = ax + by`. - - It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a` - and `b` are both zero. */ -mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y); - -/** Sets `c` to the least common multiple of `a` and `b`. - - It returns `MP_UNDEF` if the LCM is undefined, such as for example if `a` - and `b` are both zero. */ -mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c); - -/** Sets `c` to the greatest integer not less than the `b`th root of `a`, - using Newton's root-finding algorithm. - It returns `MP_UNDEF` if `a < 0` and `b` is even. */ -mp_result mp_int_root(mp_int a, mp_small b, mp_int c); - -/** Sets `c` to the greatest integer not less than the square root of `a`. - This is a special case of `mp_int_root()`. */ -static inline -mp_result -mp_int_sqrt(mp_int a, mp_int c) -{ - return mp_int_root(a, 2, c); -} - -/** Returns `MP_OK` if `z` is representable as `mp_small`, else `MP_RANGE`. - If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`. */ -mp_result mp_int_to_int(mp_int z, mp_small *out); - -/** Returns `MP_OK` if `z` is representable as `mp_usmall`, or `MP_RANGE`. - If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`. */ -mp_result mp_int_to_uint(mp_int z, mp_usmall *out); - -/** Converts `z` to a zero-terminated string of characters in the specified - `radix`, writing at most `limit` characters to `str` including the - terminating NUL value. A leading `-` is used to indicate a negative value. - - Returns `MP_TRUNC` if `limit` was to small to write all of `z`. - Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ -mp_result mp_int_to_string(mp_int z, mp_size radix, char *str, int limit); - -/** Reports the minimum number of characters required to represent `z` as a - zero-terminated string in the given `radix`. - Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ -mp_result mp_int_string_len(mp_int z, mp_size radix); - -/** Reads a string of ASCII digits in the specified `radix` from the zero - terminated `str` provided into `z`. For values of `radix > 10`, the letters - `A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect - to case. - - Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a - sign flag. Processing stops when a NUL or any other character out of range - for a digit in the given radix is encountered. - - If the whole string was consumed, `MP_OK` is returned; otherwise - `MP_TRUNC`. is returned. - - Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ -mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str); - -/** Reads a string of ASCII digits in the specified `radix` from the zero - terminated `str` provided into `z`. For values of `radix > 10`, the letters - `A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect - to case. - - Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a - sign flag. Processing stops when a NUL or any other character out of range - for a digit in the given radix is encountered. - - If the whole string was consumed, `MP_OK` is returned; otherwise - `MP_TRUNC`. is returned. If `end` is not NULL, `*end` is set to point to - the first unconsumed byte of the input string (the NUL byte if the whole - string was consumed). This emulates the behavior of the standard C - `strtol()` function. - - Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ -mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end); - -/** Returns the number of significant bits in `z`. */ -mp_result mp_int_count_bits(mp_int z); - -/** Converts `z` to 2's complement binary, writing at most `limit` bytes into - the given `buf`. Returns `MP_TRUNC` if the buffer limit was too small to - contain the whole value. If this occurs, the contents of buf will be - effectively garbage, as the function uses the buffer as scratch space. - - The binary representation of `z` is in base-256 with digits ordered from - most significant to least significant (network byte ordering). The - high-order bit of the first byte is set for negative values, clear for - non-negative values. - - As a result, non-negative values will be padded with a leading zero byte if - the high-order byte of the base-256 magnitude is set. This extra byte is - accounted for by the `mp_int_binary_len()` function. */ -mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit); - -/** Reads a 2's complement binary value from `buf` into `z`, where `len` is the - length of the buffer. The contents of `buf` may be overwritten during - processing, although they will be restored when the function returns. */ -mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len); - -/** Returns the number of bytes to represent `z` in 2's complement binary. */ -mp_result mp_int_binary_len(mp_int z); - -/** Converts the magnitude of `z` to unsigned binary, writing at most `limit` - bytes into the given `buf`. The sign of `z` is ignored, but `z` is not - modified. Returns `MP_TRUNC` if the buffer limit was too small to contain - the whole value. If this occurs, the contents of `buf` will be effectively - garbage, as the function uses the buffer as scratch space during - conversion. - - The binary representation of `z` is in base-256 with digits ordered from - most significant to least significant (network byte ordering). */ -mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit); - -/** Reads an unsigned binary value from `buf` into `z`, where `len` is the - length of the buffer. The contents of `buf` are not modified during - processing. */ -mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len); - -/** Returns the number of bytes required to represent `z` as an unsigned binary - value in base 256. */ -mp_result mp_int_unsigned_len(mp_int z); - -/** Returns a pointer to a brief, human-readable, zero-terminated string - describing `res`. The returned string is statically allocated and must not - be freed by the caller. */ -const char *mp_error_string(mp_result res); - -#endif /* end IMATH_H_ */ diff --git a/contrib/pgcrypto/internal-sha2.c b/contrib/pgcrypto/internal-sha2.c deleted file mode 100644 index ecf3004e95b..00000000000 --- a/contrib/pgcrypto/internal-sha2.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * internal.c - * Wrapper for builtin functions - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * contrib/pgcrypto/internal-sha2.c - */ - -#include "postgres.h" - -#include <time.h> - -#include "common/cryptohash.h" -#include "common/sha2.h" -#include "px.h" - -void init_sha224(PX_MD *h); -void init_sha256(PX_MD *h); -void init_sha384(PX_MD *h); -void init_sha512(PX_MD *h); - -/* SHA224 */ -static unsigned -int_sha224_len(PX_MD *h) -{ - return PG_SHA224_DIGEST_LENGTH; -} - -static unsigned -int_sha224_block_len(PX_MD *h) -{ - return PG_SHA224_BLOCK_LENGTH; -} - -/* SHA256 */ -static unsigned -int_sha256_len(PX_MD *h) -{ - return PG_SHA256_DIGEST_LENGTH; -} - -static unsigned -int_sha256_block_len(PX_MD *h) -{ - return PG_SHA256_BLOCK_LENGTH; -} - -/* SHA384 */ -static unsigned -int_sha384_len(PX_MD *h) -{ - return PG_SHA384_DIGEST_LENGTH; -} - -static unsigned -int_sha384_block_len(PX_MD *h) -{ - return PG_SHA384_BLOCK_LENGTH; -} - -/* SHA512 */ -static unsigned -int_sha512_len(PX_MD *h) -{ - return PG_SHA512_DIGEST_LENGTH; -} - -static unsigned -int_sha512_block_len(PX_MD *h) -{ - return PG_SHA512_BLOCK_LENGTH; -} - -/* Generic interface for all SHA2 methods */ -static void -int_sha2_update(PX_MD *h, const uint8 *data, unsigned dlen) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_update(ctx, data, dlen) < 0) - elog(ERROR, "could not update %s context", "SHA2"); -} - -static void -int_sha2_reset(PX_MD *h) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_init(ctx) < 0) - elog(ERROR, "could not initialize %s context", "SHA2"); -} - -static void -int_sha2_finish(PX_MD *h, uint8 *dst) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0) - elog(ERROR, "could not finalize %s context", "SHA2"); -} - -static void -int_sha2_free(PX_MD *h) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - pg_cryptohash_free(ctx); - pfree(h); -} - -/* init functions */ - -void -init_sha224(PX_MD *md) -{ - pg_cryptohash_ctx *ctx; - - ctx = pg_cryptohash_create(PG_SHA224); - md->p.ptr = ctx; - - md->result_size = int_sha224_len; - md->block_size = int_sha224_block_len; - md->reset = int_sha2_reset; - md->update = int_sha2_update; - md->finish = int_sha2_finish; - md->free = int_sha2_free; - - md->reset(md); -} - -void -init_sha256(PX_MD *md) -{ - pg_cryptohash_ctx *ctx; - - ctx = pg_cryptohash_create(PG_SHA256); - md->p.ptr = ctx; - - md->result_size = int_sha256_len; - md->block_size = int_sha256_block_len; - md->reset = int_sha2_reset; - md->update = int_sha2_update; - md->finish = int_sha2_finish; - md->free = int_sha2_free; - - md->reset(md); -} - -void -init_sha384(PX_MD *md) -{ - pg_cryptohash_ctx *ctx; - - ctx = pg_cryptohash_create(PG_SHA384); - md->p.ptr = ctx; - - md->result_size = int_sha384_len; - md->block_size = int_sha384_block_len; - md->reset = int_sha2_reset; - md->update = int_sha2_update; - md->finish = int_sha2_finish; - md->free = int_sha2_free; - - md->reset(md); -} - -void -init_sha512(PX_MD *md) -{ - pg_cryptohash_ctx *ctx; - - ctx = pg_cryptohash_create(PG_SHA512); - md->p.ptr = ctx; - - md->result_size = int_sha512_len; - md->block_size = int_sha512_block_len; - md->reset = int_sha2_reset; - md->update = int_sha2_update; - md->finish = int_sha2_finish; - md->free = int_sha2_free; - - md->reset(md); -} diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c deleted file mode 100644 index dd45fee7ed6..00000000000 --- a/contrib/pgcrypto/internal.c +++ /dev/null @@ -1,585 +0,0 @@ -/* - * internal.c - * Wrapper for builtin functions - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * contrib/pgcrypto/internal.c - */ - -#include "postgres.h" - -#include <time.h> - -#include "blf.h" -#include "px.h" -#include "rijndael.h" - -#include "common/cryptohash.h" -#include "common/md5.h" -#include "common/sha1.h" - -#define SHA1_BLOCK_SIZE 64 -#define MD5_BLOCK_SIZE 64 - -static void init_md5(PX_MD *h); -static void init_sha1(PX_MD *h); - -void init_sha224(PX_MD *h); -void init_sha256(PX_MD *h); -void init_sha384(PX_MD *h); -void init_sha512(PX_MD *h); - -struct int_digest -{ - char *name; - void (*init) (PX_MD *h); -}; - -static const struct int_digest - int_digest_list[] = { - {"md5", init_md5}, - {"sha1", init_sha1}, - {"sha224", init_sha224}, - {"sha256", init_sha256}, - {"sha384", init_sha384}, - {"sha512", init_sha512}, - {NULL, NULL} -}; - -/* MD5 */ - -static unsigned -int_md5_len(PX_MD *h) -{ - return MD5_DIGEST_LENGTH; -} - -static unsigned -int_md5_block_len(PX_MD *h) -{ - return MD5_BLOCK_SIZE; -} - -static void -int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_update(ctx, data, dlen) < 0) - elog(ERROR, "could not update %s context", "MD5"); -} - -static void -int_md5_reset(PX_MD *h) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_init(ctx) < 0) - elog(ERROR, "could not initialize %s context", "MD5"); -} - -static void -int_md5_finish(PX_MD *h, uint8 *dst) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0) - elog(ERROR, "could not finalize %s context", "MD5"); -} - -static void -int_md5_free(PX_MD *h) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - pg_cryptohash_free(ctx); - pfree(h); -} - -/* SHA1 */ - -static unsigned -int_sha1_len(PX_MD *h) -{ - return SHA1_DIGEST_LENGTH; -} - -static unsigned -int_sha1_block_len(PX_MD *h) -{ - return SHA1_BLOCK_SIZE; -} - -static void -int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_update(ctx, data, dlen) < 0) - elog(ERROR, "could not update %s context", "SHA1"); -} - -static void -int_sha1_reset(PX_MD *h) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_init(ctx) < 0) - elog(ERROR, "could not initialize %s context", "SHA1"); -} - -static void -int_sha1_finish(PX_MD *h, uint8 *dst) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0) - elog(ERROR, "could not finalize %s context", "SHA1"); -} - -static void -int_sha1_free(PX_MD *h) -{ - pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - - pg_cryptohash_free(ctx); - pfree(h); -} - -/* init functions */ - -static void -init_md5(PX_MD *md) -{ - pg_cryptohash_ctx *ctx; - - ctx = pg_cryptohash_create(PG_MD5); - - md->p.ptr = ctx; - - md->result_size = int_md5_len; - md->block_size = int_md5_block_len; - md->reset = int_md5_reset; - md->update = int_md5_update; - md->finish = int_md5_finish; - md->free = int_md5_free; - - md->reset(md); -} - -static void -init_sha1(PX_MD *md) -{ - pg_cryptohash_ctx *ctx; - - ctx = pg_cryptohash_create(PG_SHA1); - - md->p.ptr = ctx; - - md->result_size = int_sha1_len; - md->block_size = int_sha1_block_len; - md->reset = int_sha1_reset; - md->update = int_sha1_update; - md->finish = int_sha1_finish; - md->free = int_sha1_free; - - md->reset(md); -} - -/* - * ciphers generally - */ - -#define INT_MAX_KEY (512/8) -#define INT_MAX_IV (128/8) - -struct int_ctx -{ - uint8 keybuf[INT_MAX_KEY]; - uint8 iv[INT_MAX_IV]; - union - { - BlowfishContext bf; - rijndael_ctx rj; - } ctx; - unsigned keylen; - int is_init; - int mode; -}; - -static void -intctx_free(PX_Cipher *c) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (cx) - { - px_memset(cx, 0, sizeof *cx); - pfree(cx); - } - pfree(c); -} - -/* - * AES/rijndael - */ - -#define MODE_ECB 0 -#define MODE_CBC 1 - -static unsigned -rj_block_size(PX_Cipher *c) -{ - return 128 / 8; -} - -static unsigned -rj_key_size(PX_Cipher *c) -{ - return 256 / 8; -} - -static unsigned -rj_iv_size(PX_Cipher *c) -{ - return 128 / 8; -} - -static int -rj_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (klen <= 128 / 8) - cx->keylen = 128 / 8; - else if (klen <= 192 / 8) - cx->keylen = 192 / 8; - else if (klen <= 256 / 8) - cx->keylen = 256 / 8; - else - return PXE_KEY_TOO_BIG; - - memcpy(&cx->keybuf, key, klen); - - if (iv) - memcpy(cx->iv, iv, 128 / 8); - - return 0; -} - -static int -rj_real_init(struct int_ctx *cx, int dir) -{ - aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir); - return 0; -} - -static int -rj_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (!cx->is_init) - { - if (rj_real_init(cx, 1)) - return PXE_CIPHER_INIT; - } - - if (dlen == 0) - return 0; - - if (dlen & 15) - return PXE_NOTBLOCKSIZE; - - memcpy(res, data, dlen); - - if (cx->mode == MODE_CBC) - { - aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen); - memcpy(cx->iv, res + dlen - 16, 16); - } - else - aes_ecb_encrypt(&cx->ctx.rj, res, dlen); - - return 0; -} - -static int -rj_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (!cx->is_init) - if (rj_real_init(cx, 0)) - return PXE_CIPHER_INIT; - - if (dlen == 0) - return 0; - - if (dlen & 15) - return PXE_NOTBLOCKSIZE; - - memcpy(res, data, dlen); - - if (cx->mode == MODE_CBC) - { - aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen); - memcpy(cx->iv, data + dlen - 16, 16); - } - else - aes_ecb_decrypt(&cx->ctx.rj, res, dlen); - - return 0; -} - -/* - * initializers - */ - -static PX_Cipher * -rj_load(int mode) -{ - PX_Cipher *c; - struct int_ctx *cx; - - c = palloc0(sizeof *c); - - c->block_size = rj_block_size; - c->key_size = rj_key_size; - c->iv_size = rj_iv_size; - c->init = rj_init; - c->encrypt = rj_encrypt; - c->decrypt = rj_decrypt; - c->free = intctx_free; - - cx = palloc0(sizeof *cx); - cx->mode = mode; - - c->ptr = cx; - return c; -} - -/* - * blowfish - */ - -static unsigned -bf_block_size(PX_Cipher *c) -{ - return 8; -} - -static unsigned -bf_key_size(PX_Cipher *c) -{ - return 448 / 8; -} - -static unsigned -bf_iv_size(PX_Cipher *c) -{ - return 8; -} - -static int -bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - blowfish_setkey(&cx->ctx.bf, key, klen); - if (iv) - blowfish_setiv(&cx->ctx.bf, iv); - - return 0; -} - -static int -bf_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - BlowfishContext *bfctx = &cx->ctx.bf; - - if (dlen == 0) - return 0; - - if (dlen & 7) - return PXE_NOTBLOCKSIZE; - - memcpy(res, data, dlen); - switch (cx->mode) - { - case MODE_ECB: - blowfish_encrypt_ecb(res, dlen, bfctx); - break; - case MODE_CBC: - blowfish_encrypt_cbc(res, dlen, bfctx); - break; - } - return 0; -} - -static int -bf_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - BlowfishContext *bfctx = &cx->ctx.bf; - - if (dlen == 0) - return 0; - - if (dlen & 7) - return PXE_NOTBLOCKSIZE; - - memcpy(res, data, dlen); - switch (cx->mode) - { - case MODE_ECB: - blowfish_decrypt_ecb(res, dlen, bfctx); - break; - case MODE_CBC: - blowfish_decrypt_cbc(res, dlen, bfctx); - break; - } - return 0; -} - -static PX_Cipher * -bf_load(int mode) -{ - PX_Cipher *c; - struct int_ctx *cx; - - c = palloc0(sizeof *c); - - c->block_size = bf_block_size; - c->key_size = bf_key_size; - c->iv_size = bf_iv_size; - c->init = bf_init; - c->encrypt = bf_encrypt; - c->decrypt = bf_decrypt; - c->free = intctx_free; - - cx = palloc0(sizeof *cx); - cx->mode = mode; - c->ptr = cx; - return c; -} - -/* ciphers */ - -static PX_Cipher * -rj_128_ecb(void) -{ - return rj_load(MODE_ECB); -} - -static PX_Cipher * -rj_128_cbc(void) -{ - return rj_load(MODE_CBC); -} - -static PX_Cipher * -bf_ecb_load(void) -{ - return bf_load(MODE_ECB); -} - -static PX_Cipher * -bf_cbc_load(void) -{ - return bf_load(MODE_CBC); -} - -struct int_cipher -{ - char *name; - PX_Cipher *(*load) (void); -}; - -static const struct int_cipher - int_ciphers[] = { - {"bf-cbc", bf_cbc_load}, - {"bf-ecb", bf_ecb_load}, - {"aes-128-cbc", rj_128_cbc}, - {"aes-128-ecb", rj_128_ecb}, - {NULL, NULL} -}; - -static const PX_Alias int_aliases[] = { - {"bf", "bf-cbc"}, - {"blowfish", "bf-cbc"}, - {"aes", "aes-128-cbc"}, - {"aes-ecb", "aes-128-ecb"}, - {"aes-cbc", "aes-128-cbc"}, - {"aes-128", "aes-128-cbc"}, - {"rijndael", "aes-128-cbc"}, - {"rijndael-128", "aes-128-cbc"}, - {NULL, NULL} -}; - -/* PUBLIC FUNCTIONS */ - -int -px_find_digest(const char *name, PX_MD **res) -{ - const struct int_digest *p; - PX_MD *h; - - for (p = int_digest_list; p->name; p++) - if (pg_strcasecmp(p->name, name) == 0) - { - h = palloc(sizeof(*h)); - p->init(h); - - *res = h; - - return 0; - } - return PXE_NO_HASH; -} - -int -px_find_cipher(const char *name, PX_Cipher **res) -{ - int i; - PX_Cipher *c = NULL; - - name = px_resolve_alias(int_aliases, name); - - for (i = 0; int_ciphers[i].name; i++) - if (strcmp(int_ciphers[i].name, name) == 0) - { - c = int_ciphers[i].load(); - break; - } - - if (c == NULL) - return PXE_NO_CIPHER; - - *res = c; - return 0; -} diff --git a/contrib/pgcrypto/pgp-mpi-internal.c b/contrib/pgcrypto/pgp-mpi-internal.c deleted file mode 100644 index 5b94e654521..00000000000 --- a/contrib/pgcrypto/pgp-mpi-internal.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * pgp-mpi-internal.c - * OpenPGP MPI functions. - * - * Copyright (c) 2005 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * contrib/pgcrypto/pgp-mpi-internal.c - */ -#include "postgres.h" - -#include "imath.h" -#include "pgp.h" -#include "px.h" - -static mpz_t * -mp_new(void) -{ - mpz_t *mp = mp_int_alloc(); - - mp_int_init_size(mp, 256); - return mp; -} - -static void -mp_clear_free(mpz_t *a) -{ - if (!a) - return; - /* fixme: no clear? */ - mp_int_free(a); -} - - -static int -mp_px_rand(uint32 bits, mpz_t *res) -{ - unsigned bytes = (bits + 7) / 8; - int last_bits = bits & 7; - uint8 *buf; - - buf = palloc(bytes); - if (!pg_strong_random(buf, bytes)) - { - pfree(buf); - return PXE_NO_RANDOM; - } - - /* clear unnecessary bits and set last bit to one */ - if (last_bits) - { - buf[0] >>= 8 - last_bits; - buf[0] |= 1 << (last_bits - 1); - } - else - buf[0] |= 1 << 7; - - mp_int_read_unsigned(res, buf, bytes); - - pfree(buf); - - return 0; -} - -static void -mp_modmul(mpz_t *a, mpz_t *b, mpz_t *p, mpz_t *res) -{ - mpz_t *tmp = mp_new(); - - mp_int_mul(a, b, tmp); - mp_int_mod(tmp, p, res); - mp_clear_free(tmp); -} - -static mpz_t * -mpi_to_bn(PGP_MPI *n) -{ - mpz_t *bn = mp_new(); - - mp_int_read_unsigned(bn, n->data, n->bytes); - - if (!bn) - return NULL; - if (mp_int_count_bits(bn) != n->bits) - { - px_debug("mpi_to_bn: bignum conversion failed: mpi=%d, bn=%d", - n->bits, mp_int_count_bits(bn)); - mp_clear_free(bn); - return NULL; - } - return bn; -} - -static PGP_MPI * -bn_to_mpi(mpz_t *bn) -{ - int res; - PGP_MPI *n; - int bytes; - - res = pgp_mpi_alloc(mp_int_count_bits(bn), &n); - if (res < 0) - return NULL; - - bytes = (mp_int_count_bits(bn) + 7) / 8; - if (bytes != n->bytes) - { - px_debug("bn_to_mpi: bignum conversion failed: bn=%d, mpi=%d", - bytes, n->bytes); - pgp_mpi_free(n); - return NULL; - } - mp_int_to_unsigned(bn, n->data, n->bytes); - return n; -} - -/* - * Decide the number of bits in the random component k - * - * It should be in the same range as p for signing (which - * is deprecated), but can be much smaller for encrypting. - * - * Until I research it further, I just mimic gpg behaviour. - * It has a special mapping table, for values <= 5120, - * above that it uses 'arbitrary high number'. Following - * algorithm hovers 10-70 bits above gpg values. And for - * larger p, it uses gpg's algorithm. - * - * The point is - if k gets large, encryption will be - * really slow. It does not matter for decryption. - */ -static int -decide_k_bits(int p_bits) -{ - if (p_bits <= 5120) - return p_bits / 10 + 160; - else - return (p_bits / 8 + 200) * 3 / 2; -} - -int -pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m, - PGP_MPI **c1_p, PGP_MPI **c2_p) -{ - int res = PXE_PGP_MATH_FAILED; - int k_bits; - mpz_t *m = mpi_to_bn(_m); - mpz_t *p = mpi_to_bn(pk->pub.elg.p); - mpz_t *g = mpi_to_bn(pk->pub.elg.g); - mpz_t *y = mpi_to_bn(pk->pub.elg.y); - mpz_t *k = mp_new(); - mpz_t *yk = mp_new(); - mpz_t *c1 = mp_new(); - mpz_t *c2 = mp_new(); - - if (!m || !p || !g || !y || !k || !yk || !c1 || !c2) - goto err; - - /* - * generate k - */ - k_bits = decide_k_bits(mp_int_count_bits(p)); - res = mp_px_rand(k_bits, k); - if (res < 0) - return res; - - /* - * c1 = g^k c2 = m * y^k - */ - mp_int_exptmod(g, k, p, c1); - mp_int_exptmod(y, k, p, yk); - mp_modmul(m, yk, p, c2); - - /* result */ - *c1_p = bn_to_mpi(c1); - *c2_p = bn_to_mpi(c2); - if (*c1_p && *c2_p) - res = 0; -err: - mp_clear_free(c2); - mp_clear_free(c1); - mp_clear_free(yk); - mp_clear_free(k); - mp_clear_free(y); - mp_clear_free(g); - mp_clear_free(p); - mp_clear_free(m); - return res; -} - -int -pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2, - PGP_MPI **msg_p) -{ - int res = PXE_PGP_MATH_FAILED; - mpz_t *c1 = mpi_to_bn(_c1); - mpz_t *c2 = mpi_to_bn(_c2); - mpz_t *p = mpi_to_bn(pk->pub.elg.p); - mpz_t *x = mpi_to_bn(pk->sec.elg.x); - mpz_t *c1x = mp_new(); - mpz_t *div = mp_new(); - mpz_t *m = mp_new(); - - if (!c1 || !c2 || !p || !x || !c1x || !div || !m) - goto err; - - /* - * m = c2 / (c1^x) - */ - mp_int_exptmod(c1, x, p, c1x); - mp_int_invmod(c1x, p, div); - mp_modmul(c2, div, p, m); - - /* result */ - *msg_p = bn_to_mpi(m); - if (*msg_p) - res = 0; -err: - mp_clear_free(m); - mp_clear_free(div); - mp_clear_free(c1x); - mp_clear_free(x); - mp_clear_free(p); - mp_clear_free(c2); - mp_clear_free(c1); - return res; -} - -int -pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p) -{ - int res = PXE_PGP_MATH_FAILED; - mpz_t *m = mpi_to_bn(_m); - mpz_t *e = mpi_to_bn(pk->pub.rsa.e); - mpz_t *n = mpi_to_bn(pk->pub.rsa.n); - mpz_t *c = mp_new(); - - if (!m || !e || !n || !c) - goto err; - - /* - * c = m ^ e - */ - mp_int_exptmod(m, e, n, c); - - *c_p = bn_to_mpi(c); - if (*c_p) - res = 0; -err: - mp_clear_free(c); - mp_clear_free(n); - mp_clear_free(e); - mp_clear_free(m); - return res; -} - -int -pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p) -{ - int res = PXE_PGP_MATH_FAILED; - mpz_t *c = mpi_to_bn(_c); - mpz_t *d = mpi_to_bn(pk->sec.rsa.d); - mpz_t *n = mpi_to_bn(pk->pub.rsa.n); - mpz_t *m = mp_new(); - - if (!m || !d || !n || !c) - goto err; - - /* - * m = c ^ d - */ - mp_int_exptmod(c, d, n, m); - - *m_p = bn_to_mpi(m); - if (*m_p) - res = 0; -err: - mp_clear_free(m); - mp_clear_free(n); - mp_clear_free(d); - mp_clear_free(c); - return res; -} diff --git a/contrib/pgcrypto/rijndael.c b/contrib/pgcrypto/rijndael.c deleted file mode 100644 index 69387011821..00000000000 --- a/contrib/pgcrypto/rijndael.c +++ /dev/null @@ -1,677 +0,0 @@ -/* $OpenBSD: rijndael.c,v 1.6 2000/12/09 18:51:34 markus Exp $ */ - -/* contrib/pgcrypto/rijndael.c */ - -/* This is an independent implementation of the encryption algorithm: */ -/* */ -/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ -/* */ -/* which is a candidate algorithm in the Advanced Encryption Standard */ -/* programme of the US National Institute of Standards and Technology. */ -/* */ -/* Copyright in this implementation is held by Dr B R Gladman but I */ -/* hereby give permission for its free direct or derivative use subject */ -/* to acknowledgment of its origin and compliance with any conditions */ -/* that the originators of the algorithm place on its exploitation. */ -/* */ -/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ - -/* Timing data for Rijndael (rijndael.c) - -Algorithm: rijndael (rijndael.c) - -128 bit key: -Key Setup: 305/1389 cycles (encrypt/decrypt) -Encrypt: 374 cycles = 68.4 mbits/sec -Decrypt: 352 cycles = 72.7 mbits/sec -Mean: 363 cycles = 70.5 mbits/sec - -192 bit key: -Key Setup: 277/1595 cycles (encrypt/decrypt) -Encrypt: 439 cycles = 58.3 mbits/sec -Decrypt: 425 cycles = 60.2 mbits/sec -Mean: 432 cycles = 59.3 mbits/sec - -256 bit key: -Key Setup: 374/1960 cycles (encrypt/decrypt) -Encrypt: 502 cycles = 51.0 mbits/sec -Decrypt: 498 cycles = 51.4 mbits/sec -Mean: 500 cycles = 51.2 mbits/sec - -*/ - -#include "postgres.h" - -#include <sys/param.h> - -#include "px.h" -#include "rijndael.h" - -#define PRE_CALC_TABLES -#define LARGE_TABLES - -static void gen_tabs(void); - -/* 3. Basic macros for speeding up generic operations */ - -/* Circular rotate of 32 bit values */ - -#define rotr(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n)))) -#define rotl(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n)))) - -/* Invert byte order in a 32 bit variable */ - -#define bswap(x) ((rotl((x), 8) & 0x00ff00ff) | (rotr((x), 8) & 0xff00ff00)) - -/* Extract byte from a 32 bit quantity (little endian notation) */ - -#define byte(x,n) ((u1byte)((x) >> (8 * (n)))) - -#ifdef WORDS_BIGENDIAN -#define io_swap(x) bswap(x) -#else -#define io_swap(x) (x) -#endif - -#ifdef PRINT_TABS -#undef PRE_CALC_TABLES -#endif - -#ifdef PRE_CALC_TABLES - -#include "rijndael.tbl" -#define tab_gen 1 -#else /* !PRE_CALC_TABLES */ - -static u1byte pow_tab[256]; -static u1byte log_tab[256]; -static u1byte sbx_tab[256]; -static u1byte isb_tab[256]; -static u4byte rco_tab[10]; -static u4byte ft_tab[4][256]; -static u4byte it_tab[4][256]; - -#ifdef LARGE_TABLES -static u4byte fl_tab[4][256]; -static u4byte il_tab[4][256]; -#endif - -static u4byte tab_gen = 0; -#endif /* !PRE_CALC_TABLES */ - -#define ff_mult(a,b) ((a) && (b) ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0) - -#define f_rn(bo, bi, n, k) \ - (bo)[n] = ft_tab[0][byte((bi)[n],0)] ^ \ - ft_tab[1][byte((bi)[((n) + 1) & 3],1)] ^ \ - ft_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \ - ft_tab[3][byte((bi)[((n) + 3) & 3],3)] ^ *((k) + (n)) - -#define i_rn(bo, bi, n, k) \ - (bo)[n] = it_tab[0][byte((bi)[n],0)] ^ \ - it_tab[1][byte((bi)[((n) + 3) & 3],1)] ^ \ - it_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \ - it_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n)) - -#ifdef LARGE_TABLES - -#define ls_box(x) \ - ( fl_tab[0][byte(x, 0)] ^ \ - fl_tab[1][byte(x, 1)] ^ \ - fl_tab[2][byte(x, 2)] ^ \ - fl_tab[3][byte(x, 3)] ) - -#define f_rl(bo, bi, n, k) \ - (bo)[n] = fl_tab[0][byte((bi)[n],0)] ^ \ - fl_tab[1][byte((bi)[((n) + 1) & 3],1)] ^ \ - fl_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \ - fl_tab[3][byte((bi)[((n) + 3) & 3],3)] ^ *((k) + (n)) - -#define i_rl(bo, bi, n, k) \ - (bo)[n] = il_tab[0][byte((bi)[n],0)] ^ \ - il_tab[1][byte((bi)[((n) + 3) & 3],1)] ^ \ - il_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \ - il_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n)) -#else - -#define ls_box(x) \ - ((u4byte)sbx_tab[byte(x, 0)] << 0) ^ \ - ((u4byte)sbx_tab[byte(x, 1)] << 8) ^ \ - ((u4byte)sbx_tab[byte(x, 2)] << 16) ^ \ - ((u4byte)sbx_tab[byte(x, 3)] << 24) - -#define f_rl(bo, bi, n, k) \ - (bo)[n] = (u4byte)sbx_tab[byte((bi)[n],0)] ^ \ - rotl(((u4byte)sbx_tab[byte((bi)[((n) + 1) & 3],1)]), 8) ^ \ - rotl(((u4byte)sbx_tab[byte((bi)[((n) + 2) & 3],2)]), 16) ^ \ - rotl(((u4byte)sbx_tab[byte((bi)[((n) + 3) & 3],3)]), 24) ^ *((k) + (n)) - -#define i_rl(bo, bi, n, k) \ - (bo)[n] = (u4byte)isb_tab[byte((bi)[n],0)] ^ \ - rotl(((u4byte)isb_tab[byte((bi)[((n) + 3) & 3],1)]), 8) ^ \ - rotl(((u4byte)isb_tab[byte((bi)[((n) + 2) & 3],2)]), 16) ^ \ - rotl(((u4byte)isb_tab[byte((bi)[((n) + 1) & 3],3)]), 24) ^ *((k) + (n)) -#endif - -static void -gen_tabs(void) -{ -#ifndef PRE_CALC_TABLES - u4byte i, - t; - u1byte p, - q; - - /* log and power tables for GF(2**8) finite field with */ - /* 0x11b as modular polynomial - the simplest primitive */ - /* root is 0x11, used here to generate the tables */ - - for (i = 0, p = 1; i < 256; ++i) - { - pow_tab[i] = (u1byte) p; - log_tab[p] = (u1byte) i; - - p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0); - } - - log_tab[1] = 0; - p = 1; - - for (i = 0; i < 10; ++i) - { - rco_tab[i] = p; - - p = (p << 1) ^ (p & 0x80 ? 0x1b : 0); - } - - /* note that the affine byte transformation matrix in */ - /* rijndael specification is in big endian format with */ - /* bit 0 as the most significant bit. In the remainder */ - /* of the specification the bits are numbered from the */ - /* least significant end of a byte. */ - - for (i = 0; i < 256; ++i) - { - p = (i ? pow_tab[255 - log_tab[i]] : 0); - q = p; - q = (q >> 7) | (q << 1); - p ^= q; - q = (q >> 7) | (q << 1); - p ^= q; - q = (q >> 7) | (q << 1); - p ^= q; - q = (q >> 7) | (q << 1); - p ^= q ^ 0x63; - sbx_tab[i] = (u1byte) p; - isb_tab[p] = (u1byte) i; - } - - for (i = 0; i < 256; ++i) - { - p = sbx_tab[i]; - -#ifdef LARGE_TABLES - - t = p; - fl_tab[0][i] = t; - fl_tab[1][i] = rotl(t, 8); - fl_tab[2][i] = rotl(t, 16); - fl_tab[3][i] = rotl(t, 24); -#endif - t = ((u4byte) ff_mult(2, p)) | - ((u4byte) p << 8) | - ((u4byte) p << 16) | - ((u4byte) ff_mult(3, p) << 24); - - ft_tab[0][i] = t; - ft_tab[1][i] = rotl(t, 8); - ft_tab[2][i] = rotl(t, 16); - ft_tab[3][i] = rotl(t, 24); - - p = isb_tab[i]; - -#ifdef LARGE_TABLES - - t = p; - il_tab[0][i] = t; - il_tab[1][i] = rotl(t, 8); - il_tab[2][i] = rotl(t, 16); - il_tab[3][i] = rotl(t, 24); -#endif - t = ((u4byte) ff_mult(14, p)) | - ((u4byte) ff_mult(9, p) << 8) | - ((u4byte) ff_mult(13, p) << 16) | - ((u4byte) ff_mult(11, p) << 24); - - it_tab[0][i] = t; - it_tab[1][i] = rotl(t, 8); - it_tab[2][i] = rotl(t, 16); - it_tab[3][i] = rotl(t, 24); - } - - tab_gen = 1; -#endif /* !PRE_CALC_TABLES */ -} - - -#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) - -#define imix_col(y,x) \ -do { \ - u = star_x(x); \ - v = star_x(u); \ - w = star_x(v); \ - t = w ^ (x); \ - (y) = u ^ v ^ w; \ - (y) ^= rotr(u ^ t, 8) ^ \ - rotr(v ^ t, 16) ^ \ - rotr(t,24); \ -} while (0) - -/* initialise the key schedule from the user supplied key */ - -#define loop4(i) \ -do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ - t ^= e_key[4 * i]; e_key[4 * i + 4] = t; \ - t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t; \ - t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t; \ - t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t; \ -} while (0) - -#define loop6(i) \ -do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ - t ^= e_key[6 * (i)]; e_key[6 * (i) + 6] = t; \ - t ^= e_key[6 * (i) + 1]; e_key[6 * (i) + 7] = t; \ - t ^= e_key[6 * (i) + 2]; e_key[6 * (i) + 8] = t; \ - t ^= e_key[6 * (i) + 3]; e_key[6 * (i) + 9] = t; \ - t ^= e_key[6 * (i) + 4]; e_key[6 * (i) + 10] = t; \ - t ^= e_key[6 * (i) + 5]; e_key[6 * (i) + 11] = t; \ -} while (0) - -#define loop8(i) \ -do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ - t ^= e_key[8 * (i)]; e_key[8 * (i) + 8] = t; \ - t ^= e_key[8 * (i) + 1]; e_key[8 * (i) + 9] = t; \ - t ^= e_key[8 * (i) + 2]; e_key[8 * (i) + 10] = t; \ - t ^= e_key[8 * (i) + 3]; e_key[8 * (i) + 11] = t; \ - t = e_key[8 * (i) + 4] ^ ls_box(t); \ - e_key[8 * (i) + 12] = t; \ - t ^= e_key[8 * (i) + 5]; e_key[8 * (i) + 13] = t; \ - t ^= e_key[8 * (i) + 6]; e_key[8 * (i) + 14] = t; \ - t ^= e_key[8 * (i) + 7]; e_key[8 * (i) + 15] = t; \ -} while (0) - -rijndael_ctx * -rijndael_set_key(rijndael_ctx *ctx, const u4byte *in_key, const u4byte key_len, - int encrypt) -{ - u4byte i, - t, - u, - v, - w; - u4byte *e_key = ctx->e_key; - u4byte *d_key = ctx->d_key; - - ctx->decrypt = !encrypt; - - if (!tab_gen) - gen_tabs(); - - ctx->k_len = (key_len + 31) / 32; - - e_key[0] = io_swap(in_key[0]); - e_key[1] = io_swap(in_key[1]); - e_key[2] = io_swap(in_key[2]); - e_key[3] = io_swap(in_key[3]); - - switch (ctx->k_len) - { - case 4: - t = e_key[3]; - for (i = 0; i < 10; ++i) - loop4(i); - break; - - case 6: - e_key[4] = io_swap(in_key[4]); - t = e_key[5] = io_swap(in_key[5]); - for (i = 0; i < 8; ++i) - loop6(i); - break; - - case 8: - e_key[4] = io_swap(in_key[4]); - e_key[5] = io_swap(in_key[5]); - e_key[6] = io_swap(in_key[6]); - t = e_key[7] = io_swap(in_key[7]); - for (i = 0; i < 7; ++i) - loop8(i); - break; - } - - if (!encrypt) - { - d_key[0] = e_key[0]; - d_key[1] = e_key[1]; - d_key[2] = e_key[2]; - d_key[3] = e_key[3]; - - for (i = 4; i < 4 * ctx->k_len + 24; ++i) - imix_col(d_key[i], e_key[i]); - } - - return ctx; -} - -/* encrypt a block of text */ - -#define f_nround(bo, bi, k) \ -do { \ - f_rn(bo, bi, 0, k); \ - f_rn(bo, bi, 1, k); \ - f_rn(bo, bi, 2, k); \ - f_rn(bo, bi, 3, k); \ - k += 4; \ -} while (0) - -#define f_lround(bo, bi, k) \ -do { \ - f_rl(bo, bi, 0, k); \ - f_rl(bo, bi, 1, k); \ - f_rl(bo, bi, 2, k); \ - f_rl(bo, bi, 3, k); \ -} while (0) - -void -rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk) -{ - u4byte k_len = ctx->k_len; - u4byte *e_key = ctx->e_key; - u4byte b0[4], - b1[4], - *kp; - - b0[0] = io_swap(in_blk[0]) ^ e_key[0]; - b0[1] = io_swap(in_blk[1]) ^ e_key[1]; - b0[2] = io_swap(in_blk[2]) ^ e_key[2]; - b0[3] = io_swap(in_blk[3]) ^ e_key[3]; - - kp = e_key + 4; - - if (k_len > 6) - { - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - } - - if (k_len > 4) - { - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - } - - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - f_nround(b1, b0, kp); - f_lround(b0, b1, kp); - - out_blk[0] = io_swap(b0[0]); - out_blk[1] = io_swap(b0[1]); - out_blk[2] = io_swap(b0[2]); - out_blk[3] = io_swap(b0[3]); -} - -/* decrypt a block of text */ - -#define i_nround(bo, bi, k) \ -do { \ - i_rn(bo, bi, 0, k); \ - i_rn(bo, bi, 1, k); \ - i_rn(bo, bi, 2, k); \ - i_rn(bo, bi, 3, k); \ - k -= 4; \ -} while (0) - -#define i_lround(bo, bi, k) \ -do { \ - i_rl(bo, bi, 0, k); \ - i_rl(bo, bi, 1, k); \ - i_rl(bo, bi, 2, k); \ - i_rl(bo, bi, 3, k); \ -} while (0) - -void -rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk) -{ - u4byte b0[4], - b1[4], - *kp; - u4byte k_len = ctx->k_len; - u4byte *e_key = ctx->e_key; - u4byte *d_key = ctx->d_key; - - b0[0] = io_swap(in_blk[0]) ^ e_key[4 * k_len + 24]; - b0[1] = io_swap(in_blk[1]) ^ e_key[4 * k_len + 25]; - b0[2] = io_swap(in_blk[2]) ^ e_key[4 * k_len + 26]; - b0[3] = io_swap(in_blk[3]) ^ e_key[4 * k_len + 27]; - - kp = d_key + 4 * (k_len + 5); - - if (k_len > 6) - { - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - } - - if (k_len > 4) - { - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - } - - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - i_nround(b1, b0, kp); - i_lround(b0, b1, kp); - - out_blk[0] = io_swap(b0[0]); - out_blk[1] = io_swap(b0[1]); - out_blk[2] = io_swap(b0[2]); - out_blk[3] = io_swap(b0[3]); -} - -/* - * conventional interface - * - * ATM it hopes all data is 4-byte aligned - which - * should be true for PX. -marko - */ - -void -aes_set_key(rijndael_ctx *ctx, const uint8 *key, unsigned keybits, int enc) -{ - uint32 *k; - - k = (uint32 *) key; - rijndael_set_key(ctx, k, keybits, enc); -} - -void -aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len) -{ - unsigned bs = 16; - uint32 *d; - - while (len >= bs) - { - d = (uint32 *) data; - rijndael_encrypt(ctx, d, d); - - len -= bs; - data += bs; - } -} - -void -aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len) -{ - unsigned bs = 16; - uint32 *d; - - while (len >= bs) - { - d = (uint32 *) data; - rijndael_decrypt(ctx, d, d); - - len -= bs; - data += bs; - } -} - -void -aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len) -{ - uint32 *iv = (uint32 *) iva; - uint32 *d = (uint32 *) data; - unsigned bs = 16; - - while (len >= bs) - { - d[0] ^= iv[0]; - d[1] ^= iv[1]; - d[2] ^= iv[2]; - d[3] ^= iv[3]; - - rijndael_encrypt(ctx, d, d); - - iv = d; - d += bs / 4; - len -= bs; - } -} - -void -aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len) -{ - uint32 *d = (uint32 *) data; - unsigned bs = 16; - uint32 buf[4], - iv[4]; - - memcpy(iv, iva, bs); - while (len >= bs) - { - buf[0] = d[0]; - buf[1] = d[1]; - buf[2] = d[2]; - buf[3] = d[3]; - - rijndael_decrypt(ctx, buf, d); - - d[0] ^= iv[0]; - d[1] ^= iv[1]; - d[2] ^= iv[2]; - d[3] ^= iv[3]; - - iv[0] = buf[0]; - iv[1] = buf[1]; - iv[2] = buf[2]; - iv[3] = buf[3]; - d += 4; - len -= bs; - } -} - -/* - * pre-calculate tables. - * - * On i386 lifts 17k from .bss to .rodata - * and avoids 1k code and setup time. - * -marko - */ -#ifdef PRINT_TABS - -static void -show256u8(char *name, uint8 *data) -{ - int i; - - printf("static const u1byte %s[256] = {\n ", name); - for (i = 0; i < 256;) - { - printf("%u", pow_tab[i++]); - if (i < 256) - printf(i % 16 ? ", " : ",\n "); - } - printf("\n};\n\n"); -} - - -static void -show4x256u32(char *name, uint32 data[4][256]) -{ - int i, - j; - - printf("static const u4byte %s[4][256] = {\n{\n ", name); - for (i = 0; i < 4; i++) - { - for (j = 0; j < 256;) - { - printf("0x%08x", data[i][j]); - j++; - if (j < 256) - printf(j % 4 ? ", " : ",\n "); - } - printf(i < 3 ? "\n}, {\n " : "\n}\n"); - } - printf("};\n\n"); -} - -int -main() -{ - int i; - char *hdr = "/* Generated by rijndael.c */\n\n"; - - gen_tabs(); - - printf(hdr); - show256u8("pow_tab", pow_tab); - show256u8("log_tab", log_tab); - show256u8("sbx_tab", sbx_tab); - show256u8("isb_tab", isb_tab); - - show4x256u32("ft_tab", ft_tab); - show4x256u32("it_tab", it_tab); -#ifdef LARGE_TABLES - show4x256u32("fl_tab", fl_tab); - show4x256u32("il_tab", il_tab); -#endif - printf("static const u4byte rco_tab[10] = {\n "); - for (i = 0; i < 10; i++) - { - printf("0x%08x", rco_tab[i]); - if (i < 9) - printf(", "); - if (i == 4) - printf("\n "); - } - printf("\n};\n\n"); - return 0; -} - -#endif diff --git a/contrib/pgcrypto/rijndael.h b/contrib/pgcrypto/rijndael.h deleted file mode 100644 index bc9ddfaad35..00000000000 --- a/contrib/pgcrypto/rijndael.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * contrib/pgcrypto/rijndael.h - * - * $OpenBSD: rijndael.h,v 1.3 2001/05/09 23:01:32 markus Exp $ */ - -/* This is an independent implementation of the encryption algorithm: */ -/* */ -/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ -/* */ -/* which is a candidate algorithm in the Advanced Encryption Standard */ -/* programme of the US National Institute of Standards and Technology. */ -/* */ -/* Copyright in this implementation is held by Dr B R Gladman but I */ -/* hereby give permission for its free direct or derivative use subject */ -/* to acknowledgment of its origin and compliance with any conditions */ -/* that the originators of the algorithm place on its exploitation. */ -/* */ -/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ - -#ifndef _RIJNDAEL_H_ -#define _RIJNDAEL_H_ - -/* 1. Standard types for AES cryptography source code */ - -typedef uint8 u1byte; /* an 8 bit unsigned character type */ -typedef uint16 u2byte; /* a 16 bit unsigned integer type */ -typedef uint32 u4byte; /* a 32 bit unsigned integer type */ - -typedef int8 s1byte; /* an 8 bit signed character type */ -typedef int16 s2byte; /* a 16 bit signed integer type */ -typedef int32 s4byte; /* a 32 bit signed integer type */ - -typedef struct _rijndael_ctx -{ - u4byte k_len; - int decrypt; - u4byte e_key[64]; - u4byte d_key[64]; -} rijndael_ctx; - - -/* 2. Standard interface for AES cryptographic routines */ - -/* These are all based on 32 bit unsigned values and will therefore */ -/* require endian conversions for big-endian architectures */ - -rijndael_ctx *rijndael_set_key(rijndael_ctx *, const u4byte *, const u4byte, int); -void rijndael_encrypt(rijndael_ctx *, const u4byte *, u4byte *); -void rijndael_decrypt(rijndael_ctx *, const u4byte *, u4byte *); - -/* conventional interface */ - -void aes_set_key(rijndael_ctx *ctx, const uint8 *key, unsigned keybits, int enc); -void aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len); -void aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len); -void aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len); -void aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len); - -#endif /* _RIJNDAEL_H_ */ diff --git a/contrib/pgcrypto/rijndael.tbl b/contrib/pgcrypto/rijndael.tbl deleted file mode 100644 index c7610c01346..00000000000 --- a/contrib/pgcrypto/rijndael.tbl +++ /dev/null @@ -1,1138 +0,0 @@ -/* Generated by rijndael.c */ - -static const u1byte pow_tab[256] = { - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -static const u1byte log_tab[256] = { - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -static const u1byte sbx_tab[256] = { - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -static const u1byte isb_tab[256] = { - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -static const u4byte ft_tab[4][256] = { -{ - 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, - 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, - 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, - 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, - 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, - 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, - 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, - 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, - 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, - 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, - 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, - 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, - 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, - 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, - 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, - 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, - 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, - 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, - 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, - 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, - 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, - 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, - 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, - 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, - 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, - 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, - 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, - 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, - 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, - 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, - 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, - 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, - 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, - 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, - 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, - 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, - 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, - 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, - 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, - 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, - 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, - 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, - 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, - 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, - 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, - 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, - 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, - 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, - 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, - 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, - 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, - 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, - 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, - 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, - 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, - 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, - 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, - 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, - 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, - 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, - 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, - 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, - 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, - 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c -}, { - 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, - 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, - 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, - 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, - 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, - 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, - 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, - 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, - 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, - 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, - 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, - 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, - 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, - 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, - 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, - 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, - 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, - 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, - 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, - 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, - 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, - 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, - 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, - 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, - 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, - 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, - 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, - 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, - 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, - 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, - 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, - 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, - 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, - 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, - 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, - 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, - 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, - 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, - 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, - 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, - 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, - 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, - 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, - 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, - 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, - 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, - 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, - 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, - 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, - 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, - 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, - 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, - 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, - 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, - 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, - 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, - 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, - 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, - 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, - 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, - 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, - 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, - 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, - 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a -}, { - 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, - 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, - 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, - 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, - 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, - 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, - 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, - 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, - 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, - 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, - 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, - 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, - 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, - 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, - 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, - 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, - 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, - 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, - 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, - 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, - 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, - 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, - 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, - 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, - 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, - 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, - 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, - 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, - 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, - 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, - 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, - 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, - 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, - 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, - 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, - 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, - 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, - 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, - 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, - 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, - 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, - 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, - 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, - 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, - 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, - 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, - 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, - 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, - 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, - 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, - 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, - 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, - 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, - 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, - 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, - 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, - 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, - 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, - 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, - 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, - 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, - 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, - 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, - 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 -}, { - 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, - 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, - 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, - 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, - 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, - 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, - 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, - 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, - 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, - 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, - 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, - 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, - 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, - 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, - 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, - 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, - 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, - 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, - 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, - 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, - 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, - 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, - 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, - 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, - 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, - 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, - 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, - 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, - 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, - 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, - 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, - 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, - 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, - 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, - 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, - 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, - 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, - 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, - 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, - 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, - 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, - 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, - 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, - 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, - 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, - 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, - 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, - 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, - 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, - 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, - 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, - 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, - 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, - 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, - 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, - 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, - 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, - 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, - 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, - 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, - 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, - 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, - 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, - 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 -} -}; - -static const u4byte it_tab[4][256] = { -{ - 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, - 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, - 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, - 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, - 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, - 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, - 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, - 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, - 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, - 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, - 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, - 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, - 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, - 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, - 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, - 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, - 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, - 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, - 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, - 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, - 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, - 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, - 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, - 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, - 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, - 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, - 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, - 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, - 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, - 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, - 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, - 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, - 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, - 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, - 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, - 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, - 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, - 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, - 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, - 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, - 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, - 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, - 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, - 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, - 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, - 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, - 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, - 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef, - 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, - 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, - 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, - 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, - 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, - 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, - 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, - 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, - 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, - 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, - 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, - 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, - 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, - 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, - 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, - 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0 -}, { - 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, - 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93, - 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, - 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, - 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1, - 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, - 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, - 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, - 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, - 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, - 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, - 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, - 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, - 0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a, - 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5, - 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, - 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, - 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, - 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, - 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, - 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, - 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, - 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, - 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, - 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, - 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, - 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, - 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, - 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, - 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, - 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, - 0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, - 0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd, - 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, - 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, - 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, - 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, - 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, - 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, - 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, - 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, - 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, - 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, - 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, - 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, - 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, - 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, - 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, - 0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6, - 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, - 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, - 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, - 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df, - 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, - 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, - 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, - 0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89, - 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, - 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, - 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, - 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, - 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, - 0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, - 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042 -}, { - 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, - 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, - 0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c, - 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, - 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, - 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, - 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, - 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, - 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, - 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, - 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, - 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b, - 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, - 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, - 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, - 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, - 0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, - 0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe, - 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, - 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, - 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, - 0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15, - 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, - 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, - 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, - 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, - 0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, - 0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, - 0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, - 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, - 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, - 0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, - 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, - 0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, - 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, - 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, - 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, - 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, - 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, - 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, - 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, - 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, - 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, - 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, - 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, - 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, - 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, - 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, - 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, - 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, - 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, - 0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, - 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, - 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, - 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, - 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, - 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, - 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, - 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, - 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, - 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, - 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195, - 0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1, - 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257 -}, { - 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, - 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, - 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, - 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, - 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, - 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, - 0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, - 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, - 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, - 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, - 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, - 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, - 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, - 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, - 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, - 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, - 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, - 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6, - 0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, - 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, - 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, - 0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550, - 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, - 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8, - 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, - 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, - 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d, - 0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, - 0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, - 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, - 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, - 0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, - 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, - 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, - 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, - 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, - 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, - 0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1, - 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, - 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, - 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, - 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, - 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, - 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, - 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, - 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, - 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, - 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, - 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, - 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, - 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, - 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, - 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, - 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, - 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, - 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, - 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, - 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, - 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, - 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, - 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, - 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, - 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156, - 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8 -} -}; - -static const u4byte fl_tab[4][256] = { -{ - 0x00000063, 0x0000007c, 0x00000077, 0x0000007b, - 0x000000f2, 0x0000006b, 0x0000006f, 0x000000c5, - 0x00000030, 0x00000001, 0x00000067, 0x0000002b, - 0x000000fe, 0x000000d7, 0x000000ab, 0x00000076, - 0x000000ca, 0x00000082, 0x000000c9, 0x0000007d, - 0x000000fa, 0x00000059, 0x00000047, 0x000000f0, - 0x000000ad, 0x000000d4, 0x000000a2, 0x000000af, - 0x0000009c, 0x000000a4, 0x00000072, 0x000000c0, - 0x000000b7, 0x000000fd, 0x00000093, 0x00000026, - 0x00000036, 0x0000003f, 0x000000f7, 0x000000cc, - 0x00000034, 0x000000a5, 0x000000e5, 0x000000f1, - 0x00000071, 0x000000d8, 0x00000031, 0x00000015, - 0x00000004, 0x000000c7, 0x00000023, 0x000000c3, - 0x00000018, 0x00000096, 0x00000005, 0x0000009a, - 0x00000007, 0x00000012, 0x00000080, 0x000000e2, - 0x000000eb, 0x00000027, 0x000000b2, 0x00000075, - 0x00000009, 0x00000083, 0x0000002c, 0x0000001a, - 0x0000001b, 0x0000006e, 0x0000005a, 0x000000a0, - 0x00000052, 0x0000003b, 0x000000d6, 0x000000b3, - 0x00000029, 0x000000e3, 0x0000002f, 0x00000084, - 0x00000053, 0x000000d1, 0x00000000, 0x000000ed, - 0x00000020, 0x000000fc, 0x000000b1, 0x0000005b, - 0x0000006a, 0x000000cb, 0x000000be, 0x00000039, - 0x0000004a, 0x0000004c, 0x00000058, 0x000000cf, - 0x000000d0, 0x000000ef, 0x000000aa, 0x000000fb, - 0x00000043, 0x0000004d, 0x00000033, 0x00000085, - 0x00000045, 0x000000f9, 0x00000002, 0x0000007f, - 0x00000050, 0x0000003c, 0x0000009f, 0x000000a8, - 0x00000051, 0x000000a3, 0x00000040, 0x0000008f, - 0x00000092, 0x0000009d, 0x00000038, 0x000000f5, - 0x000000bc, 0x000000b6, 0x000000da, 0x00000021, - 0x00000010, 0x000000ff, 0x000000f3, 0x000000d2, - 0x000000cd, 0x0000000c, 0x00000013, 0x000000ec, - 0x0000005f, 0x00000097, 0x00000044, 0x00000017, - 0x000000c4, 0x000000a7, 0x0000007e, 0x0000003d, - 0x00000064, 0x0000005d, 0x00000019, 0x00000073, - 0x00000060, 0x00000081, 0x0000004f, 0x000000dc, - 0x00000022, 0x0000002a, 0x00000090, 0x00000088, - 0x00000046, 0x000000ee, 0x000000b8, 0x00000014, - 0x000000de, 0x0000005e, 0x0000000b, 0x000000db, - 0x000000e0, 0x00000032, 0x0000003a, 0x0000000a, - 0x00000049, 0x00000006, 0x00000024, 0x0000005c, - 0x000000c2, 0x000000d3, 0x000000ac, 0x00000062, - 0x00000091, 0x00000095, 0x000000e4, 0x00000079, - 0x000000e7, 0x000000c8, 0x00000037, 0x0000006d, - 0x0000008d, 0x000000d5, 0x0000004e, 0x000000a9, - 0x0000006c, 0x00000056, 0x000000f4, 0x000000ea, - 0x00000065, 0x0000007a, 0x000000ae, 0x00000008, - 0x000000ba, 0x00000078, 0x00000025, 0x0000002e, - 0x0000001c, 0x000000a6, 0x000000b4, 0x000000c6, - 0x000000e8, 0x000000dd, 0x00000074, 0x0000001f, - 0x0000004b, 0x000000bd, 0x0000008b, 0x0000008a, - 0x00000070, 0x0000003e, 0x000000b5, 0x00000066, - 0x00000048, 0x00000003, 0x000000f6, 0x0000000e, - 0x00000061, 0x00000035, 0x00000057, 0x000000b9, - 0x00000086, 0x000000c1, 0x0000001d, 0x0000009e, - 0x000000e1, 0x000000f8, 0x00000098, 0x00000011, - 0x00000069, 0x000000d9, 0x0000008e, 0x00000094, - 0x0000009b, 0x0000001e, 0x00000087, 0x000000e9, - 0x000000ce, 0x00000055, 0x00000028, 0x000000df, - 0x0000008c, 0x000000a1, 0x00000089, 0x0000000d, - 0x000000bf, 0x000000e6, 0x00000042, 0x00000068, - 0x00000041, 0x00000099, 0x0000002d, 0x0000000f, - 0x000000b0, 0x00000054, 0x000000bb, 0x00000016 -}, { - 0x00006300, 0x00007c00, 0x00007700, 0x00007b00, - 0x0000f200, 0x00006b00, 0x00006f00, 0x0000c500, - 0x00003000, 0x00000100, 0x00006700, 0x00002b00, - 0x0000fe00, 0x0000d700, 0x0000ab00, 0x00007600, - 0x0000ca00, 0x00008200, 0x0000c900, 0x00007d00, - 0x0000fa00, 0x00005900, 0x00004700, 0x0000f000, - 0x0000ad00, 0x0000d400, 0x0000a200, 0x0000af00, - 0x00009c00, 0x0000a400, 0x00007200, 0x0000c000, - 0x0000b700, 0x0000fd00, 0x00009300, 0x00002600, - 0x00003600, 0x00003f00, 0x0000f700, 0x0000cc00, - 0x00003400, 0x0000a500, 0x0000e500, 0x0000f100, - 0x00007100, 0x0000d800, 0x00003100, 0x00001500, - 0x00000400, 0x0000c700, 0x00002300, 0x0000c300, - 0x00001800, 0x00009600, 0x00000500, 0x00009a00, - 0x00000700, 0x00001200, 0x00008000, 0x0000e200, - 0x0000eb00, 0x00002700, 0x0000b200, 0x00007500, - 0x00000900, 0x00008300, 0x00002c00, 0x00001a00, - 0x00001b00, 0x00006e00, 0x00005a00, 0x0000a000, - 0x00005200, 0x00003b00, 0x0000d600, 0x0000b300, - 0x00002900, 0x0000e300, 0x00002f00, 0x00008400, - 0x00005300, 0x0000d100, 0x00000000, 0x0000ed00, - 0x00002000, 0x0000fc00, 0x0000b100, 0x00005b00, - 0x00006a00, 0x0000cb00, 0x0000be00, 0x00003900, - 0x00004a00, 0x00004c00, 0x00005800, 0x0000cf00, - 0x0000d000, 0x0000ef00, 0x0000aa00, 0x0000fb00, - 0x00004300, 0x00004d00, 0x00003300, 0x00008500, - 0x00004500, 0x0000f900, 0x00000200, 0x00007f00, - 0x00005000, 0x00003c00, 0x00009f00, 0x0000a800, - 0x00005100, 0x0000a300, 0x00004000, 0x00008f00, - 0x00009200, 0x00009d00, 0x00003800, 0x0000f500, - 0x0000bc00, 0x0000b600, 0x0000da00, 0x00002100, - 0x00001000, 0x0000ff00, 0x0000f300, 0x0000d200, - 0x0000cd00, 0x00000c00, 0x00001300, 0x0000ec00, - 0x00005f00, 0x00009700, 0x00004400, 0x00001700, - 0x0000c400, 0x0000a700, 0x00007e00, 0x00003d00, - 0x00006400, 0x00005d00, 0x00001900, 0x00007300, - 0x00006000, 0x00008100, 0x00004f00, 0x0000dc00, - 0x00002200, 0x00002a00, 0x00009000, 0x00008800, - 0x00004600, 0x0000ee00, 0x0000b800, 0x00001400, - 0x0000de00, 0x00005e00, 0x00000b00, 0x0000db00, - 0x0000e000, 0x00003200, 0x00003a00, 0x00000a00, - 0x00004900, 0x00000600, 0x00002400, 0x00005c00, - 0x0000c200, 0x0000d300, 0x0000ac00, 0x00006200, - 0x00009100, 0x00009500, 0x0000e400, 0x00007900, - 0x0000e700, 0x0000c800, 0x00003700, 0x00006d00, - 0x00008d00, 0x0000d500, 0x00004e00, 0x0000a900, - 0x00006c00, 0x00005600, 0x0000f400, 0x0000ea00, - 0x00006500, 0x00007a00, 0x0000ae00, 0x00000800, - 0x0000ba00, 0x00007800, 0x00002500, 0x00002e00, - 0x00001c00, 0x0000a600, 0x0000b400, 0x0000c600, - 0x0000e800, 0x0000dd00, 0x00007400, 0x00001f00, - 0x00004b00, 0x0000bd00, 0x00008b00, 0x00008a00, - 0x00007000, 0x00003e00, 0x0000b500, 0x00006600, - 0x00004800, 0x00000300, 0x0000f600, 0x00000e00, - 0x00006100, 0x00003500, 0x00005700, 0x0000b900, - 0x00008600, 0x0000c100, 0x00001d00, 0x00009e00, - 0x0000e100, 0x0000f800, 0x00009800, 0x00001100, - 0x00006900, 0x0000d900, 0x00008e00, 0x00009400, - 0x00009b00, 0x00001e00, 0x00008700, 0x0000e900, - 0x0000ce00, 0x00005500, 0x00002800, 0x0000df00, - 0x00008c00, 0x0000a100, 0x00008900, 0x00000d00, - 0x0000bf00, 0x0000e600, 0x00004200, 0x00006800, - 0x00004100, 0x00009900, 0x00002d00, 0x00000f00, - 0x0000b000, 0x00005400, 0x0000bb00, 0x00001600 -}, { - 0x00630000, 0x007c0000, 0x00770000, 0x007b0000, - 0x00f20000, 0x006b0000, 0x006f0000, 0x00c50000, - 0x00300000, 0x00010000, 0x00670000, 0x002b0000, - 0x00fe0000, 0x00d70000, 0x00ab0000, 0x00760000, - 0x00ca0000, 0x00820000, 0x00c90000, 0x007d0000, - 0x00fa0000, 0x00590000, 0x00470000, 0x00f00000, - 0x00ad0000, 0x00d40000, 0x00a20000, 0x00af0000, - 0x009c0000, 0x00a40000, 0x00720000, 0x00c00000, - 0x00b70000, 0x00fd0000, 0x00930000, 0x00260000, - 0x00360000, 0x003f0000, 0x00f70000, 0x00cc0000, - 0x00340000, 0x00a50000, 0x00e50000, 0x00f10000, - 0x00710000, 0x00d80000, 0x00310000, 0x00150000, - 0x00040000, 0x00c70000, 0x00230000, 0x00c30000, - 0x00180000, 0x00960000, 0x00050000, 0x009a0000, - 0x00070000, 0x00120000, 0x00800000, 0x00e20000, - 0x00eb0000, 0x00270000, 0x00b20000, 0x00750000, - 0x00090000, 0x00830000, 0x002c0000, 0x001a0000, - 0x001b0000, 0x006e0000, 0x005a0000, 0x00a00000, - 0x00520000, 0x003b0000, 0x00d60000, 0x00b30000, - 0x00290000, 0x00e30000, 0x002f0000, 0x00840000, - 0x00530000, 0x00d10000, 0x00000000, 0x00ed0000, - 0x00200000, 0x00fc0000, 0x00b10000, 0x005b0000, - 0x006a0000, 0x00cb0000, 0x00be0000, 0x00390000, - 0x004a0000, 0x004c0000, 0x00580000, 0x00cf0000, - 0x00d00000, 0x00ef0000, 0x00aa0000, 0x00fb0000, - 0x00430000, 0x004d0000, 0x00330000, 0x00850000, - 0x00450000, 0x00f90000, 0x00020000, 0x007f0000, - 0x00500000, 0x003c0000, 0x009f0000, 0x00a80000, - 0x00510000, 0x00a30000, 0x00400000, 0x008f0000, - 0x00920000, 0x009d0000, 0x00380000, 0x00f50000, - 0x00bc0000, 0x00b60000, 0x00da0000, 0x00210000, - 0x00100000, 0x00ff0000, 0x00f30000, 0x00d20000, - 0x00cd0000, 0x000c0000, 0x00130000, 0x00ec0000, - 0x005f0000, 0x00970000, 0x00440000, 0x00170000, - 0x00c40000, 0x00a70000, 0x007e0000, 0x003d0000, - 0x00640000, 0x005d0000, 0x00190000, 0x00730000, - 0x00600000, 0x00810000, 0x004f0000, 0x00dc0000, - 0x00220000, 0x002a0000, 0x00900000, 0x00880000, - 0x00460000, 0x00ee0000, 0x00b80000, 0x00140000, - 0x00de0000, 0x005e0000, 0x000b0000, 0x00db0000, - 0x00e00000, 0x00320000, 0x003a0000, 0x000a0000, - 0x00490000, 0x00060000, 0x00240000, 0x005c0000, - 0x00c20000, 0x00d30000, 0x00ac0000, 0x00620000, - 0x00910000, 0x00950000, 0x00e40000, 0x00790000, - 0x00e70000, 0x00c80000, 0x00370000, 0x006d0000, - 0x008d0000, 0x00d50000, 0x004e0000, 0x00a90000, - 0x006c0000, 0x00560000, 0x00f40000, 0x00ea0000, - 0x00650000, 0x007a0000, 0x00ae0000, 0x00080000, - 0x00ba0000, 0x00780000, 0x00250000, 0x002e0000, - 0x001c0000, 0x00a60000, 0x00b40000, 0x00c60000, - 0x00e80000, 0x00dd0000, 0x00740000, 0x001f0000, - 0x004b0000, 0x00bd0000, 0x008b0000, 0x008a0000, - 0x00700000, 0x003e0000, 0x00b50000, 0x00660000, - 0x00480000, 0x00030000, 0x00f60000, 0x000e0000, - 0x00610000, 0x00350000, 0x00570000, 0x00b90000, - 0x00860000, 0x00c10000, 0x001d0000, 0x009e0000, - 0x00e10000, 0x00f80000, 0x00980000, 0x00110000, - 0x00690000, 0x00d90000, 0x008e0000, 0x00940000, - 0x009b0000, 0x001e0000, 0x00870000, 0x00e90000, - 0x00ce0000, 0x00550000, 0x00280000, 0x00df0000, - 0x008c0000, 0x00a10000, 0x00890000, 0x000d0000, - 0x00bf0000, 0x00e60000, 0x00420000, 0x00680000, - 0x00410000, 0x00990000, 0x002d0000, 0x000f0000, - 0x00b00000, 0x00540000, 0x00bb0000, 0x00160000 -}, { - 0x63000000, 0x7c000000, 0x77000000, 0x7b000000, - 0xf2000000, 0x6b000000, 0x6f000000, 0xc5000000, - 0x30000000, 0x01000000, 0x67000000, 0x2b000000, - 0xfe000000, 0xd7000000, 0xab000000, 0x76000000, - 0xca000000, 0x82000000, 0xc9000000, 0x7d000000, - 0xfa000000, 0x59000000, 0x47000000, 0xf0000000, - 0xad000000, 0xd4000000, 0xa2000000, 0xaf000000, - 0x9c000000, 0xa4000000, 0x72000000, 0xc0000000, - 0xb7000000, 0xfd000000, 0x93000000, 0x26000000, - 0x36000000, 0x3f000000, 0xf7000000, 0xcc000000, - 0x34000000, 0xa5000000, 0xe5000000, 0xf1000000, - 0x71000000, 0xd8000000, 0x31000000, 0x15000000, - 0x04000000, 0xc7000000, 0x23000000, 0xc3000000, - 0x18000000, 0x96000000, 0x05000000, 0x9a000000, - 0x07000000, 0x12000000, 0x80000000, 0xe2000000, - 0xeb000000, 0x27000000, 0xb2000000, 0x75000000, - 0x09000000, 0x83000000, 0x2c000000, 0x1a000000, - 0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000, - 0x52000000, 0x3b000000, 0xd6000000, 0xb3000000, - 0x29000000, 0xe3000000, 0x2f000000, 0x84000000, - 0x53000000, 0xd1000000, 0x00000000, 0xed000000, - 0x20000000, 0xfc000000, 0xb1000000, 0x5b000000, - 0x6a000000, 0xcb000000, 0xbe000000, 0x39000000, - 0x4a000000, 0x4c000000, 0x58000000, 0xcf000000, - 0xd0000000, 0xef000000, 0xaa000000, 0xfb000000, - 0x43000000, 0x4d000000, 0x33000000, 0x85000000, - 0x45000000, 0xf9000000, 0x02000000, 0x7f000000, - 0x50000000, 0x3c000000, 0x9f000000, 0xa8000000, - 0x51000000, 0xa3000000, 0x40000000, 0x8f000000, - 0x92000000, 0x9d000000, 0x38000000, 0xf5000000, - 0xbc000000, 0xb6000000, 0xda000000, 0x21000000, - 0x10000000, 0xff000000, 0xf3000000, 0xd2000000, - 0xcd000000, 0x0c000000, 0x13000000, 0xec000000, - 0x5f000000, 0x97000000, 0x44000000, 0x17000000, - 0xc4000000, 0xa7000000, 0x7e000000, 0x3d000000, - 0x64000000, 0x5d000000, 0x19000000, 0x73000000, - 0x60000000, 0x81000000, 0x4f000000, 0xdc000000, - 0x22000000, 0x2a000000, 0x90000000, 0x88000000, - 0x46000000, 0xee000000, 0xb8000000, 0x14000000, - 0xde000000, 0x5e000000, 0x0b000000, 0xdb000000, - 0xe0000000, 0x32000000, 0x3a000000, 0x0a000000, - 0x49000000, 0x06000000, 0x24000000, 0x5c000000, - 0xc2000000, 0xd3000000, 0xac000000, 0x62000000, - 0x91000000, 0x95000000, 0xe4000000, 0x79000000, - 0xe7000000, 0xc8000000, 0x37000000, 0x6d000000, - 0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000, - 0x6c000000, 0x56000000, 0xf4000000, 0xea000000, - 0x65000000, 0x7a000000, 0xae000000, 0x08000000, - 0xba000000, 0x78000000, 0x25000000, 0x2e000000, - 0x1c000000, 0xa6000000, 0xb4000000, 0xc6000000, - 0xe8000000, 0xdd000000, 0x74000000, 0x1f000000, - 0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000, - 0x70000000, 0x3e000000, 0xb5000000, 0x66000000, - 0x48000000, 0x03000000, 0xf6000000, 0x0e000000, - 0x61000000, 0x35000000, 0x57000000, 0xb9000000, - 0x86000000, 0xc1000000, 0x1d000000, 0x9e000000, - 0xe1000000, 0xf8000000, 0x98000000, 0x11000000, - 0x69000000, 0xd9000000, 0x8e000000, 0x94000000, - 0x9b000000, 0x1e000000, 0x87000000, 0xe9000000, - 0xce000000, 0x55000000, 0x28000000, 0xdf000000, - 0x8c000000, 0xa1000000, 0x89000000, 0x0d000000, - 0xbf000000, 0xe6000000, 0x42000000, 0x68000000, - 0x41000000, 0x99000000, 0x2d000000, 0x0f000000, - 0xb0000000, 0x54000000, 0xbb000000, 0x16000000 -} -}; - -static const u4byte il_tab[4][256] = { -{ - 0x00000052, 0x00000009, 0x0000006a, 0x000000d5, - 0x00000030, 0x00000036, 0x000000a5, 0x00000038, - 0x000000bf, 0x00000040, 0x000000a3, 0x0000009e, - 0x00000081, 0x000000f3, 0x000000d7, 0x000000fb, - 0x0000007c, 0x000000e3, 0x00000039, 0x00000082, - 0x0000009b, 0x0000002f, 0x000000ff, 0x00000087, - 0x00000034, 0x0000008e, 0x00000043, 0x00000044, - 0x000000c4, 0x000000de, 0x000000e9, 0x000000cb, - 0x00000054, 0x0000007b, 0x00000094, 0x00000032, - 0x000000a6, 0x000000c2, 0x00000023, 0x0000003d, - 0x000000ee, 0x0000004c, 0x00000095, 0x0000000b, - 0x00000042, 0x000000fa, 0x000000c3, 0x0000004e, - 0x00000008, 0x0000002e, 0x000000a1, 0x00000066, - 0x00000028, 0x000000d9, 0x00000024, 0x000000b2, - 0x00000076, 0x0000005b, 0x000000a2, 0x00000049, - 0x0000006d, 0x0000008b, 0x000000d1, 0x00000025, - 0x00000072, 0x000000f8, 0x000000f6, 0x00000064, - 0x00000086, 0x00000068, 0x00000098, 0x00000016, - 0x000000d4, 0x000000a4, 0x0000005c, 0x000000cc, - 0x0000005d, 0x00000065, 0x000000b6, 0x00000092, - 0x0000006c, 0x00000070, 0x00000048, 0x00000050, - 0x000000fd, 0x000000ed, 0x000000b9, 0x000000da, - 0x0000005e, 0x00000015, 0x00000046, 0x00000057, - 0x000000a7, 0x0000008d, 0x0000009d, 0x00000084, - 0x00000090, 0x000000d8, 0x000000ab, 0x00000000, - 0x0000008c, 0x000000bc, 0x000000d3, 0x0000000a, - 0x000000f7, 0x000000e4, 0x00000058, 0x00000005, - 0x000000b8, 0x000000b3, 0x00000045, 0x00000006, - 0x000000d0, 0x0000002c, 0x0000001e, 0x0000008f, - 0x000000ca, 0x0000003f, 0x0000000f, 0x00000002, - 0x000000c1, 0x000000af, 0x000000bd, 0x00000003, - 0x00000001, 0x00000013, 0x0000008a, 0x0000006b, - 0x0000003a, 0x00000091, 0x00000011, 0x00000041, - 0x0000004f, 0x00000067, 0x000000dc, 0x000000ea, - 0x00000097, 0x000000f2, 0x000000cf, 0x000000ce, - 0x000000f0, 0x000000b4, 0x000000e6, 0x00000073, - 0x00000096, 0x000000ac, 0x00000074, 0x00000022, - 0x000000e7, 0x000000ad, 0x00000035, 0x00000085, - 0x000000e2, 0x000000f9, 0x00000037, 0x000000e8, - 0x0000001c, 0x00000075, 0x000000df, 0x0000006e, - 0x00000047, 0x000000f1, 0x0000001a, 0x00000071, - 0x0000001d, 0x00000029, 0x000000c5, 0x00000089, - 0x0000006f, 0x000000b7, 0x00000062, 0x0000000e, - 0x000000aa, 0x00000018, 0x000000be, 0x0000001b, - 0x000000fc, 0x00000056, 0x0000003e, 0x0000004b, - 0x000000c6, 0x000000d2, 0x00000079, 0x00000020, - 0x0000009a, 0x000000db, 0x000000c0, 0x000000fe, - 0x00000078, 0x000000cd, 0x0000005a, 0x000000f4, - 0x0000001f, 0x000000dd, 0x000000a8, 0x00000033, - 0x00000088, 0x00000007, 0x000000c7, 0x00000031, - 0x000000b1, 0x00000012, 0x00000010, 0x00000059, - 0x00000027, 0x00000080, 0x000000ec, 0x0000005f, - 0x00000060, 0x00000051, 0x0000007f, 0x000000a9, - 0x00000019, 0x000000b5, 0x0000004a, 0x0000000d, - 0x0000002d, 0x000000e5, 0x0000007a, 0x0000009f, - 0x00000093, 0x000000c9, 0x0000009c, 0x000000ef, - 0x000000a0, 0x000000e0, 0x0000003b, 0x0000004d, - 0x000000ae, 0x0000002a, 0x000000f5, 0x000000b0, - 0x000000c8, 0x000000eb, 0x000000bb, 0x0000003c, - 0x00000083, 0x00000053, 0x00000099, 0x00000061, - 0x00000017, 0x0000002b, 0x00000004, 0x0000007e, - 0x000000ba, 0x00000077, 0x000000d6, 0x00000026, - 0x000000e1, 0x00000069, 0x00000014, 0x00000063, - 0x00000055, 0x00000021, 0x0000000c, 0x0000007d -}, { - 0x00005200, 0x00000900, 0x00006a00, 0x0000d500, - 0x00003000, 0x00003600, 0x0000a500, 0x00003800, - 0x0000bf00, 0x00004000, 0x0000a300, 0x00009e00, - 0x00008100, 0x0000f300, 0x0000d700, 0x0000fb00, - 0x00007c00, 0x0000e300, 0x00003900, 0x00008200, - 0x00009b00, 0x00002f00, 0x0000ff00, 0x00008700, - 0x00003400, 0x00008e00, 0x00004300, 0x00004400, - 0x0000c400, 0x0000de00, 0x0000e900, 0x0000cb00, - 0x00005400, 0x00007b00, 0x00009400, 0x00003200, - 0x0000a600, 0x0000c200, 0x00002300, 0x00003d00, - 0x0000ee00, 0x00004c00, 0x00009500, 0x00000b00, - 0x00004200, 0x0000fa00, 0x0000c300, 0x00004e00, - 0x00000800, 0x00002e00, 0x0000a100, 0x00006600, - 0x00002800, 0x0000d900, 0x00002400, 0x0000b200, - 0x00007600, 0x00005b00, 0x0000a200, 0x00004900, - 0x00006d00, 0x00008b00, 0x0000d100, 0x00002500, - 0x00007200, 0x0000f800, 0x0000f600, 0x00006400, - 0x00008600, 0x00006800, 0x00009800, 0x00001600, - 0x0000d400, 0x0000a400, 0x00005c00, 0x0000cc00, - 0x00005d00, 0x00006500, 0x0000b600, 0x00009200, - 0x00006c00, 0x00007000, 0x00004800, 0x00005000, - 0x0000fd00, 0x0000ed00, 0x0000b900, 0x0000da00, - 0x00005e00, 0x00001500, 0x00004600, 0x00005700, - 0x0000a700, 0x00008d00, 0x00009d00, 0x00008400, - 0x00009000, 0x0000d800, 0x0000ab00, 0x00000000, - 0x00008c00, 0x0000bc00, 0x0000d300, 0x00000a00, - 0x0000f700, 0x0000e400, 0x00005800, 0x00000500, - 0x0000b800, 0x0000b300, 0x00004500, 0x00000600, - 0x0000d000, 0x00002c00, 0x00001e00, 0x00008f00, - 0x0000ca00, 0x00003f00, 0x00000f00, 0x00000200, - 0x0000c100, 0x0000af00, 0x0000bd00, 0x00000300, - 0x00000100, 0x00001300, 0x00008a00, 0x00006b00, - 0x00003a00, 0x00009100, 0x00001100, 0x00004100, - 0x00004f00, 0x00006700, 0x0000dc00, 0x0000ea00, - 0x00009700, 0x0000f200, 0x0000cf00, 0x0000ce00, - 0x0000f000, 0x0000b400, 0x0000e600, 0x00007300, - 0x00009600, 0x0000ac00, 0x00007400, 0x00002200, - 0x0000e700, 0x0000ad00, 0x00003500, 0x00008500, - 0x0000e200, 0x0000f900, 0x00003700, 0x0000e800, - 0x00001c00, 0x00007500, 0x0000df00, 0x00006e00, - 0x00004700, 0x0000f100, 0x00001a00, 0x00007100, - 0x00001d00, 0x00002900, 0x0000c500, 0x00008900, - 0x00006f00, 0x0000b700, 0x00006200, 0x00000e00, - 0x0000aa00, 0x00001800, 0x0000be00, 0x00001b00, - 0x0000fc00, 0x00005600, 0x00003e00, 0x00004b00, - 0x0000c600, 0x0000d200, 0x00007900, 0x00002000, - 0x00009a00, 0x0000db00, 0x0000c000, 0x0000fe00, - 0x00007800, 0x0000cd00, 0x00005a00, 0x0000f400, - 0x00001f00, 0x0000dd00, 0x0000a800, 0x00003300, - 0x00008800, 0x00000700, 0x0000c700, 0x00003100, - 0x0000b100, 0x00001200, 0x00001000, 0x00005900, - 0x00002700, 0x00008000, 0x0000ec00, 0x00005f00, - 0x00006000, 0x00005100, 0x00007f00, 0x0000a900, - 0x00001900, 0x0000b500, 0x00004a00, 0x00000d00, - 0x00002d00, 0x0000e500, 0x00007a00, 0x00009f00, - 0x00009300, 0x0000c900, 0x00009c00, 0x0000ef00, - 0x0000a000, 0x0000e000, 0x00003b00, 0x00004d00, - 0x0000ae00, 0x00002a00, 0x0000f500, 0x0000b000, - 0x0000c800, 0x0000eb00, 0x0000bb00, 0x00003c00, - 0x00008300, 0x00005300, 0x00009900, 0x00006100, - 0x00001700, 0x00002b00, 0x00000400, 0x00007e00, - 0x0000ba00, 0x00007700, 0x0000d600, 0x00002600, - 0x0000e100, 0x00006900, 0x00001400, 0x00006300, - 0x00005500, 0x00002100, 0x00000c00, 0x00007d00 -}, { - 0x00520000, 0x00090000, 0x006a0000, 0x00d50000, - 0x00300000, 0x00360000, 0x00a50000, 0x00380000, - 0x00bf0000, 0x00400000, 0x00a30000, 0x009e0000, - 0x00810000, 0x00f30000, 0x00d70000, 0x00fb0000, - 0x007c0000, 0x00e30000, 0x00390000, 0x00820000, - 0x009b0000, 0x002f0000, 0x00ff0000, 0x00870000, - 0x00340000, 0x008e0000, 0x00430000, 0x00440000, - 0x00c40000, 0x00de0000, 0x00e90000, 0x00cb0000, - 0x00540000, 0x007b0000, 0x00940000, 0x00320000, - 0x00a60000, 0x00c20000, 0x00230000, 0x003d0000, - 0x00ee0000, 0x004c0000, 0x00950000, 0x000b0000, - 0x00420000, 0x00fa0000, 0x00c30000, 0x004e0000, - 0x00080000, 0x002e0000, 0x00a10000, 0x00660000, - 0x00280000, 0x00d90000, 0x00240000, 0x00b20000, - 0x00760000, 0x005b0000, 0x00a20000, 0x00490000, - 0x006d0000, 0x008b0000, 0x00d10000, 0x00250000, - 0x00720000, 0x00f80000, 0x00f60000, 0x00640000, - 0x00860000, 0x00680000, 0x00980000, 0x00160000, - 0x00d40000, 0x00a40000, 0x005c0000, 0x00cc0000, - 0x005d0000, 0x00650000, 0x00b60000, 0x00920000, - 0x006c0000, 0x00700000, 0x00480000, 0x00500000, - 0x00fd0000, 0x00ed0000, 0x00b90000, 0x00da0000, - 0x005e0000, 0x00150000, 0x00460000, 0x00570000, - 0x00a70000, 0x008d0000, 0x009d0000, 0x00840000, - 0x00900000, 0x00d80000, 0x00ab0000, 0x00000000, - 0x008c0000, 0x00bc0000, 0x00d30000, 0x000a0000, - 0x00f70000, 0x00e40000, 0x00580000, 0x00050000, - 0x00b80000, 0x00b30000, 0x00450000, 0x00060000, - 0x00d00000, 0x002c0000, 0x001e0000, 0x008f0000, - 0x00ca0000, 0x003f0000, 0x000f0000, 0x00020000, - 0x00c10000, 0x00af0000, 0x00bd0000, 0x00030000, - 0x00010000, 0x00130000, 0x008a0000, 0x006b0000, - 0x003a0000, 0x00910000, 0x00110000, 0x00410000, - 0x004f0000, 0x00670000, 0x00dc0000, 0x00ea0000, - 0x00970000, 0x00f20000, 0x00cf0000, 0x00ce0000, - 0x00f00000, 0x00b40000, 0x00e60000, 0x00730000, - 0x00960000, 0x00ac0000, 0x00740000, 0x00220000, - 0x00e70000, 0x00ad0000, 0x00350000, 0x00850000, - 0x00e20000, 0x00f90000, 0x00370000, 0x00e80000, - 0x001c0000, 0x00750000, 0x00df0000, 0x006e0000, - 0x00470000, 0x00f10000, 0x001a0000, 0x00710000, - 0x001d0000, 0x00290000, 0x00c50000, 0x00890000, - 0x006f0000, 0x00b70000, 0x00620000, 0x000e0000, - 0x00aa0000, 0x00180000, 0x00be0000, 0x001b0000, - 0x00fc0000, 0x00560000, 0x003e0000, 0x004b0000, - 0x00c60000, 0x00d20000, 0x00790000, 0x00200000, - 0x009a0000, 0x00db0000, 0x00c00000, 0x00fe0000, - 0x00780000, 0x00cd0000, 0x005a0000, 0x00f40000, - 0x001f0000, 0x00dd0000, 0x00a80000, 0x00330000, - 0x00880000, 0x00070000, 0x00c70000, 0x00310000, - 0x00b10000, 0x00120000, 0x00100000, 0x00590000, - 0x00270000, 0x00800000, 0x00ec0000, 0x005f0000, - 0x00600000, 0x00510000, 0x007f0000, 0x00a90000, - 0x00190000, 0x00b50000, 0x004a0000, 0x000d0000, - 0x002d0000, 0x00e50000, 0x007a0000, 0x009f0000, - 0x00930000, 0x00c90000, 0x009c0000, 0x00ef0000, - 0x00a00000, 0x00e00000, 0x003b0000, 0x004d0000, - 0x00ae0000, 0x002a0000, 0x00f50000, 0x00b00000, - 0x00c80000, 0x00eb0000, 0x00bb0000, 0x003c0000, - 0x00830000, 0x00530000, 0x00990000, 0x00610000, - 0x00170000, 0x002b0000, 0x00040000, 0x007e0000, - 0x00ba0000, 0x00770000, 0x00d60000, 0x00260000, - 0x00e10000, 0x00690000, 0x00140000, 0x00630000, - 0x00550000, 0x00210000, 0x000c0000, 0x007d0000 -}, { - 0x52000000, 0x09000000, 0x6a000000, 0xd5000000, - 0x30000000, 0x36000000, 0xa5000000, 0x38000000, - 0xbf000000, 0x40000000, 0xa3000000, 0x9e000000, - 0x81000000, 0xf3000000, 0xd7000000, 0xfb000000, - 0x7c000000, 0xe3000000, 0x39000000, 0x82000000, - 0x9b000000, 0x2f000000, 0xff000000, 0x87000000, - 0x34000000, 0x8e000000, 0x43000000, 0x44000000, - 0xc4000000, 0xde000000, 0xe9000000, 0xcb000000, - 0x54000000, 0x7b000000, 0x94000000, 0x32000000, - 0xa6000000, 0xc2000000, 0x23000000, 0x3d000000, - 0xee000000, 0x4c000000, 0x95000000, 0x0b000000, - 0x42000000, 0xfa000000, 0xc3000000, 0x4e000000, - 0x08000000, 0x2e000000, 0xa1000000, 0x66000000, - 0x28000000, 0xd9000000, 0x24000000, 0xb2000000, - 0x76000000, 0x5b000000, 0xa2000000, 0x49000000, - 0x6d000000, 0x8b000000, 0xd1000000, 0x25000000, - 0x72000000, 0xf8000000, 0xf6000000, 0x64000000, - 0x86000000, 0x68000000, 0x98000000, 0x16000000, - 0xd4000000, 0xa4000000, 0x5c000000, 0xcc000000, - 0x5d000000, 0x65000000, 0xb6000000, 0x92000000, - 0x6c000000, 0x70000000, 0x48000000, 0x50000000, - 0xfd000000, 0xed000000, 0xb9000000, 0xda000000, - 0x5e000000, 0x15000000, 0x46000000, 0x57000000, - 0xa7000000, 0x8d000000, 0x9d000000, 0x84000000, - 0x90000000, 0xd8000000, 0xab000000, 0x00000000, - 0x8c000000, 0xbc000000, 0xd3000000, 0x0a000000, - 0xf7000000, 0xe4000000, 0x58000000, 0x05000000, - 0xb8000000, 0xb3000000, 0x45000000, 0x06000000, - 0xd0000000, 0x2c000000, 0x1e000000, 0x8f000000, - 0xca000000, 0x3f000000, 0x0f000000, 0x02000000, - 0xc1000000, 0xaf000000, 0xbd000000, 0x03000000, - 0x01000000, 0x13000000, 0x8a000000, 0x6b000000, - 0x3a000000, 0x91000000, 0x11000000, 0x41000000, - 0x4f000000, 0x67000000, 0xdc000000, 0xea000000, - 0x97000000, 0xf2000000, 0xcf000000, 0xce000000, - 0xf0000000, 0xb4000000, 0xe6000000, 0x73000000, - 0x96000000, 0xac000000, 0x74000000, 0x22000000, - 0xe7000000, 0xad000000, 0x35000000, 0x85000000, - 0xe2000000, 0xf9000000, 0x37000000, 0xe8000000, - 0x1c000000, 0x75000000, 0xdf000000, 0x6e000000, - 0x47000000, 0xf1000000, 0x1a000000, 0x71000000, - 0x1d000000, 0x29000000, 0xc5000000, 0x89000000, - 0x6f000000, 0xb7000000, 0x62000000, 0x0e000000, - 0xaa000000, 0x18000000, 0xbe000000, 0x1b000000, - 0xfc000000, 0x56000000, 0x3e000000, 0x4b000000, - 0xc6000000, 0xd2000000, 0x79000000, 0x20000000, - 0x9a000000, 0xdb000000, 0xc0000000, 0xfe000000, - 0x78000000, 0xcd000000, 0x5a000000, 0xf4000000, - 0x1f000000, 0xdd000000, 0xa8000000, 0x33000000, - 0x88000000, 0x07000000, 0xc7000000, 0x31000000, - 0xb1000000, 0x12000000, 0x10000000, 0x59000000, - 0x27000000, 0x80000000, 0xec000000, 0x5f000000, - 0x60000000, 0x51000000, 0x7f000000, 0xa9000000, - 0x19000000, 0xb5000000, 0x4a000000, 0x0d000000, - 0x2d000000, 0xe5000000, 0x7a000000, 0x9f000000, - 0x93000000, 0xc9000000, 0x9c000000, 0xef000000, - 0xa0000000, 0xe0000000, 0x3b000000, 0x4d000000, - 0xae000000, 0x2a000000, 0xf5000000, 0xb0000000, - 0xc8000000, 0xeb000000, 0xbb000000, 0x3c000000, - 0x83000000, 0x53000000, 0x99000000, 0x61000000, - 0x17000000, 0x2b000000, 0x04000000, 0x7e000000, - 0xba000000, 0x77000000, 0xd6000000, 0x26000000, - 0xe1000000, 0x69000000, 0x14000000, 0x63000000, - 0x55000000, 0x21000000, 0x0c000000, 0x7d000000 -} -}; - -static const u4byte rco_tab[10] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, - 0x00000020, 0x00000040, 0x00000080, 0x0000001b, 0x00000036 -}; diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml index 648703cbc71..79759654a78 100644 --- a/doc/src/sgml/pgcrypto.sgml +++ b/doc/src/sgml/pgcrypto.sgml @@ -23,6 +23,11 @@ on the current database. </para> + <para> + <filename>pgcrypto</filename> requires OpenSSL and won't be installed if + OpenSSL support was not selected when PostgreSQL was built. + </para> + <sect2> <title>General Hashing Functions</title> @@ -44,9 +49,8 @@ digest(data bytea, type text) returns bytea Standard algorithms are <literal>md5</literal>, <literal>sha1</literal>, <literal>sha224</literal>, <literal>sha256</literal>, <literal>sha384</literal> and <literal>sha512</literal>. - If <filename>pgcrypto</filename> was built with - <productname>OpenSSL</productname>, more algorithms are available, as - detailed in <xref linkend="pgcrypto-with-without-openssl"/>. + Moreover, any digest algorithm <productname>OpenSSL</productname> supports + is automatically picked up. </para> <para> @@ -764,7 +768,7 @@ pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256') Which cipher algorithm to use. </para> <literallayout> -Values: bf, aes128, aes192, aes256 (OpenSSL-only: <literal>3des</literal>, <literal>cast5</literal>) +Values: bf, aes128, aes192, aes256, 3des, cast5 Default: aes128 Applies to: pgp_sym_encrypt, pgp_pub_encrypt </literallayout> @@ -1163,98 +1167,16 @@ gen_random_uuid() returns uuid </para> <para> - When compiled with <productname>OpenSSL</productname>, there will be - more algorithms available. Also public-key encryption functions will - be faster as <productname>OpenSSL</productname> has more optimized - BIGNUM functions. + <filename>pgcrypto</filename> requires <productname>OpenSSL</productname>. + Otherwise, it will not be built or installed. </para> - <table id="pgcrypto-with-without-openssl"> - <title>Summary of Functionality with and without OpenSSL</title> - <tgroup cols="3"> - <thead> - <row> - <entry>Functionality</entry> - <entry>Built-in</entry> - <entry>With OpenSSL</entry> - </row> - </thead> - <tbody> - <row> - <entry>MD5</entry> - <entry>yes</entry> - <entry>yes</entry> - </row> - <row> - <entry>SHA1</entry> - <entry>yes</entry> - <entry>yes</entry> - </row> - <row> - <entry>SHA224/256/384/512</entry> - <entry>yes</entry> - <entry>yes</entry> - </row> - <row> - <entry>Other digest algorithms</entry> - <entry>no</entry> - <entry>yes (Note 1)</entry> - </row> - <row> - <entry>Blowfish</entry> - <entry>yes</entry> - <entry>yes</entry> - </row> - <row> - <entry>AES</entry> - <entry>yes</entry> - <entry>yes</entry> - </row> - <row> - <entry>DES/3DES/CAST5</entry> - <entry>no</entry> - <entry>yes</entry> - </row> - <row> - <entry>Raw encryption</entry> - <entry>yes</entry> - <entry>yes</entry> - </row> - <row> - <entry>PGP Symmetric encryption</entry> - <entry>yes</entry> - <entry>yes</entry> - </row> - <row> - <entry>PGP Public-Key encryption</entry> - <entry>yes</entry> - <entry>yes</entry> - </row> - </tbody> - </tgroup> - </table> - <para> When compiled against <productname>OpenSSL</productname> 3.0.0 and later versions, the legacy provider must be activated in the <filename>openssl.cnf</filename> configuration file in order to use older ciphers like DES or Blowfish. </para> - - <para> - Notes: - </para> - - <orderedlist> - <listitem> - <para> - Any digest algorithm <productname>OpenSSL</productname> supports - is automatically picked up. - This is not possible with ciphers, which need to be supported - explicitly. - </para> - </listitem> - </orderedlist> </sect3> <sect3> @@ -1401,21 +1323,6 @@ gen_random_uuid() returns uuid <entry>Solar Designer</entry> <entry>www.openwall.com</entry> </row> - <row> - <entry>Blowfish cipher</entry> - <entry>Simon Tatham</entry> - <entry>PuTTY</entry> - </row> - <row> - <entry>Rijndael cipher</entry> - <entry>Brian Gladman</entry> - <entry>OpenBSD sys/crypto</entry> - </row> - <row> - <entry>BIGNUM math</entry> - <entry>Michael J. Fromberger</entry> - <entry>dartmouth.edu/~sting/sw/imath</entry> - </row> </tbody> </tgroup> </informaltable> diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index 4362bd44fd1..856fb7a2cc5 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -440,7 +440,7 @@ sub mkvcbuild if (!$solution->{options}->{openssl}) { - push @contrib_excludes, 'sslinfo', 'ssl_passphrase_callback'; + push @contrib_excludes, 'sslinfo', 'ssl_passphrase_callback', 'pgcrypto'; } if (!$solution->{options}->{uuid}) @@ -448,41 +448,6 @@ sub mkvcbuild push @contrib_excludes, 'uuid-ossp'; } - # AddProject() does not recognize the constructs used to populate OBJS in - # the pgcrypto Makefile, so it will discover no files. - my $pgcrypto = - $solution->AddProject('pgcrypto', 'dll', 'crypto', 'contrib/pgcrypto'); - $pgcrypto->AddFiles( - 'contrib/pgcrypto', 'pgcrypto.c', - 'px.c', 'px-hmac.c', - 'px-crypt.c', 'crypt-gensalt.c', - 'crypt-blowfish.c', 'crypt-des.c', - 'crypt-md5.c', 'mbuf.c', - 'pgp.c', 'pgp-armor.c', - 'pgp-cfb.c', 'pgp-compress.c', - 'pgp-decrypt.c', 'pgp-encrypt.c', - 'pgp-info.c', 'pgp-mpi.c', - 'pgp-pubdec.c', 'pgp-pubenc.c', - 'pgp-pubkey.c', 'pgp-s2k.c', - 'pgp-pgsql.c'); - if ($solution->{options}->{openssl}) - { - $pgcrypto->AddFiles('contrib/pgcrypto', 'openssl.c', - 'pgp-mpi-openssl.c'); - } - else - { - $pgcrypto->AddFiles( - 'contrib/pgcrypto', 'internal.c', - 'internal-sha2.c', 'blf.c', - 'rijndael.c', 'pgp-mpi-internal.c', - 'imath.c'); - } - $pgcrypto->AddReference($postgres); - $pgcrypto->AddLibrary('ws2_32.lib'); - my $mf = Project::read_file('contrib/pgcrypto/Makefile'); - GenerateContribSqlFiles('pgcrypto', $mf); - foreach my $subdir ('contrib', 'src/test/modules') { opendir($D, $subdir) || croak "Could not opendir on $subdir!\n"; @@ -795,7 +760,7 @@ sub mkvcbuild } } - $mf = + my $mf = Project::read_file('src/backend/utils/mb/conversion_procs/Makefile'); $mf =~ s{\\\r?\n}{}g; $mf =~ m{SUBDIRS\s*=\s*(.*)$}m diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl index fc826da3ff2..f3357b32920 100644 --- a/src/tools/msvc/vcregress.pl +++ b/src/tools/msvc/vcregress.pl @@ -726,18 +726,13 @@ sub fetchTests if ($m =~ /contrib\/pgcrypto/) { - # pgcrypto is special since the tests depend on the + # pgcrypto is special since some tests depend on the # configuration of the build - my $cftests = - $config->{openssl} - ? GetTests("OSSL_TESTS", $m) - : GetTests("INT_TESTS", $m); my $pgptests = $config->{zlib} ? GetTests("ZLIB_TST", $m) : GetTests("ZLIB_OFF_TST", $m); - $t =~ s/\$\(CF_TESTS\)/$cftests/; $t =~ s/\$\(CF_PGP_TESTS\)/$pgptests/; } } |