Below is the list of changes that have just been committed into a local
5.0 repository of msvensson. When msvensson does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-05-04 16:33:53+02:00, msvensson@stripped +69 -0
Import cyassl
extra/cyassl/ctaocrypt/benchmark/benchmark.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +376 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/benchmark/benchmark.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/aes.h@stripped, 2006-04-05 03:36:57+02:00, msvensson@stripped +61 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/aes.h@stripped, 2006-04-05 03:36:57+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/arc4.h@stripped, 2006-04-05 03:36:57+02:00, msvensson@stripped +53 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/arc4.h@stripped, 2006-04-05 03:36:57+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/asn.h@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +160 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/asn.h@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/coding.h@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +44 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/coding.h@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/des3.h@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +72 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/des3.h@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/dh.h@stripped, 2006-04-05 03:36:58+02:00, msvensson@stripped +56 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/dh.h@stripped, 2006-04-05 03:36:58+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/dsa.h@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +58 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/dsa.h@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/error.h@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +87 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/error.h@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/hmac.h@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +79 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/hmac.h@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/integer.h@stripped, 2006-04-05 03:36:58+02:00, msvensson@stripped +322 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/integer.h@stripped, 2006-04-05 03:36:58+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/md5.h@stripped, 2006-04-05 03:36:58+02:00, msvensson@stripped +58 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/md5.h@stripped, 2006-04-05 03:36:58+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/mpi_class.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +996 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/mpi_class.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/mpi_superclass.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +73 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/mpi_superclass.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/random.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +69 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/random.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/rsa.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +64 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/rsa.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/sha.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +59 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/sha.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/sha256.h@stripped, 2006-12-05 20:11:18+01:00, msvensson@stripped +65 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/sha256.h@stripped, 2006-12-05 20:11:18+01:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/include/types.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +114 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/include/types.h@stripped, 2006-04-05 03:36:59+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/aes.c@stripped, 2006-04-05 03:37:00+02:00, msvensson@stripped +1138 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/aes.c@stripped, 2006-04-05 03:37:00+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/arc4.c@stripped, 2006-04-05 03:37:00+02:00, msvensson@stripped +73 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/arc4.c@stripped, 2006-04-05 03:37:00+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/asn.c@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +1106 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/asn.c@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/coding.c@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +184 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/coding.c@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/des3.c@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +491 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/des3.c@stripped, 2007-04-30 22:33:38+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/dh.c@stripped, 2006-04-05 03:37:01+02:00, msvensson@stripped +150 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/dh.c@stripped, 2006-04-05 03:37:01+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/dsa.c@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +207 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/dsa.c@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/hmac.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +154 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/hmac.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/integer.c@stripped, 2006-04-05 03:37:03+02:00, msvensson@stripped +3588 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/integer.c@stripped, 2006-04-05 03:37:03+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/md5.c@stripped, 2006-04-05 03:37:03+02:00, msvensson@stripped +207 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/md5.c@stripped, 2006-04-05 03:37:03+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/misc.c@stripped, 2006-04-05 03:37:04+02:00, msvensson@stripped +128 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/misc.c@stripped, 2006-04-05 03:37:04+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/random.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +123 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/random.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/rsa.c@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +312 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/rsa.c@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/sha.c@stripped, 2006-04-05 03:37:04+02:00, msvensson@stripped +192 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/sha.c@stripped, 2006-04-05 03:37:04+02:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/src/sha256.c@stripped, 2006-12-19 02:36:21+01:00, msvensson@stripped +191 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/src/sha256.c@stripped, 2006-12-19 02:36:21+01:00, msvensson@stripped +0 -0
extra/cyassl/ctaocrypt/test/test.c@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +907 -0
Import patch yassl.diff
extra/cyassl/ctaocrypt/test/test.c@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +0 -0
extra/cyassl/examples/client/client.c@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +154 -0
Import patch yassl.diff
extra/cyassl/examples/client/client.c@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +0 -0
extra/cyassl/examples/echoclient/echoclient.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +111 -0
Import patch yassl.diff
extra/cyassl/examples/echoclient/echoclient.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +0 -0
extra/cyassl/examples/echoclient/quit@stripped, 2006-04-05 03:37:11+02:00, msvensson@stripped +2 -0
Import patch yassl.diff
extra/cyassl/examples/echoclient/quit@stripped, 2006-04-05 03:37:11+02:00, msvensson@stripped +0 -0
extra/cyassl/examples/echoserver/echoserver.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +156 -0
Import patch yassl.diff
extra/cyassl/examples/echoserver/echoserver.c@stripped, 2006-11-23 00:33:56+01:00, msvensson@stripped +0 -0
extra/cyassl/examples/server/server.c@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +115 -0
Import patch yassl.diff
extra/cyassl/examples/server/server.c@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +0 -0
extra/cyassl/examples/test.h@stripped, 2006-10-28 01:32:46+02:00, msvensson@stripped +207 -0
Import patch yassl.diff
extra/cyassl/examples/test.h@stripped, 2006-10-28 01:32:46+02:00, msvensson@stripped +0 -0
extra/cyassl/include/cyassl_error.h@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +75 -0
Import patch yassl.diff
extra/cyassl/include/cyassl_error.h@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/cyassl_int.h@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +633 -0
Import patch yassl.diff
extra/cyassl/include/cyassl_int.h@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/crypto.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +19 -0
Import patch yassl.diff
extra/cyassl/include/openssl/crypto.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/des.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +63 -0
Import patch yassl.diff
extra/cyassl/include/openssl/des.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/err.h@stripped, 2006-04-05 03:37:09+02:00, msvensson@stripped +2 -0
Import patch yassl.diff
extra/cyassl/include/openssl/err.h@stripped, 2006-04-05 03:37:09+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/evp.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +74 -0
Import patch yassl.diff
extra/cyassl/include/openssl/evp.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/hmac.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +48 -0
Import patch yassl.diff
extra/cyassl/include/openssl/hmac.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/lhash.h@stripped, 2006-04-05 03:37:09+02:00, msvensson@stripped +2 -0
Import patch yassl.diff
extra/cyassl/include/openssl/lhash.h@stripped, 2006-04-05 03:37:09+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/md5.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +32 -0
Import patch yassl.diff
extra/cyassl/include/openssl/md5.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/opensslv.h@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +12 -0
Import patch yassl.diff
extra/cyassl/include/openssl/opensslv.h@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/prefix_crypto.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +2 -0
New BitKeeper file ``extra/cyassl/include/openssl/prefix_crypto.h''
extra/cyassl/include/openssl/prefix_crypto.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/prefix_des.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +4 -0
New BitKeeper file ``extra/cyassl/include/openssl/prefix_des.h''
extra/cyassl/include/openssl/prefix_des.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/prefix_evp.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +9 -0
New BitKeeper file ``extra/cyassl/include/openssl/prefix_evp.h''
extra/cyassl/include/openssl/prefix_evp.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/prefix_hmac.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +2 -0
New BitKeeper file ``extra/cyassl/include/openssl/prefix_hmac.h''
extra/cyassl/include/openssl/prefix_hmac.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/prefix_md5.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +3 -0
New BitKeeper file ``extra/cyassl/include/openssl/prefix_md5.h''
extra/cyassl/include/openssl/prefix_md5.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/prefix_sha.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +3 -0
New BitKeeper file ``extra/cyassl/include/openssl/prefix_sha.h''
extra/cyassl/include/openssl/prefix_sha.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/prefix_ssl.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +53 -0
New BitKeeper file ``extra/cyassl/include/openssl/prefix_ssl.h''
extra/cyassl/include/openssl/prefix_ssl.h@stripped, 2007-05-04 16:33:52+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/rand.h@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +5 -0
Import patch yassl.diff
extra/cyassl/include/openssl/rand.h@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/rsa.h@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +10 -0
Import patch yassl.diff
extra/cyassl/include/openssl/rsa.h@stripped, 2006-05-15 00:17:09+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/sha.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +32 -0
Import patch yassl.diff
extra/cyassl/include/openssl/sha.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +0 -0
extra/cyassl/include/openssl/ssl.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +199 -0
Import patch yassl.diff
extra/cyassl/include/openssl/ssl.h@stripped, 2007-05-04 16:28:39+02:00, msvensson@stripped +0 -0
extra/cyassl/src/cyassl_int.c@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +2520 -0
Import patch yassl.diff
extra/cyassl/src/cyassl_int.c@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +0 -0
extra/cyassl/src/keys.c@stripped, 2006-11-02 03:22:31+01:00, msvensson@stripped +379 -0
Import patch yassl.diff
extra/cyassl/src/keys.c@stripped, 2006-11-02 03:22:31+01:00, msvensson@stripped +0 -0
extra/cyassl/src/ssl.c@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +1063 -0
Import patch yassl.diff
extra/cyassl/src/ssl.c@stripped, 2007-04-30 22:33:39+02:00, msvensson@stripped +0 -0
extra/cyassl/src/tls.c@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +359 -0
Import patch yassl.diff
extra/cyassl/src/tls.c@stripped, 2006-12-07 22:51:51+01:00, msvensson@stripped +0 -0
extra/cyassl/testsuite/quit@stripped, 2006-04-05 03:37:13+02:00, msvensson@stripped +2 -0
Import patch yassl.diff
extra/cyassl/testsuite/quit@stripped, 2006-04-05 03:37:13+02:00, msvensson@stripped +0 -0
extra/cyassl/testsuite/testsuite.c@stripped, 2006-10-25 23:17:21+02:00, msvensson@stripped +193 -0
Import patch yassl.diff
extra/cyassl/testsuite/testsuite.c@stripped, 2006-10-25 23:17:21+02:00, msvensson@stripped +0 -0
extra/yassl/taocrypt/src/coding.cpp@stripped, 2007-05-03 19:31:49+02:00, msvensson@stripped +2 -1
Import patch yassl.diff
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: msvensson
# Host: pilot.blaudden
# Root: /home/msvensson/mysql/cyassl/tmp/my50-cyassl
--- New file ---
+++ extra/cyassl/ctaocrypt/benchmark/benchmark.c 06/11/23 00:33:56
/* benchmark.c */
/* CTaoCrypt benchmark */
#include <string.h>
#include <stdio.h>
#include "des3.h"
#include "arc4.h"
#include "aes.h"
#include "md5.h"
#include "sha.h"
#include "sha256.h"
#include "rsa.h"
#include "asn.h"
/*
#include "dh.h"
*/
#define NO_DH /* remove for now */
void bench_des();
void bench_arc4();
void bench_aes();
void bench_md5();
void bench_sha();
void bench_sha256();
void bench_rsa();
void bench_dh();
double current_time();
int main(int argc, char** argv)
{
#ifndef NO_AES
bench_aes();
#endif
bench_arc4();
#ifndef NO_DES3
bench_des();
#endif
printf("\n");
bench_md5();
bench_sha();
#ifndef NO_SHA256
bench_sha256();
#endif
printf("\n");
bench_rsa();
#ifndef NO_DH
bench_dh();
#endif
return 0;
}
const int megs = 5; /* how many megs to test (en/de)cryption */
const int times = 100; /* public key iterations */
const byte key[] =
{
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
};
const byte iv[] =
{
0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
};
byte plain [1024*1024];
byte cipher[1024*1024];
#ifndef NO_AES
void bench_aes()
{
Aes enc;
double start, total, persec;
int i;
AesSetKey(&enc, key, 24, iv, AES_ENCRYPTION);
start = current_time();
for(i = 0; i < megs; i++)
AesCbcEncrypt(&enc, plain, cipher, sizeof(plain));
total = current_time() - start;
persec = 1 / total * megs;
printf("AES %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
persec);
}
#endif
#ifndef NO_DES3
void bench_des()
{
Des3 enc;
double start, total, persec;
int i;
Des3_SetKey(&enc, key, iv, DES_ENCRYPTION);
start = current_time();
for(i = 0; i < megs; i++)
Des3_CbcEncrypt(&enc, plain, cipher, sizeof(plain));
total = current_time() - start;
persec = 1 / total * megs;
printf("3DES %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
persec);
}
#endif
void bench_arc4()
{
Arc4 enc;
double start, total, persec;
int i;
Arc4SetKey(&enc, key, 16);
start = current_time();
for(i = 0; i < megs; i++)
Arc4Process(&enc, cipher, plain, sizeof(plain));
total = current_time() - start;
persec = 1 / total * megs;
printf("ARC4 %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
persec);
}
void bench_md5()
{
Md5 hash;
byte digest[MD5_DIGEST_SIZE];
double start, total, persec;
int i;
InitMd5(&hash);
start = current_time();
for(i = 0; i < megs; i++)
Md5Update(&hash, plain, sizeof(plain));
Md5Final(&hash, digest);
total = current_time() - start;
persec = 1 / total * megs;
printf("MD5 %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
persec);
}
void bench_sha()
{
Sha hash;
byte digest[SHA_DIGEST_SIZE];
double start, total, persec;
int i;
InitSha(&hash);
start = current_time();
for(i = 0; i < megs; i++)
ShaUpdate(&hash, plain, sizeof(plain));
ShaFinal(&hash, digest);
total = current_time() - start;
persec = 1 / total * megs;
printf("SHA %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
persec);
}
#ifndef NO_SHA256
void bench_sha256()
{
Sha256 hash;
byte digest[SHA256_DIGEST_SIZE];
double start, total, persec;
int i;
InitSha256(&hash);
start = current_time();
for(i = 0; i < megs; i++)
Sha256Update(&hash, plain, sizeof(plain));
Sha256Final(&hash, digest);
total = current_time() - start;
persec = 1 / total * megs;
printf("SHA-256 %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
persec);
}
#endif
RNG rng;
void bench_rsa()
{
int i;
byte tmp[1024];
size_t bytes;
word32 idx = 0;
byte message[] = "Everyone gets Friday off.";
byte cipher[128]; /* for 1024 bit */
byte plain[128]; /* for 1024 bit */
const int len = strlen((char*)message);
double start, total, each, milliEach;
RsaKey key;
FILE* file = fopen("./rsa1024.der", "rb");
if (!file) {
printf("can't find ./rsa1024.der\n");
return;
}
bytes = fread(tmp, 1, 1024, file);
InitRsaKey(&key);
bytes = RsaPrivateKeyDecode(tmp, &idx, &key, bytes);
start = current_time();
for (i = 0; i < times; i++)
RsaPublicEncrypt(message, len, cipher, sizeof(cipher), &key, &rng);
total = current_time() - start;
each = total / times; /* per second */
milliEach = each * 1000; /* milliseconds */
printf("RSA 1024 encryption took %6.2f milliseconds, avg over %d"
" iterations\n", milliEach, times);
start = current_time();
for (i = 0; i < times; i++)
RsaPrivateDecrypt(cipher, 128, plain, sizeof(plain), &key);
total = current_time() - start;
each = total / times; /* per second */
milliEach = each * 1000; /* milliseconds */
printf("RSA 1024 decryption took %6.2f milliseconds, avg over %d"
" iterations\n", milliEach, times);
fclose(file);
FreeRsaKey(&key);
}
#ifndef NO_DH
void bench_dh()
{
int i;
byte tmp[1024];
size_t bytes;
word32 idx = 0, pubSz, privSz, pubSz2, privSz2, agreeSz;
byte pub[128]; /* for 1024 bit */
byte priv[128]; /* for 1024 bit */
byte pub2[128]; /* for 1024 bit */
byte priv2[128]; /* for 1024 bit */
byte agree[128]; /* for 1024 bit */
double start, total, each, milliEach;
DhKey key;
FILE* file = fopen("./dh1024.der", "rb");
if (!file) {
printf("can't find ./dh1024.der\n");
return;
}
bytes = fread(tmp, 1, 1024, file);
InitDhKey(&key);
bytes = DhKeyDecode(tmp, &idx, &key, bytes);
start = current_time();
for (i = 0; i < times; i++)
DhGenerateKeyPair(&key, &rng, priv, &privSz, pub, &pubSz);
total = current_time() - start;
each = total / times; /* per second */
milliEach = each * 1000; /* milliseconds */
printf("DH 1024 key generation %6.2f milliseconds, avg over %d"
" iterations\n", milliEach, times);
DhGenerateKeyPair(&key, &rng, priv2, &privSz2, pub2, &pubSz2);
start = current_time();
for (i = 0; i < times; i++)
DhAgree(&key, agree, &agreeSz, priv, privSz, pub2, pubSz2);
total = current_time() - start;
each = total / times; /* per second */
milliEach = each * 1000; /* milliseconds */
printf("DH 1024 key agreement %6.2f milliseconds, avg over %d"
" iterations\n", milliEach, times);
fclose(file);
FreeDhKey(&key);
}
#endif
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
double current_time()
{
static int init = 0;
static LARGE_INTEGER freq;
LARGE_INTEGER count;
if (!init) {
QueryPerformanceFrequency(&freq);
init = 1;
}
QueryPerformanceCounter(&count);
return (double)count.QuadPart / freq.QuadPart;
}
#else
#include <sys/time.h>
double current_time()
{
struct timeval tv;
gettimeofday(&tv, 0);
return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
}
#endif /* _WIN32 */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/aes.h 06/04/05 03:36:57
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_AES
#ifndef CTAO_CRYPT_AES_H
#define CTAO_CRYPT_AES_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
AES_ENCRYPTION = 0,
AES_DECRYPTION = 1,
AES_BLOCK_SIZE = 16
};
typedef struct Aes {
word32 rounds;
word32 key[60];
word32 reg[AES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
word32 tmp[AES_BLOCK_SIZE / sizeof(word32)]; /* same */
} Aes;
void AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv, int dir);
void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz);
void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_AES_H */
#endif /* NO_AES */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/arc4.h 06/04/05 03:36:57
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_ARC4_H
#define CTAO_CRYPT_ARC4_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
ARC4_STATE_SIZE = 256
};
/* ARC4 encryption and decryption */
typedef struct Arc4 {
byte x;
byte y;
byte state[ARC4_STATE_SIZE];
} Arc4;
void Arc4Process(Arc4*, byte*, const byte*, word32);
void Arc4SetKey(Arc4*, const byte*, word32);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_ARC4_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/asn.h 06/12/07 22:51:51
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_ASN_H
#define CTAO_CRYPT_ASN_H
#include "types.h"
#include "rsa.h"
#include "dh.h"
#include "dsa.h"
#include "sha.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ASN Tags */
enum ASN_Tags {
ASN_INTEGER = 0x02,
ASN_BIT_STRING = 0x03,
ASN_OCTET_STRING = 0x04,
ASN_TAG_NULL = 0x05,
ASN_OBJECT_ID = 0x06,
ASN_SEQUENCE = 0x10,
ASN_SET = 0x11,
ASN_UTC_TIME = 0x17,
ASN_GENERALIZED_TIME = 0x18,
ASN_LONG_LENGTH = 0x80
};
enum ASN_Flags{
ASN_CONSTRUCTED = 0x20,
ASN_CONTEXT_SPECIFIC = 0x80
};
enum DN_Tags {
ASN_COMMON_NAME = 0x03
};
enum Misc_ASN {
SHA_SIZE = 20,
MIN_DATE_SIZE = 13,
MAX_DATE_SIZE = 15,
MAX_ENCODED_SIG_SZ = 512,
MAX_SIG_SZ = 256,
MAX_ALGO_SZ = 16,
MAX_SEQ_SZ = 5, /* enum(seq | con) + length(4) */
MAX_ENCODED_DIG_SZ = 25, /* sha + enum(bit or octet) + legnth(4) */
MAX_LENGTH_SZ = 4
};
enum Sig_Sum {
SHAwDSA = 517,
MD2wRSA = 646,
MD5wRSA = 648,
SHAwRSA = 649
};
enum Hash_Sum {
MD2h = 646,
MD5h = 649,
SHAh = 88
};
enum Key_Sum {
DSAk = 515,
RSAk = 645
};
/* Certificate file Type */
enum CertType {
CERT_TYPE = 0,
PRIVATEKEY_TYPE,
CA_TYPE
};
enum VerifyType {
NO_VERIFY = 0,
VERIFY = 1
};
typedef struct DecodedCert {
byte* publicKey;
word32 pubKeySize;
word32 certBegin; /* offset to start of cert */
word32 sigIndex; /* offset to start of signature */
word32 sigLength; /* length of signature */
word32 signatureOID; /* sum of algorithm object id */
word32 keyOID; /* sum of key algo object id */
byte subjectHash[SHA_SIZE]; /* hash of all Names */
byte issuerHash[SHA_SIZE]; /* hash of all Names */
byte* signature;
char* issuer; /* CommonName */
char* subject; /* CommonName */
int verify; /* Default to yes, but could be off */
byte* source; /* byte buffer holder cert, NOT owner */
word32 srcIdx; /* current offset into buffer */
} DecodedCert;
typedef struct Signer Signer;
/* CA Signers */
struct Signer {
byte* publicKey;
word32 pubKeySize;
char* name; /* common name */
byte hash[SHA_DIGEST_SIZE]; /* sha hash of names in certificate */
Signer* next;
};
void InitDecodedCert(DecodedCert*, byte*);
void FreeDecodedCert(DecodedCert*);
int ParseCert(DecodedCert*, word32, int type, int verify, Signer* signer);
Signer* MakeSigner(void);
void FreeSigners(Signer*);
int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32);
int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32);
#ifndef NO_DH
int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32);
#endif
#ifndef NO_DSA
int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey*, word32);
int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey*, word32);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_ASN_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/coding.h 06/12/07 22:51:51
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_CODING_H
#define CTAO_CRYPT_CODING_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* decode needed by CyaSSL */
int Base64Decode(const byte* in, word32 inLen, byte* out, word32* outLen);
#ifdef BUILD_CTAOCRYPT_EXTRA
/* encode isn't */
int Base64Encode(const byte* in, word32 inLen, byte* out, word32* outLen);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_CODING_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/des3.h 07/04/30 22:33:38
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_DES3
#ifndef CTAO_CRYPT_DES3_H
#define CTAO_CRYPT_DES3_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
DES_BLOCK_SIZE = 8,
DES_KEY_SIZE = 32,
DES_ENCRYPTION = 0,
DES_DECRYPTION = 1,
};
/* DES encryption and decryption */
typedef struct Des {
word32 key[DES_KEY_SIZE];
word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */
} Des;
/* DES3 encryption and decryption */
typedef struct Des3 {
word32 key[3][DES_KEY_SIZE];
word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */
} Des3;
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir);
void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz);
void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz);
void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir);
void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz);
void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* NO_DES3 */
#endif /* CTAO_CRYPT_DES3_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/dh.h 06/04/05 03:36:58
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_DH
#ifndef CTAO_CRYPT_DH_H
#define CTAO_CRYPT_DH_H
#include "types.h"
#include "integer.h"
#include "random.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Diffie-Hellman Key */
typedef struct DhKey {
mp_int p, g; /* group parameters */
} DhKey;
void InitDhKey(DhKey* key);
void FreeDhKey(DhKey* key);
int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz,
byte* pub, word32* pubSz);
int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
word32 privSz, const byte* otherPub, word32 pubSz);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_DH_H */
#endif /* NO_DH */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/dsa.h 06/05/15 00:17:09
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_DSA
#ifndef CTAO_CRYPT_DSA_H
#define CTAO_CRYPT_DSA_H
#include "types.h"
#include "integer.h"
#include "random.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
DSA_PUBLIC = 0,
DSA_PRIVATE = 1
};
/* DSA */
typedef struct DsaKey {
mp_int p, q, g, y, x;
int type; /* public or private */
} DsaKey;
void InitDsaKey(DsaKey* key);
void FreeDsaKey(DsaKey* key);
int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng);
int DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_DSA_H */
#endif /* NO_DSA */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/error.h 07/04/30 22:33:38
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_ERROR_H
#define CTAO_CRYPT_ERROR_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* error codes */
enum {
MAX_ERROR_SZ = 80, /* max size of error string */
MAX_CODE_E = -100, /* errors -101 - -199 */
OPEN_RAN_E = -101, /* opening random device error */
READ_RAN_E = -102, /* reading random device error */
WINCRYPT_E = -103, /* windows crypt init error */
CRYPTGEN_E = -104, /* windows crypt generation error */
MP_INIT_E = -110, /* mp_init error state */
MP_READ_E = -111, /* mp_read error state */
MP_EXPTMOD_E = -112, /* mp_exptmod error state */
MP_TO_E = -113, /* mp_to_xxx error state, can't convert */
MP_SUB_E = -114, /* mp_sub error state, can't subtract */
MP_ADD_E = -115, /* mp_add error state, can't add */
MP_MUL_E = -116, /* mp_mul error state, can't multiply */
MP_MULMOD_E = -117, /* mp_mulmod error state, can't multiply mod */
MP_MOD_E = -118, /* mp_mod error state, can't mod */
MP_INVMOD_E = -119, /* mp_invmod error state, can't inv mod */
MEMORY_E = -120, /* out of memory error */
RSA_WRONG_TYPE_E = -130, /* RSA wrong block type for RSA function */
RSA_BUFFER_E = -131, /* RSA buffer error, too small */
ASN_PARSE_E = -140, /* ASN parsing error, invalid input */
ASN_VERSION_E = -141, /* ASN version error, invalid number */
ASN_GETINT_E = -142, /* ASN get big int error, invalid data */
ASN_RSA_KEY_E = -143, /* ASN key init error, invalid input */
ASN_OBJECT_ID_E = -144, /* ASN object id error, invalid id */
ASN_TAG_NULL_E = -145, /* ASN tag error, not null */
ASN_EXPECT_0_E = -146, /* ASN expect error, not zero */
ASN_BITSTR_E = -147, /* ASN bit string error, wrong id */
ASN_UNKNOWN_OID_E = -148, /* ASN oid error, unknown sum id */
ASN_DATE_SZ_E = -149, /* ASN date error, bad size */
ASN_BEFORE_DATE_E = -150, /* ASN date error, current date before */
ASN_AFTER_DATE_E = -151, /* ASN date error, current date after */
ASN_SIG_OID_E = -152, /* ASN signature error, mismatched oid */
ASN_TIME_E = -153, /* ASN time error, unkown time type */
ASN_INPUT_E = -154, /* ASN input error, not enough data */
ASN_SIG_CONFIRM_E = -155, /* ASN sig error, confirm failure */
ASN_SIG_HASH_E = -156, /* ASN sig error, unsupported hash type */
ASN_SIG_KEY_E = -157, /* ASN sig error, unsupported key type */
ASN_DH_KEY_E = -158, /* ASN key init error, invalid input */
MIN_CODE_E = -200 /* errors -101 - -199 */
};
void CTaoCryptErrorString(int error, char* buffer);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_ERROR_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/hmac.h 06/11/23 00:33:56
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_HMAC
#ifndef CTAO_CRYPT_HMAC_H
#define CTAO_CRYPT_HMAC_H
#include "md5.h"
#include "sha.h"
#ifndef NO_SHA256
#include "sha256.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum {
MD5 = 0,
SHA = 1,
SHA256 = 2,
IPAD = 0x36,
OPAD = 0x5C,
HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE
};
/* hash union */
typedef union {
Md5 md5;
Sha sha;
#ifndef NO_SHA256
Sha256 sha256;
#endif
} Hash;
/* Hmac digest */
typedef struct Hmac {
Hash hash;
word32 ipad[HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/
word32 opad[HMAC_BLOCK_SIZE / sizeof(word32)];
word32 innerHash[SHA_DIGEST_SIZE / sizeof(word32)]; /* max size */
byte macType; /* md5 sha or sha256 */
byte innerHashKeyed; /* keyed flag */
} Hmac;
void HmacSetKey(Hmac*, int type, const byte* key, word32 keySz); /* does init */
void HmacUpdate(Hmac*, const byte*, word32);
void HmacFinal(Hmac*, byte*);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_HMAC_H */
#endif /* NO_HMAC */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/integer.h 06/04/05 03:36:58
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
/*
* Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@stripped,
* http://math.libtomcrypt.org
*/
#ifndef CTAO_CRYPT_INTEGER_H
#define CTAO_CRYPT_INTEGER_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include "types.h" /* will set MP_xxBIT if not default */
#include "mpi_class.h"
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#endif
#ifdef __cplusplus
extern "C" {
/* C++ compilers don't like assigning void * to mp_digit * */
#define OPT_CAST(x) (x *)
#else
/* C on the other hand doesn't care */
#define OPT_CAST(x)
#endif
/* detect 64-bit mode if possible */
#if defined(__x86_64__)
#if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
#define MP_64BIT
#endif
#endif
/* some default configurations.
*
* A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
* A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
*
* At the very least a mp_digit must be able to hold 7 bits
* [any size beyond that is ok provided it doesn't overflow the data type]
*/
#ifdef MP_8BIT
typedef unsigned char mp_digit;
typedef unsigned short mp_word;
#elif defined(MP_16BIT)
typedef unsigned short mp_digit;
typedef unsigned long mp_word;
#elif defined(MP_64BIT)
/* for GCC only on supported platforms */
#ifndef CRYPT
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
typedef unsigned long mp_digit;
typedef unsigned long mp_word __attribute__ ((mode(TI)));
#define DIGIT_BIT 60
#else
/* this is the default case, 28-bit digits */
/* this is to make porting into LibTomCrypt easier :-) */
#ifndef CRYPT
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
typedef signed __int64 long64;
#else
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
#endif
typedef unsigned long mp_digit;
typedef ulong64 mp_word;
#ifdef MP_31BIT
/* this is an extension that uses 31-bit digits */
#define DIGIT_BIT 31
#else
/* default case is 28-bit digits, defines MP_28BIT as a handy test macro */
#define DIGIT_BIT 28
#define MP_28BIT
#endif
#endif
/* define heap macros */
#ifndef CRYPT
/* default to libc stuff */
#ifndef XMALLOC
#define XMALLOC malloc
#define XFREE free
#define XREALLOC realloc
#define XCALLOC calloc
#else
/* prototypes for our heap functions */
extern void *XMALLOC(size_t n);
extern void *XREALLOC(void *p, size_t n);
extern void *XCALLOC(size_t n, size_t s);
extern void XFREE(void *p);
#endif
#endif
/* otherwise the bits per digit is calculated automatically from the size of
a mp_digit */
#ifndef DIGIT_BIT
#define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1)))
/* bits per digit */
#endif
#define MP_DIGIT_BIT DIGIT_BIT
#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
#define MP_DIGIT_MAX MP_MASK
/* equalities */
#define MP_LT -1 /* less than */
#define MP_EQ 0 /* equal to */
#define MP_GT 1 /* greater than */
#define MP_ZPOS 0 /* positive integer */
#define MP_NEG 1 /* negative */
#define MP_OKAY 0 /* ok result */
#define MP_MEM -2 /* out of mem */
#define MP_VAL -3 /* invalid input */
#define MP_RANGE MP_VAL
#define MP_YES 1 /* yes response */
#define MP_NO 0 /* no response */
/* Primality generation flags */
#define LTM_PRIME_BBS 0x0001 /* BBS style prime */
#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
typedef int mp_err;
/* define this to use lower memory usage routines (exptmods mostly) */
#define MP_LOW_MEM
/* default precision */
#ifndef MP_PREC
#ifndef MP_LOW_MEM
#define MP_PREC 32 /* default digits of precision */
#else
#define MP_PREC 1 /* default digits of precision */
#endif
#endif
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD -
BITS_PER_DIGIT*2) */
#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
/* the infamous mp_int structure */
typedef struct {
int used, alloc, sign;
mp_digit *dp;
} mp_int;
/* callback for mp_prime_random, should fill dst with random bytes and return
how many read [upto len] */
typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
#define USED(m) ((m)->used)
#define DIGIT(m,k) ((m)->dp[(k)])
#define SIGN(m) ((m)->sign)
/* ---> Basic Manipulations <--- */
#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
#define mp_iseven(a) \
(((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
#define mp_isodd(a) \
(((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
/* number of primes */
#ifdef MP_8BIT
#define PRIME_SIZE 31
#else
#define PRIME_SIZE 256
#endif
#define mp_prime_random(a, t, size, bbs, cb, dat) \
mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
#define mp_raw_size(mp) mp_signed_bin_size(mp)
#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
#define mp_tohex(M, S) mp_toradix((M), (S), 16)
#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
extern const char *mp_s_rmap;
/* 6 functions needed by Rsa */
int mp_init (mp_int * a);
void mp_clear (mp_int * a);
int mp_unsigned_bin_size(mp_int * a);
int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
int mp_to_unsigned_bin (mp_int * a, unsigned char *b);
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
/* end functions needed by Rsa */
/* functions added to support above needed, removed TOOM and KARATSUBA */
int mp_count_bits (mp_int * a);
int mp_init_copy (mp_int * a, mp_int * b);
int mp_copy (mp_int * a, mp_int * b);
int mp_grow (mp_int * a, int size);
void bn_reverse (unsigned char *s, int len);
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d);
void mp_zero (mp_int * a);
void mp_clamp (mp_int * a);
void mp_exch (mp_int * a, mp_int * b);
void mp_rshd (mp_int * a, int b);
int mp_mod_2d (mp_int * a, int b, mp_int * c);
int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
int mp_mul_2d (mp_int * a, int b, mp_int * c);
int mp_lshd (mp_int * a, int b);
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
int mp_abs (mp_int * a, mp_int * b);
int mp_invmod (mp_int * a, mp_int * b, mp_int * c);
int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c);
int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
int mp_cmp_mag (mp_int * a, mp_int * b);
int mp_cmp (mp_int * a, mp_int * b);
int mp_cmp_d(mp_int * a, mp_digit b);
void mp_set (mp_int * a, mp_digit b);
int mp_mod (mp_int * a, mp_int * b, mp_int * c);
int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);
int mp_div_2(mp_int * a, mp_int * b);
int mp_add (mp_int * a, mp_int * b, mp_int * c);
int s_mp_add (mp_int * a, mp_int * b, mp_int * c);
int s_mp_sub (mp_int * a, mp_int * b, mp_int * c);
int mp_sub (mp_int * a, mp_int * b, mp_int * c);
int mp_init (mp_int * a);
int mp_reduce_is_2k_l(mp_int *a);
int mp_reduce_is_2k(mp_int *a);
int mp_dr_is_modulus(mp_int *a);
int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int);
int mp_montgomery_setup (mp_int * n, mp_digit * rho);
int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);
int mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);
void mp_dr_setup(mp_int *a, mp_digit *d);
int mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k);
int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
int s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
int mp_reduce (mp_int * x, mp_int * m, mp_int * mu);
int mp_reduce_setup (mp_int * a, mp_int * b);
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);
int mp_montgomery_calc_normalization (mp_int * a, mp_int * b);
int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
int s_mp_sqr (mp_int * a, mp_int * b);
int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
int fast_s_mp_sqr (mp_int * a, mp_int * b);
int mp_init_size (mp_int * a, int size);
int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d);
int mp_mul_2(mp_int * a, mp_int * b);
int mp_mul (mp_int * a, mp_int * b, mp_int * c);
int mp_sqr (mp_int * a, mp_int * b);
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
int mp_mul_d (mp_int * a, mp_digit b, mp_int * c);
int mp_2expt (mp_int * a, int b);
int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
/* end support added functions */
/* added */
int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
mp_int* f);
#ifdef __cplusplus
}
#endif
#endif /* CTAO_CRYPT_INTEGER_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/md5.h 06/04/05 03:36:58
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_MD5_H
#define CTAO_CRYPT_MD5_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* in bytes */
enum {
MD5_BLOCK_SIZE = 64,
MD5_DIGEST_SIZE = 16,
MD5_PAD_SIZE = 56
};
/* MD5 digest */
typedef struct Md5 {
word32 buffLen; /* in bytes */
word32 loLen; /* length in bytes */
word32 hiLen; /* length in bytes */
word32 digest[MD5_DIGEST_SIZE / sizeof(word32)];
word32 buffer[MD5_BLOCK_SIZE / sizeof(word32)];
} Md5;
void InitMd5(Md5*);
void Md5Update(Md5*, const byte*, word32);
void Md5Final(Md5*, byte*);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_MD5_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/mpi_class.h 06/04/05 03:36:59
#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
#if defined(LTM2)
#define LTM3
#endif
#if defined(LTM1)
#define LTM2
#endif
#define LTM1
#if defined(LTM_ALL)
#define BN_ERROR_C
#define BN_FAST_MP_INVMOD_C
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_FAST_S_MP_SQR_C
#define BN_MP_2EXPT_C
#define BN_MP_ABS_C
#define BN_MP_ADD_C
#define BN_MP_ADD_D_C
#define BN_MP_ADDMOD_C
#define BN_MP_AND_C
#define BN_MP_CLAMP_C
#define BN_MP_CLEAR_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_CMP_C
#define BN_MP_CMP_D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_CNT_LSB_C
#define BN_MP_COPY_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_C
#define BN_MP_DIV_2_C
#define BN_MP_DIV_2D_C
#define BN_MP_DIV_3_C
#define BN_MP_DIV_D_C
#define BN_MP_DR_IS_MODULUS_C
#define BN_MP_DR_REDUCE_C
#define BN_MP_DR_SETUP_C
#define BN_MP_EXCH_C
#define BN_MP_EXPT_D_C
#define BN_MP_EXPTMOD_C
#define BN_MP_EXPTMOD_FAST_C
#define BN_MP_EXTEUCLID_C
#define BN_MP_FREAD_C
#define BN_MP_FWRITE_C
#define BN_MP_GCD_C
#define BN_MP_GET_INT_C
#define BN_MP_GROW_C
#define BN_MP_INIT_C
#define BN_MP_INIT_COPY_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_INIT_SET_C
#define BN_MP_INIT_SET_INT_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_INVMOD_C
#define BN_MP_INVMOD_SLOW_C
#define BN_MP_IS_SQUARE_C
#define BN_MP_JACOBI_C
#define BN_MP_KARATSUBA_MUL_C
#define BN_MP_KARATSUBA_SQR_C
#define BN_MP_LCM_C
#define BN_MP_LSHD_C
#define BN_MP_MOD_C
#define BN_MP_MOD_2D_C
#define BN_MP_MOD_D_C
#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
#define BN_MP_MONTGOMERY_REDUCE_C
#define BN_MP_MONTGOMERY_SETUP_C
#define BN_MP_MUL_C
#define BN_MP_MUL_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_MULMOD_C
#define BN_MP_N_ROOT_C
#define BN_MP_NEG_C
#define BN_MP_OR_C
#define BN_MP_PRIME_FERMAT_C
#define BN_MP_PRIME_IS_DIVISIBLE_C
#define BN_MP_PRIME_IS_PRIME_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_PRIME_NEXT_PRIME_C
#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
#define BN_MP_PRIME_RANDOM_EX_C
#define BN_MP_RADIX_SIZE_C
#define BN_MP_RADIX_SMAP_C
#define BN_MP_RAND_C
#define BN_MP_READ_RADIX_C
#define BN_MP_READ_SIGNED_BIN_C
#define BN_MP_READ_UNSIGNED_BIN_C
#define BN_MP_REDUCE_C
#define BN_MP_REDUCE_2K_C
#define BN_MP_REDUCE_2K_L_C
#define BN_MP_REDUCE_2K_SETUP_C
#define BN_MP_REDUCE_2K_SETUP_L_C
#define BN_MP_REDUCE_IS_2K_C
#define BN_MP_REDUCE_IS_2K_L_C
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_RSHD_C
#define BN_MP_SET_C
#define BN_MP_SET_INT_C
#define BN_MP_SHRINK_C
#define BN_MP_SIGNED_BIN_SIZE_C
#define BN_MP_SQR_C
#define BN_MP_SQRMOD_C
#define BN_MP_SQRT_C
#define BN_MP_SUB_C
#define BN_MP_SUB_D_C
#define BN_MP_SUBMOD_C
#define BN_MP_TO_SIGNED_BIN_C
#define BN_MP_TO_SIGNED_BIN_N_C
#define BN_MP_TO_UNSIGNED_BIN_C
#define BN_MP_TO_UNSIGNED_BIN_N_C
#define BN_MP_TOOM_MUL_C
#define BN_MP_TOOM_SQR_C
#define BN_MP_TORADIX_C
#define BN_MP_TORADIX_N_C
#define BN_MP_UNSIGNED_BIN_SIZE_C
#define BN_MP_XOR_C
#define BN_MP_ZERO_C
#define BN_PRIME_TAB_C
#define BN_REVERSE_C
#define BN_S_MP_ADD_C
#define BN_S_MP_EXPTMOD_C
#define BN_S_MP_MUL_DIGS_C
#define BN_S_MP_MUL_HIGH_DIGS_C
#define BN_S_MP_SQR_C
#define BN_S_MP_SUB_C
#define BNCORE_C
#endif
#if defined(BN_ERROR_C)
#define BN_MP_ERROR_TO_STRING_C
#endif
#if defined(BN_FAST_MP_INVMOD_C)
#define BN_MP_ISEVEN_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_COPY_C
#define BN_MP_MOD_C
#define BN_MP_SET_C
#define BN_MP_DIV_2_C
#define BN_MP_ISODD_C
#define BN_MP_SUB_C
#define BN_MP_CMP_C
#define BN_MP_ISZERO_C
#define BN_MP_CMP_D_C
#define BN_MP_ADD_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
#define BN_MP_GROW_C
#define BN_MP_RSHD_C
#define BN_MP_CLAMP_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_FAST_S_MP_MUL_DIGS_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_FAST_S_MP_SQR_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_2EXPT_C)
#define BN_MP_ZERO_C
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_ABS_C)
#define BN_MP_COPY_C
#endif
#if defined(BN_MP_ADD_C)
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_ADD_D_C)
#define BN_MP_GROW_C
#define BN_MP_SUB_D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_ADDMOD_C)
#define BN_MP_INIT_C
#define BN_MP_ADD_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_AND_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_CLAMP_C)
#endif
#if defined(BN_MP_CLEAR_C)
#endif
#if defined(BN_MP_CLEAR_MULTI_C)
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_CMP_C)
#define BN_MP_CMP_MAG_C
#endif
#if defined(BN_MP_CMP_D_C)
#endif
#if defined(BN_MP_CMP_MAG_C)
#endif
#if defined(BN_MP_CNT_LSB_C)
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_COPY_C)
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_COUNT_BITS_C)
#endif
#if defined(BN_MP_DIV_C)
#define BN_MP_ISZERO_C
#define BN_MP_CMP_MAG_C
#define BN_MP_COPY_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_SET_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_ABS_C
#define BN_MP_MUL_2D_C
#define BN_MP_CMP_C
#define BN_MP_SUB_C
#define BN_MP_ADD_C
#define BN_MP_DIV_2D_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_INIT_C
#define BN_MP_INIT_COPY_C
#define BN_MP_LSHD_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_D_C
#define BN_MP_CLAMP_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DIV_2_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_DIV_2D_C)
#define BN_MP_COPY_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_C
#define BN_MP_MOD_2D_C
#define BN_MP_CLEAR_C
#define BN_MP_RSHD_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_MP_DIV_3_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DIV_D_C)
#define BN_MP_ISZERO_C
#define BN_MP_COPY_C
#define BN_MP_DIV_2D_C
#define BN_MP_DIV_3_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DR_IS_MODULUS_C)
#endif
#if defined(BN_MP_DR_REDUCE_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_DR_SETUP_C)
#endif
#if defined(BN_MP_EXCH_C)
#endif
#if defined(BN_MP_EXPT_D_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_SET_C
#define BN_MP_SQR_C
#define BN_MP_CLEAR_C
#define BN_MP_MUL_C
#endif
#if defined(BN_MP_EXPTMOD_C)
#define BN_MP_INIT_C
#define BN_MP_INVMOD_C
#define BN_MP_CLEAR_C
#define BN_MP_ABS_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_REDUCE_IS_2K_L_C
#define BN_S_MP_EXPTMOD_C
#define BN_MP_DR_IS_MODULUS_C
#define BN_MP_REDUCE_IS_2K_C
#define BN_MP_ISODD_C
#define BN_MP_EXPTMOD_FAST_C
#endif
#if defined(BN_MP_EXPTMOD_FAST_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#define BN_MP_MONTGOMERY_SETUP_C
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_MP_MONTGOMERY_REDUCE_C
#define BN_MP_DR_SETUP_C
#define BN_MP_DR_REDUCE_C
#define BN_MP_REDUCE_2K_SETUP_C
#define BN_MP_REDUCE_2K_C
#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
#define BN_MP_MULMOD_C
#define BN_MP_SET_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_SQR_C
#define BN_MP_MUL_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_MP_EXTEUCLID_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_SET_C
#define BN_MP_COPY_C
#define BN_MP_ISZERO_C
#define BN_MP_DIV_C
#define BN_MP_MUL_C
#define BN_MP_SUB_C
#define BN_MP_NEG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_FREAD_C)
#define BN_MP_ZERO_C
#define BN_MP_S_RMAP_C
#define BN_MP_MUL_D_C
#define BN_MP_ADD_D_C
#define BN_MP_CMP_D_C
#endif
#if defined(BN_MP_FWRITE_C)
#define BN_MP_RADIX_SIZE_C
#define BN_MP_TORADIX_C
#endif
#if defined(BN_MP_GCD_C)
#define BN_MP_ISZERO_C
#define BN_MP_ABS_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_S_MP_SUB_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_GET_INT_C)
#endif
#if defined(BN_MP_GROW_C)
#endif
#if defined(BN_MP_INIT_C)
#endif
#if defined(BN_MP_INIT_COPY_C)
#define BN_MP_COPY_C
#endif
#if defined(BN_MP_INIT_MULTI_C)
#define BN_MP_ERR_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_INIT_SET_C)
#define BN_MP_INIT_C
#define BN_MP_SET_C
#endif
#if defined(BN_MP_INIT_SET_INT_C)
#define BN_MP_INIT_C
#define BN_MP_SET_INT_C
#endif
#if defined(BN_MP_INIT_SIZE_C)
#define BN_MP_INIT_C
#endif
#if defined(BN_MP_INVMOD_C)
#define BN_MP_ISZERO_C
#define BN_MP_ISODD_C
#define BN_FAST_MP_INVMOD_C
#define BN_MP_INVMOD_SLOW_C
#endif
#if defined(BN_MP_INVMOD_SLOW_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_ISEVEN_C
#define BN_MP_SET_C
#define BN_MP_DIV_2_C
#define BN_MP_ISODD_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_CMP_C
#define BN_MP_CMP_D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_IS_SQUARE_C)
#define BN_MP_MOD_D_C
#define BN_MP_INIT_SET_INT_C
#define BN_MP_MOD_C
#define BN_MP_GET_INT_C
#define BN_MP_SQRT_C
#define BN_MP_SQR_C
#define BN_MP_CMP_MAG_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_JACOBI_C)
#define BN_MP_CMP_D_C
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_MOD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_KARATSUBA_MUL_C)
#define BN_MP_MUL_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_SUB_C
#define BN_MP_ADD_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_KARATSUBA_SQR_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_SQR_C
#define BN_MP_SUB_C
#define BN_S_MP_ADD_C
#define BN_MP_LSHD_C
#define BN_MP_ADD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_LCM_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_GCD_C
#define BN_MP_CMP_MAG_C
#define BN_MP_DIV_C
#define BN_MP_MUL_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_LSHD_C)
#define BN_MP_GROW_C
#define BN_MP_RSHD_C
#endif
#if defined(BN_MP_MOD_C)
#define BN_MP_INIT_C
#define BN_MP_DIV_C
#define BN_MP_CLEAR_C
#define BN_MP_ADD_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_MP_MOD_2D_C)
#define BN_MP_ZERO_C
#define BN_MP_COPY_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MOD_D_C)
#define BN_MP_DIV_D_C
#endif
#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_2EXPT_C
#define BN_MP_SET_C
#define BN_MP_MUL_2_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_MONTGOMERY_REDUCE_C)
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#define BN_MP_RSHD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_MONTGOMERY_SETUP_C)
#endif
#if defined(BN_MP_MUL_C)
#define BN_MP_TOOM_MUL_C
#define BN_MP_KARATSUBA_MUL_C
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_S_MP_MUL_C
#define BN_S_MP_MUL_DIGS_C
#endif
#if defined(BN_MP_MUL_2_C)
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_MUL_2D_C)
#define BN_MP_COPY_C
#define BN_MP_GROW_C
#define BN_MP_LSHD_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MUL_D_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MULMOD_C)
#define BN_MP_INIT_C
#define BN_MP_MUL_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_N_ROOT_C)
#define BN_MP_INIT_C
#define BN_MP_SET_C
#define BN_MP_COPY_C
#define BN_MP_EXPT_D_C
#define BN_MP_MUL_C
#define BN_MP_SUB_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_C
#define BN_MP_CMP_C
#define BN_MP_SUB_D_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_NEG_C)
#define BN_MP_COPY_C
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_OR_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_FERMAT_C)
#define BN_MP_CMP_D_C
#define BN_MP_INIT_C
#define BN_MP_EXPTMOD_C
#define BN_MP_CMP_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
#define BN_MP_MOD_D_C
#endif
#if defined(BN_MP_PRIME_IS_PRIME_C)
#define BN_MP_CMP_D_C
#define BN_MP_PRIME_IS_DIVISIBLE_C
#define BN_MP_INIT_C
#define BN_MP_SET_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_MILLER_RABIN_C)
#define BN_MP_CMP_D_C
#define BN_MP_INIT_COPY_C
#define BN_MP_SUB_D_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_EXPTMOD_C
#define BN_MP_CMP_C
#define BN_MP_SQRMOD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_NEXT_PRIME_C)
#define BN_MP_CMP_D_C
#define BN_MP_SET_C
#define BN_MP_SUB_D_C
#define BN_MP_ISEVEN_C
#define BN_MP_MOD_D_C
#define BN_MP_INIT_C
#define BN_MP_ADD_D_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
#endif
#if defined(BN_MP_PRIME_RANDOM_EX_C)
#define BN_MP_READ_UNSIGNED_BIN_C
#define BN_MP_PRIME_IS_PRIME_C
#define BN_MP_SUB_D_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_D_C
#endif
#if defined(BN_MP_RADIX_SIZE_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_COPY_C
#define BN_MP_ISZERO_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_RADIX_SMAP_C)
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_RAND_C)
#define BN_MP_ZERO_C
#define BN_MP_ADD_D_C
#define BN_MP_LSHD_C
#endif
#if defined(BN_MP_READ_RADIX_C)
#define BN_MP_ZERO_C
#define BN_MP_S_RMAP_C
#define BN_MP_RADIX_SMAP_C
#define BN_MP_MUL_D_C
#define BN_MP_ADD_D_C
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_READ_SIGNED_BIN_C)
#define BN_MP_READ_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_READ_UNSIGNED_BIN_C)
#define BN_MP_GROW_C
#define BN_MP_ZERO_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_REDUCE_C)
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_INIT_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_C
#define BN_S_MP_MUL_HIGH_DIGS_C
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_MP_MOD_2D_C
#define BN_S_MP_MUL_DIGS_C
#define BN_MP_SUB_C
#define BN_MP_CMP_D_C
#define BN_MP_SET_C
#define BN_MP_LSHD_C
#define BN_MP_ADD_C
#define BN_MP_CMP_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_2D_C
#define BN_MP_MUL_D_C
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_L_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_2D_C
#define BN_MP_MUL_C
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_SETUP_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_2EXPT_C
#define BN_MP_CLEAR_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
#define BN_MP_INIT_C
#define BN_MP_2EXPT_C
#define BN_MP_COUNT_BITS_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_IS_2K_C)
#define BN_MP_REDUCE_2K_C
#define BN_MP_COUNT_BITS_C
#endif
#if defined(BN_MP_REDUCE_IS_2K_L_C)
#endif
#if defined(BN_MP_REDUCE_SETUP_C)
#define BN_MP_2EXPT_C
#define BN_MP_DIV_C
#endif
#if defined(BN_MP_RSHD_C)
#define BN_MP_ZERO_C
#endif
#if defined(BN_MP_SET_C)
#define BN_MP_ZERO_C
#endif
#if defined(BN_MP_SET_INT_C)
#define BN_MP_ZERO_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_SHRINK_C)
#endif
#if defined(BN_MP_SIGNED_BIN_SIZE_C)
#define BN_MP_UNSIGNED_BIN_SIZE_C
#endif
#if defined(BN_MP_SQR_C)
#define BN_MP_TOOM_SQR_C
#define BN_MP_KARATSUBA_SQR_C
#define BN_FAST_S_MP_SQR_C
#define BN_S_MP_SQR_C
#endif
#if defined(BN_MP_SQRMOD_C)
#define BN_MP_INIT_C
#define BN_MP_SQR_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_SQRT_C)
#define BN_MP_N_ROOT_C
#define BN_MP_ISZERO_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_DIV_C
#define BN_MP_ADD_C
#define BN_MP_DIV_2_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_SUB_C)
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_SUB_D_C)
#define BN_MP_GROW_C
#define BN_MP_ADD_D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_SUBMOD_C)
#define BN_MP_INIT_C
#define BN_MP_SUB_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_TO_SIGNED_BIN_C)
#define BN_MP_TO_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_TO_SIGNED_BIN_N_C)
#define BN_MP_SIGNED_BIN_SIZE_C
#define BN_MP_TO_SIGNED_BIN_C
#endif
#if defined(BN_MP_TO_UNSIGNED_BIN_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_ISZERO_C
#define BN_MP_DIV_2D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
#define BN_MP_UNSIGNED_BIN_SIZE_C
#define BN_MP_TO_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_TOOM_MUL_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_2D_C
#define BN_MP_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_3_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_TOOM_SQR_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_2D_C
#define BN_MP_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_SQR_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_3_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_TORADIX_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_TORADIX_N_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
#define BN_MP_COUNT_BITS_C
#endif
#if defined(BN_MP_XOR_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_ZERO_C)
#endif
#if defined(BN_PRIME_TAB_C)
#endif
#if defined(BN_REVERSE_C)
#endif
#if defined(BN_S_MP_ADD_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_S_MP_EXPTMOD_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_REDUCE_C
#define BN_MP_REDUCE_2K_SETUP_L_C
#define BN_MP_REDUCE_2K_L_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_SQR_C
#define BN_MP_MUL_C
#define BN_MP_SET_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_S_MP_MUL_DIGS_C)
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_SQR_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_SUB_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BNCORE_C)
#endif
#ifdef LTM3
#define LTM_LAST
#endif
#include <mpi_superclass.h>
#include <mpi_class.h>
#else
#define LTM_LAST
#endif
--- New file ---
+++ extra/cyassl/ctaocrypt/include/mpi_superclass.h 06/04/05 03:36:59
/* super class file for PK algos */
/* default ... include all MPI */
#define LTM_ALL
/* RSA only (does not support DH/DSA/ECC) */
/* #define SC_RSA_1 */
/* For reference.... On an Athlon64 optimizing for speed...
LTM's mpi.o with all functions [striped] is 142KiB in size.
*/
/* Works for RSA only, mpi.o is 68KiB */
#ifdef SC_RSA_1
#define BN_MP_SHRINK_C
#define BN_MP_LCM_C
#define BN_MP_PRIME_RANDOM_EX_C
#define BN_MP_INVMOD_C
#define BN_MP_GCD_C
#define BN_MP_MOD_C
#define BN_MP_MULMOD_C
#define BN_MP_ADDMOD_C
#define BN_MP_EXPTMOD_C
#define BN_MP_SET_INT_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_UNSIGNED_BIN_SIZE_C
#define BN_MP_TO_UNSIGNED_BIN_C
#define BN_MP_MOD_D_C
#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
#define BN_REVERSE_C
#define BN_PRIME_TAB_C
/* other modifiers */
#define BN_MP_DIV_SMALL /* Slower division, not critical */
/* here we are on the last pass so we turn things off. The functions classes are still there
* but we remove them specifically from the build. This also invokes tweaks in functions
* like removing support for even moduli, etc...
*/
#ifdef LTM_LAST
#undef BN_MP_TOOM_MUL_C
#undef BN_MP_TOOM_SQR_C
#undef BN_MP_KARATSUBA_MUL_C
#undef BN_MP_KARATSUBA_SQR_C
#undef BN_MP_REDUCE_C
#undef BN_MP_REDUCE_SETUP_C
#undef BN_MP_DR_IS_MODULUS_C
#undef BN_MP_DR_SETUP_C
#undef BN_MP_DR_REDUCE_C
#undef BN_MP_REDUCE_IS_2K_C
#undef BN_MP_REDUCE_2K_SETUP_C
#undef BN_MP_REDUCE_2K_C
#undef BN_S_MP_EXPTMOD_C
#undef BN_MP_DIV_3_C
#undef BN_S_MP_MUL_HIGH_DIGS_C
#undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
#undef BN_FAST_MP_INVMOD_C
/* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
* which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
* which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
* trouble.
*/
#undef BN_S_MP_MUL_DIGS_C
#undef BN_S_MP_SQR_C
#undef BN_MP_MONTGOMERY_REDUCE_C
#endif
#endif
--- New file ---
+++ extra/cyassl/ctaocrypt/include/random.h 06/04/05 03:36:59
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_RANDOM_H
#define CTAO_CRYPT_RANDOM_H
#include "arc4.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_WIN32)
#if defined(_WIN64)
typedef unsigned __int64 ProviderHandle;
/* type HCRYPTPROV, avoid #include <windows.h> */
#else
typedef unsigned long ProviderHandle;
#endif
#endif
/* OS specific seeder */
typedef struct OS_Seed {
#if defined(_WIN32)
ProviderHandle handle;
#else
int fd;
#endif
} OS_Seed;
int GenerateSeed(OS_Seed* os, byte* seed, word32 sz);
/* secure Random Nnumber Generator */
typedef struct RNG {
OS_Seed seed;
Arc4 cipher;
} RNG;
int InitRng(RNG*);
void RNG_GenerateBlock(RNG*, byte*, word32 sz);
byte RNG_GenerateByte(RNG*);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_RANDOM_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/rsa.h 06/04/05 03:36:59
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_RSA_H
#define CTAO_CRYPT_RSA_H
#include "types.h"
#include "integer.h"
#include "random.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
RSA_PUBLIC = 0,
RSA_PRIVATE = 1
};
/* RSA */
typedef struct RsaKey {
mp_int n, e, d, p, q, dP, dQ, u;
int type; /* public or private */
} RsaKey;
void InitRsaKey(RsaKey* key);
void FreeRsaKey(RsaKey* key);
int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key, RNG* rng);
int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key);
int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key, RNG* rng);
int RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key);
int RsaEncryptSize(RsaKey* key);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_RSA_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/sha.h 06/04/05 03:36:59
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_SHA_H
#define CTAO_CRYPT_SHA_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* in bytes */
enum {
SHA_BLOCK_SIZE = 64,
SHA_DIGEST_SIZE = 20,
SHA_PAD_SIZE = 56
};
/* Sha digest */
typedef struct Sha {
word32 buffLen; /* in bytes */
word32 loLen; /* length in bytes */
word32 hiLen; /* length in bytes */
word32 digest[SHA_DIGEST_SIZE / sizeof(word32)];
word32 buffer[SHA_BLOCK_SIZE / sizeof(word32)];
} Sha;
void InitSha(Sha*);
void ShaUpdate(Sha*, const byte*, word32);
void ShaFinal(Sha*, byte*);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_SHA_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/sha256.h 06/12/05 20:11:18
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
/* code submitted by raphael.huck@stripped */
#ifndef NO_SHA256
#ifndef CTAO_CRYPT_SHA256_H
#define CTAO_CRYPT_SHA256_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* in bytes */
enum {
SHA256_BLOCK_SIZE = 64,
SHA256_DIGEST_SIZE = 32,
SHA256_PAD_SIZE = 56
};
/* Sha256 digest */
typedef struct Sha256 {
word32 buffLen; /* in bytes */
word32 loLen; /* length in bytes */
word32 hiLen; /* length in bytes */
word32 digest[SHA256_DIGEST_SIZE / sizeof(word32)];
word32 buffer[SHA256_BLOCK_SIZE / sizeof(word32)];
} Sha256;
void InitSha256(Sha256*);
void Sha256Update(Sha256*, const byte*, word32);
void Sha256Final(Sha256*, byte*);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_SHA256_H */
#endif /* NO_SHA256 */
--- New file ---
+++ extra/cyassl/ctaocrypt/include/types.h 06/04/05 03:36:59
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef CTAO_CRYPT_TYPES_H
#define CTAO_CRYPT_TYPES_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(WORDS_BIGENDIAN) || (defined(__MWERKS__) && !defined(__INTEL__))
#define BIG_ENDIAN_ORDER
#endif
#ifndef BIG_ENDIAN_ORDER
#define LITTLE_ENDIAN_ORDER
#endif
typedef unsigned char byte;
typedef unsigned short word16;
typedef unsigned int word32;
#if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
#define WORD64_AVAILABLE
#define WORD64_IS_DISTINCT_TYPE
typedef unsigned __int64 word64;
#elif SIZEOF_LONG == 8
#define WORD64_AVAILABLE
typedef unsigned long word64;
#elif SIZEOF_LONG_LONG == 8
#define WORD64_AVAILABLE
#define WORD64_IS_DISTINCT_TYPE
typedef unsigned long long word64;
#else
#define MP_16BIT /* for mp_int, mp_word needs to be twice as big as
mp_digit, no 64 bit type so make mp_digit 16 bit */
#endif
/* These platforms have 64-bit CPU registers. */
#if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \
defined(__mips64) || defined(__x86_64__))
typedef word32 hword;
typedef word64 word;
#else
typedef word16 hword;
typedef word32 word;
#ifdef WORD64_AVAILABLE
typedef word64 dword;
#endif
#endif
enum {
WORD_SIZE = sizeof(word),
BIT_SIZE = 8,
WORD_BITS = WORD_SIZE * BIT_SIZE
};
/* use inlining if compiler allows */
#ifdef _MSC_VER
#define INLINE __inline
#elif __GNUC__
#define INLINE inline
#else
#define INLINE
#endif
/* set up rotate style */
#if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
#define INTEL_INTRINSICS
#define FAST_ROTATE
#elif defined(__MWERKS__) && TARGET_CPU_PPC
#define PPC_INTRINSICS
#define FAST_ROTATE
#elif defined(__GNUC__) && defined(__i386__)
/* GCC does peephole optimizations which should result in using rotate
instructions */
#define FAST_ROTATE
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_TYPES_H */
--- New file ---
+++ extra/cyassl/ctaocrypt/src/aes.c 06/04/05 03:37:00
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_AES
#include "aes.h"
#include "misc.c"
#include <assert.h>
static const word32 rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x1B000000, 0x36000000,
/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
};
static const word32 Te[5][256] = {
{
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
},
{
0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
},
{
0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
},
{
0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
},
{
0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
}
};
static const word32 Td[5][256] = {
{
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
},
{
0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
},
{
0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
},
{
0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
},
{
0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
}
};
#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
void AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
int dir)
{
word32 temp, *rk = aes->key;
unsigned int i = 0;
assert( (keylen == 16) || (keylen == 24) || (keylen == 32) );
aes->rounds = keylen/4 + 6;
memcpy(rk, userKey, keylen);
#ifdef LITTLE_ENDIAN_ORDER
ByteReverseWords(rk, rk, keylen);
#endif
switch(keylen)
{
case 16:
while (1)
{
temp = rk[3];
rk[4] = rk[0] ^
(Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
(Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10)
break;
rk += 4;
}
break;
case 24:
while (1) /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
{
temp = rk[ 5];
rk[ 6] = rk[ 0] ^
(Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
(Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8)
break;
rk[10] = rk[ 4] ^ rk[ 9];
rk[11] = rk[ 5] ^ rk[10];
rk += 6;
}
break;
case 32:
while (1)
{
temp = rk[ 7];
rk[ 8] = rk[ 0] ^
(Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
(Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7)
break;
temp = rk[11];
rk[12] = rk[ 4] ^
(Te[4][GETBYTE(temp, 3)] & 0xff000000) ^
(Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^
(Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^
(Te[4][GETBYTE(temp, 0)] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
break;
}
if (dir == AES_DECRYPTION)
{
unsigned int i, j;
rk = aes->key;
/* invert the order of the round keys: */
for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
}
/* apply the inverse MixColumn transform to all round keys but the
first and the last: */
for (i = 1; i < aes->rounds; i++) {
rk += 4;
rk[0] =
Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^
Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^
Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^
Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff];
rk[1] =
Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^
Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^
Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^
Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff];
rk[2] =
Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^
Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^
Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^
Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff];
rk[3] =
Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^
Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^
Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^
Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff];
}
}
memcpy(aes->reg, iv, AES_BLOCK_SIZE);
}
void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
{
word32 s0, s1, s2, s3;
word32 t0, t1, t2, t3;
word32 r = aes->rounds >> 1;
const word32* rk = aes->key;
/*
* map byte array block to cipher state
* and add initial round key:
*/
memcpy(&s0, inBlock, sizeof(s0));
memcpy(&s1, inBlock + sizeof(s0), sizeof(s1));
memcpy(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
memcpy(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
#ifdef LITTLE_ENDIAN_ORDER
s0 = ByteReverseWord32(s0);
s1 = ByteReverseWord32(s1);
s2 = ByteReverseWord32(s2);
s3 = ByteReverseWord32(s3);
#endif
s0 ^= rk[0];
s1 ^= rk[1];
s2 ^= rk[2];
s3 ^= rk[3];
/*
* Nr - 1 full rounds:
*/
for (;;) {
t0 =
Te[0][GETBYTE(s0, 3)] ^
Te[1][GETBYTE(s1, 2)] ^
Te[2][GETBYTE(s2, 1)] ^
Te[3][GETBYTE(s3, 0)] ^
rk[4];
t1 =
Te[0][GETBYTE(s1, 3)] ^
Te[1][GETBYTE(s2, 2)] ^
Te[2][GETBYTE(s3, 1)] ^
Te[3][GETBYTE(s0, 0)] ^
rk[5];
t2 =
Te[0][GETBYTE(s2, 3)] ^
Te[1][GETBYTE(s3, 2)] ^
Te[2][GETBYTE(s0, 1)] ^
Te[3][GETBYTE(s1, 0)] ^
rk[6];
t3 =
Te[0][GETBYTE(s3, 3)] ^
Te[1][GETBYTE(s0, 2)] ^
Te[2][GETBYTE(s1, 1)] ^
Te[3][GETBYTE(s2, 0)] ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Te[0][GETBYTE(t0, 3)] ^
Te[1][GETBYTE(t1, 2)] ^
Te[2][GETBYTE(t2, 1)] ^
Te[3][GETBYTE(t3, 0)] ^
rk[0];
s1 =
Te[0][GETBYTE(t1, 3)] ^
Te[1][GETBYTE(t2, 2)] ^
Te[2][GETBYTE(t3, 1)] ^
Te[3][GETBYTE(t0, 0)] ^
rk[1];
s2 =
Te[0][GETBYTE(t2, 3)] ^
Te[1][GETBYTE(t3, 2)] ^
Te[2][GETBYTE(t0, 1)] ^
Te[3][GETBYTE(t1, 0)] ^
rk[2];
s3 =
Te[0][GETBYTE(t3, 3)] ^
Te[1][GETBYTE(t0, 2)] ^
Te[2][GETBYTE(t1, 1)] ^
Te[3][GETBYTE(t2, 0)] ^
rk[3];
}
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te[4][GETBYTE(t0, 3)] & 0xff000000) ^
(Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
(Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
(Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^
rk[0];
s1 =
(Te[4][GETBYTE(t1, 3)] & 0xff000000) ^
(Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
(Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
(Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^
rk[1];
s2 =
(Te[4][GETBYTE(t2, 3)] & 0xff000000) ^
(Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
(Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
(Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^
rk[2];
s3 =
(Te[4][GETBYTE(t3, 3)] & 0xff000000) ^
(Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
(Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
(Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^
rk[3];
/* write out */
#ifdef LITTLE_ENDIAN_ORDER
s0 = ByteReverseWord32(s0);
s1 = ByteReverseWord32(s1);
s2 = ByteReverseWord32(s2);
s3 = ByteReverseWord32(s3);
#endif
memcpy(outBlock, &s0, sizeof(s0));
memcpy(outBlock + sizeof(s0), &s1, sizeof(s1));
memcpy(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
memcpy(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
}
void AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
{
word32 s0, s1, s2, s3;
word32 t0, t1, t2, t3;
word32 r = aes->rounds >> 1;
const word32* rk = aes->key;
/*
* map byte array block to cipher state
* and add initial round key:
*/
memcpy(&s0, inBlock, sizeof(s0));
memcpy(&s1, inBlock + sizeof(s0), sizeof(s1));
memcpy(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
memcpy(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
#ifdef LITTLE_ENDIAN_ORDER
s0 = ByteReverseWord32(s0);
s1 = ByteReverseWord32(s1);
s2 = ByteReverseWord32(s2);
s3 = ByteReverseWord32(s3);
#endif
s0 ^= rk[0];
s1 ^= rk[1];
s2 ^= rk[2];
s3 ^= rk[3];
/*
* Nr - 1 full rounds:
*/
for (;;) {
t0 =
Td[0][GETBYTE(s0, 3)] ^
Td[1][GETBYTE(s3, 2)] ^
Td[2][GETBYTE(s2, 1)] ^
Td[3][GETBYTE(s1, 0)] ^
rk[4];
t1 =
Td[0][GETBYTE(s1, 3)] ^
Td[1][GETBYTE(s0, 2)] ^
Td[2][GETBYTE(s3, 1)] ^
Td[3][GETBYTE(s2, 0)] ^
rk[5];
t2 =
Td[0][GETBYTE(s2, 3)] ^
Td[1][GETBYTE(s1, 2)] ^
Td[2][GETBYTE(s0, 1)] ^
Td[3][GETBYTE(s3, 0)] ^
rk[6];
t3 =
Td[0][GETBYTE(s3, 3)] ^
Td[1][GETBYTE(s2, 2)] ^
Td[2][GETBYTE(s1, 1)] ^
Td[3][GETBYTE(s0, 0)] ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Td[0][GETBYTE(t0, 3)] ^
Td[1][GETBYTE(t3, 2)] ^
Td[2][GETBYTE(t2, 1)] ^
Td[3][GETBYTE(t1, 0)] ^
rk[0];
s1 =
Td[0][GETBYTE(t1, 3)] ^
Td[1][GETBYTE(t0, 2)] ^
Td[2][GETBYTE(t3, 1)] ^
Td[3][GETBYTE(t2, 0)] ^
rk[1];
s2 =
Td[0][GETBYTE(t2, 3)] ^
Td[1][GETBYTE(t1, 2)] ^
Td[2][GETBYTE(t0, 1)] ^
Td[3][GETBYTE(t3, 0)] ^
rk[2];
s3 =
Td[0][GETBYTE(t3, 3)] ^
Td[1][GETBYTE(t2, 2)] ^
Td[2][GETBYTE(t1, 1)] ^
Td[3][GETBYTE(t0, 0)] ^
rk[3];
}
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td[4][GETBYTE(t0, 3)] & 0xff000000) ^
(Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
(Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
(Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^
rk[0];
s1 =
(Td[4][GETBYTE(t1, 3)] & 0xff000000) ^
(Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
(Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
(Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^
rk[1];
s2 =
(Td[4][GETBYTE(t2, 3)] & 0xff000000) ^
(Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
(Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
(Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^
rk[2];
s3 =
(Td[4][GETBYTE(t3, 3)] & 0xff000000) ^
(Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
(Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
(Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^
rk[3];
/* write out */
#ifdef LITTLE_ENDIAN_ORDER
s0 = ByteReverseWord32(s0);
s1 = ByteReverseWord32(s1);
s2 = ByteReverseWord32(s2);
s3 = ByteReverseWord32(s3);
#endif
memcpy(outBlock, &s0, sizeof(s0));
memcpy(outBlock + sizeof(s0), &s1, sizeof(s1));
memcpy(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
memcpy(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
}
void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
word32 blocks = sz / AES_BLOCK_SIZE;
while (blocks--) {
xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
memcpy(out, aes->reg, AES_BLOCK_SIZE);
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
}
}
void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
word32 blocks = sz / AES_BLOCK_SIZE;
byte hold[16];
while (blocks--) {
memcpy(aes->tmp, in, AES_BLOCK_SIZE);
AesDecrypt(aes, (byte*)aes->tmp, out);
xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);
memcpy(hold, aes->reg, AES_BLOCK_SIZE);
memcpy(aes->reg, aes->tmp, AES_BLOCK_SIZE);
memcpy(aes->tmp, hold, AES_BLOCK_SIZE);
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
}
}
#endif /* NO_AES */
--- New file ---
+++ extra/cyassl/ctaocrypt/src/arc4.c 06/04/05 03:37:00
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#include "arc4.h"
void Arc4SetKey(Arc4* arc4, const byte* key, word32 length)
{
word32 i;
word32 keyIndex = 0, stateIndex = 0;
arc4->x = 1;
arc4->y = 0;
for (i = 0; i < ARC4_STATE_SIZE; i++)
arc4->state[i] = i;
for (i = 0; i < ARC4_STATE_SIZE; i++) {
word32 a = arc4->state[i];
stateIndex += key[keyIndex] + a;
stateIndex &= 0xFF;
arc4->state[i] = arc4->state[stateIndex];
arc4->state[stateIndex] = a;
if (++keyIndex >= length)
keyIndex = 0;
}
}
static INLINE word32 MakeByte(word32* x, word32* y, byte* s)
{
word32 a = s[*x], b;
*y = (*y+a) & 0xff;
b = s[*y];
s[*x] = b;
s[*y] = a;
*x = (*x+1) & 0xff;
return s[(a+b) & 0xff];
}
void Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length)
{
word32 x = arc4->x;
word32 y = arc4->y;
while(length--)
*out++ = *in++ ^ MakeByte(&x, &y, arc4->state);
arc4->x = x;
arc4->y = y;
}
--- New file ---
+++ extra/cyassl/ctaocrypt/src/asn.c 07/04/30 22:33:38
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#include "asn.h"
#include "sha.h"
#include "md5.h"
#include "error.h"
#include <time.h>
#include <assert.h>
#define NO_DH /* remove for now */
#define NO_DSA /* remove for now */
enum {
ISSUER = 0,
SUBJECT = 1,
BEFORE = 0,
AFTER = 1
};
int GetLength(const byte* input, word32* inOutIdx, int* len)
{
int length = 0;
word32 i = *inOutIdx;
byte b = input[i++];
if (b >= ASN_LONG_LENGTH) {
word32 bytes = b & 0x7F;
while (bytes--) {
b = input[i++];
length = (length << 8) | b;
}
}
else
length = b;
*inOutIdx = i;
*len = length;
return length;
}
int GetSequence(const byte* input, word32* inOutIdx, int* len)
{
int length = -1;
word32 idx = *inOutIdx;
if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
GetLength(input, &idx, &length) < 0)
return ASN_PARSE_E;
*len = length;
*inOutIdx = idx;
return length;
}
int GetSet(const byte* input, word32* inOutIdx, int* len)
{
int length = -1;
word32 idx = *inOutIdx;
if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
GetLength(input, &idx, &length) < 0)
return ASN_PARSE_E;
*len = length;
*inOutIdx = idx;
return length;
}
int GetVersion(const byte* input, word32* inOutIdx, int* version)
{
word32 idx = *inOutIdx;
if (input[idx++] != ASN_INTEGER)
return ASN_PARSE_E;
if (input[idx++] != 0x01)
return ASN_VERSION_E;
*version = input[idx++];
*inOutIdx = idx;
return *version;
}
/* May not have one, not an error */
int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
{
word32 idx = *inOutIdx;
if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
*inOutIdx = ++idx; /* eat header */
return GetVersion(input, inOutIdx, version);
}
/* go back as is */
*version = 0;
return 0;
}
int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx )
{
word32 i = *inOutIdx;
byte b = input[i++];
int length;
if (b != ASN_INTEGER)
return ASN_PARSE_E;
if (GetLength(input, &i, &length) < 0)
return ASN_PARSE_E;
if ( (b = input[i++]) == 0x00)
length--;
else
i--;
mp_init(mpi);
if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) {
mp_clear(mpi);
return ASN_GETINT_E;
}
*inOutIdx = i + length;
return 0;
}
int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
{
word32 begin = *inOutIdx;
int version, length;
if (GetSequence(input, inOutIdx, &length) < 0)
return ASN_PARSE_E;
if ((word32)length > (inSz - (*inOutIdx - begin)))
return ASN_INPUT_E;
if (GetVersion(input, inOutIdx, &version) < 0)
return ASN_PARSE_E;
key->type = RSA_PRIVATE;
if (GetInt(&key->n, input, inOutIdx) < 0 ||
GetInt(&key->e, input, inOutIdx) < 0 ||
GetInt(&key->d, input, inOutIdx) < 0 ||
GetInt(&key->p, input, inOutIdx) < 0 ||
GetInt(&key->q, input, inOutIdx) < 0 ||
GetInt(&key->dP, input, inOutIdx) < 0 ||
GetInt(&key->dQ, input, inOutIdx) < 0 ||
GetInt(&key->u, input, inOutIdx) < 0 ) return ASN_RSA_KEY_E;
return 0;
}
int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
{
word32 begin = *inOutIdx;
int length;
if (GetSequence(input, inOutIdx, &length) < 0)
return ASN_PARSE_E;
if ((word32)length > (inSz - (*inOutIdx - begin)))
return ASN_INPUT_E;
key->type = RSA_PUBLIC;
if (GetInt(&key->n, input, inOutIdx) < 0 ||
GetInt(&key->e, input, inOutIdx) < 0 ) return ASN_RSA_KEY_E;
return 0;
}
#ifndef NO_DH
int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
{
word32 begin = *inOutIdx;
int length;
if (GetSequence(input, inOutIdx, &length) < 0)
return ASN_PARSE_E;
if ((word32)length > (inSz - (*inOutIdx - begin)))
return ASN_INPUT_E;
if (GetInt(&key->p, input, inOutIdx) < 0 ||
GetInt(&key->g, input, inOutIdx) < 0 ) return ASN_DH_KEY_E;
return 0;
}
#endif /* NO_DH */
#ifndef NO_DSA
int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
word32 inSz)
{
word32 begin = *inOutIdx;
int length;
if (GetSequence(input, inOutIdx, &length) < 0)
return ASN_PARSE_E;
if ((word32)length > (inSz - (*inOutIdx - begin)))
return ASN_INPUT_E;
if (GetInt(&key->p, input, inOutIdx) < 0 ||
GetInt(&key->q, input, inOutIdx) < 0 ||
GetInt(&key->g, input, inOutIdx) < 0 ||
GetInt(&key->y, input, inOutIdx) < 0 ) return ASN_DH_KEY_E;
return 0;
}
int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
word32 inSz)
{
word32 begin = *inOutIdx;
int length, version;
if (GetSequence(input, inOutIdx, &length) < 0)
return ASN_PARSE_E;
if ((word32)length > (inSz - (*inOutIdx - begin)))
return ASN_INPUT_E;
if (GetVersion(input, inOutIdx, &version) < 0)
return ASN_PARSE_E;
if (GetInt(&key->p, input, inOutIdx) < 0 ||
GetInt(&key->q, input, inOutIdx) < 0 ||
GetInt(&key->g, input, inOutIdx) < 0 ||
GetInt(&key->y, input, inOutIdx) < 0 ||
GetInt(&key->x, input, inOutIdx) < 0 ) return ASN_DH_KEY_E;
return 0;
}
#endif /* NO_DSA */
void InitDecodedCert(DecodedCert* cert, byte* source)
{
cert->publicKey = 0;
cert->signature = 0;
cert->issuer = 0;
cert->subject = 0;
cert->source = source; /* don't own */
cert->srcIdx = 0;
}
void FreeDecodedCert(DecodedCert* cert)
{
free(cert->subject);
free(cert->issuer);
free(cert->signature);
free(cert->publicKey);
}
static int GetCertHeader(DecodedCert* cert, word32 inSz)
{
int ret = 0, version, len;
word32 begin = cert->srcIdx;
mp_int mpi;
if (GetSequence(cert->source, &cert->srcIdx, &len) < 0)
return ASN_PARSE_E;
if ((word32)len > (inSz - (cert->srcIdx - begin))) return ASN_INPUT_E;
cert->certBegin = cert->srcIdx;
GetSequence(cert->source, &cert->srcIdx, &len);
cert->sigIndex = len + cert->srcIdx;
if (GetExplicitVersion(cert->source, &cert->srcIdx, &version) < 0)
return ASN_PARSE_E;
if (GetInt(&mpi, cert->source, &cert->srcIdx) < 0)
ret = ASN_PARSE_E;
mp_clear(&mpi);
return ret;
}
static int GetAlgoId(DecodedCert* cert, word32* oid)
{
int length;
byte b;
*oid = 0;
if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
return ASN_PARSE_E;
b = cert->source[cert->srcIdx++];
if (b != ASN_OBJECT_ID)
return ASN_OBJECT_ID_E;
if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
return ASN_PARSE_E;
while(length--)
*oid += cert->source[cert->srcIdx++];
/* just sum it up for now */
if (*oid != SHAwDSA && *oid != DSAk) {
b = cert->source[cert->srcIdx++]; /* should have NULL tag and 0 */
if (b != ASN_TAG_NULL)
return ASN_TAG_NULL_E;
b = cert->source[cert->srcIdx++];
if (b != 0)
return ASN_EXPECT_0_E;
}
return 0;
}
static int StoreKey(DecodedCert* cert)
{
int length;
word32 read = cert->srcIdx;
if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
return ASN_PARSE_E;
read = cert->srcIdx - read;
length += read;
while (read--)
cert->srcIdx--;
cert->pubKeySize = length;
if ( !(cert->publicKey = (byte*) malloc(length)) )
return MEMORY_E;
memcpy(cert->publicKey, cert->source + cert->srcIdx, length);
cert->srcIdx += length;
return 0;
}
static int GetKey(DecodedCert* cert)
{
int length;
if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
return ASN_PARSE_E;
if (GetAlgoId(cert, &cert->keyOID) < 0)
return ASN_PARSE_E;
if (cert->keyOID == RSAk) {
byte b = cert->source[cert->srcIdx++];
if (b != ASN_BIT_STRING)
return ASN_BITSTR_E;
b = cert->source[cert->srcIdx++]; /* length, future */
b = cert->source[cert->srcIdx++];
while (b != 0)
b = cert->source[cert->srcIdx++];
}
else if (cert->keyOID == DSAk )
; /* do nothing */
else
return ASN_UNKNOWN_OID_E;
return StoreKey(cert);
}
/* process NAME, either issuer or subject */
static int GetName(DecodedCert* cert, int nameType)
{
Sha sha;
int length; /* length of all distinguished names */
int dummy;
InitSha(&sha);
if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
return ASN_PARSE_E;
length += cert->srcIdx;
while (cert->srcIdx < (word32)length) {
byte b;
byte joint[2];
int oidSz;
if (GetSet(cert->source, &cert->srcIdx, &dummy) < 0)
return ASN_PARSE_E;
if (GetSequence(cert->source, &cert->srcIdx, &dummy) < 0)
return ASN_PARSE_E;
b = cert->source[cert->srcIdx++];
if (b != ASN_OBJECT_ID)
return ASN_OBJECT_ID_E;
if (GetLength(cert->source, &cert->srcIdx, &oidSz) < 0)
return ASN_PARSE_E;
memcpy(joint, &cert->source[cert->srcIdx], sizeof(joint));
/* v1 name types */
if (joint[0] == 0x55 && joint[1] == 0x04) {
byte id;
int strLen;
cert->srcIdx += 2;
id = cert->source[cert->srcIdx++];
b = cert->source[cert->srcIdx++]; /* strType */
if (GetLength(cert->source, &cert->srcIdx, &strLen) < 0)
return ASN_PARSE_E;
if (id == ASN_COMMON_NAME) {
char** pp = (nameType == ISSUER) ?
&cert->issuer : &cert->subject;
*pp = (char*) malloc(strLen + 1);
if (!*pp)
return MEMORY_E;
memcpy(*pp, &cert->source[cert->srcIdx], strLen);
(*pp)[strLen] = 0;
}
ShaUpdate(&sha, &cert->source[cert->srcIdx], strLen);
cert->srcIdx += strLen;
}
else {
/* skip */
int adv;
cert->srcIdx += oidSz + 1;
if (GetLength(cert->source, &cert->srcIdx, &adv) < 0)
return ASN_PARSE_E;
cert->srcIdx += adv;
}
}
if (nameType == ISSUER)
ShaFinal(&sha, cert->issuerHash);
else
ShaFinal(&sha, cert->subjectHash);
return 0;
}
/* to the minute */
static int DateGreaterThan(const struct tm* a, const struct tm* b)
{
if (a->tm_year > b->tm_year)
return 1;
if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
return 1;
if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
a->tm_mday > b->tm_mday)
return 1;
if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
return 1;
if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
a->tm_min > b->tm_min)
return 1;
return 0; /* false */
}
static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
{
return !DateGreaterThan(a,b);
}
/* like atoi but only use first byte */
static INLINE word32 btoi(byte b)
{
return b - 0x30;
}
/* two byte date/time, add to value */
static INLINE void GetTime(int* value, const byte* date, int* idx)
{
int i = *idx;
*value += btoi(date[i++]) * 10;
*value += btoi(date[i++]);
*idx = i;
}
/* Make sure before and after dates are valid */
static int ValidateDate(const byte* date, byte format, int dateType)
{
time_t ltime = time(0);
struct tm certTime;
struct tm* localTime;
int i = 0;
memset(&certTime, 0, sizeof(certTime));
if (format == ASN_UTC_TIME) {
if (btoi(date[0]) >= 5)
certTime.tm_year = 1900;
else
certTime.tm_year = 2000;
}
else { /* format == GENERALIZED_TIME */
certTime.tm_year += btoi(date[i++]) * 1000;
certTime.tm_year += btoi(date[i++]) * 100;
}
GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */
GetTime(&certTime.tm_mon, date, &i); certTime.tm_mon -= 1; /* adjust */
GetTime(&certTime.tm_mday, date, &i);
GetTime(&certTime.tm_hour, date, &i);
GetTime(&certTime.tm_min, date, &i);
GetTime(&certTime.tm_sec, date, &i);
assert(date[i] == 'Z'); /* only Zulu supported for this profile */
localTime = gmtime(<ime);
if (dateType == BEFORE) {
if (DateLessThan(localTime, &certTime))
return 0;
}
else
if (DateGreaterThan(localTime, &certTime))
return 0;
return 1;
}
static int GetDate(DecodedCert* cert, int dateType)
{
int length;
byte date[MAX_DATE_SIZE];
byte b = cert->source[cert->srcIdx++];
if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
return ASN_TIME_E;
if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
return ASN_PARSE_E;
if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
return ASN_DATE_SZ_E;
memcpy(date, &cert->source[cert->srcIdx], length);
cert->srcIdx += length;
if (!ValidateDate(date, b, dateType)) {
if (dateType == BEFORE)
return ASN_BEFORE_DATE_E;
else
return ASN_AFTER_DATE_E;
}
return 0;
}
static int GetValidity(DecodedCert* cert, int verify)
{
int length;
if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
return ASN_PARSE_E;
if (GetDate(cert, BEFORE) < 0 && verify)
return ASN_BEFORE_DATE_E;
if (GetDate(cert, AFTER) < 0 && verify)
return ASN_AFTER_DATE_E;
return 0;
}
static int DecodeToKey(DecodedCert* cert, word32 inSz, int verify)
{
int ret;
if ( (ret = GetCertHeader(cert, inSz)) < 0)
return ret;
if ( (ret = GetAlgoId(cert, &cert->signatureOID)) < 0)
return ret;
if ( (ret = GetName(cert, ISSUER)) < 0)
return ret;
if ( (ret = GetValidity(cert, verify)) < 0)
return ret;
if ( (ret = GetName(cert, SUBJECT)) < 0)
return ret;
if ( (ret = GetKey(cert)) < 0)
return ret;
return ret;
}
static int GetSignature(DecodedCert* cert)
{
int length;
byte b = cert->source[cert->srcIdx++];
if (b != ASN_BIT_STRING)
return ASN_BITSTR_E;
if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
return ASN_PARSE_E;
cert->sigLength = length;
b = cert->source[cert->srcIdx++];
if (b != 0x00)
return ASN_EXPECT_0_E;
cert->sigLength--;
cert->signature = (byte*) malloc(cert->sigLength);
if (!cert->signature)
return MEMORY_E;
memcpy(cert->signature, &cert->source[cert->srcIdx], cert->sigLength);
cert->srcIdx += cert->sigLength;
return 0;
}
static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
{
output[0] = ASN_OCTET_STRING;
output[1] = digSz;
memcpy(&output[2], digest, digSz);
return digSz + 2;
}
static word32 BytePrecision(word32 value)
{
word32 i;
for (i = sizeof(value); i; --i)
if (value >> (i - 1) * 8)
break;
return i;
}
static word32 SetLength(word32 length, byte* output)
{
word32 i = 0, j;
if (length < ASN_LONG_LENGTH)
output[i++] = length;
else {
output[i++] = BytePrecision(length) | ASN_LONG_LENGTH;
for (j = BytePrecision(length); j; --j) {
output[i] = length >> (j - 1) * 8;
i++;
}
}
return i;
}
static word32 SetSequence(word32 len, byte* output)
{
output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
return SetLength(len, output + 1) + 1;
}
static word32 SetAlgoID(int algoOID, byte* output)
{
/* adding TAG_NULL and 0 to end */
static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
0x05, 0x00 };
static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x02, 0x05, 0x05, 0x00 };
static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x02, 0x02, 0x05, 0x00};
int algoSz = 0;
word32 idSz, seqSz;
const byte* algoName = 0;
byte ID_Length[MAX_LENGTH_SZ];
byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */
switch (algoOID) {
case SHAh:
algoSz = sizeof(shaAlgoID);
algoName = shaAlgoID;
break;
case MD2h:
algoSz = sizeof(md2AlgoID);
algoName = md2AlgoID;
break;
case MD5h:
algoSz = sizeof(md5AlgoID);
algoName = md5AlgoID;
break;
default:
return 0; /* UNKOWN_HASH_E; */
}
idSz = SetLength(algoSz - 2, ID_Length); /* don't include TAG_NULL/0 */
seqSz = SetSequence(idSz + algoSz + 1, seqArray);
seqArray[seqSz++] = ASN_OBJECT_ID;
memcpy(output, seqArray, seqSz);
memcpy(output + seqSz, ID_Length, idSz);
memcpy(output + seqSz + idSz, algoName, algoSz);
return seqSz + idSz + algoSz;
}
static word32 EncodeSignature(byte* out, const byte* digest, word32 digSz,
int hashOID)
{
byte digArray[MAX_ENCODED_DIG_SZ];
byte algoArray[MAX_ALGO_SZ];
byte seqArray[MAX_SEQ_SZ];
word32 encDigSz, algoSz, seqSz;
encDigSz = SetDigest(digest, digSz, digArray);
algoSz = SetAlgoID(hashOID, algoArray);
seqSz = SetSequence(encDigSz + algoSz, seqArray);
memcpy(out, seqArray, seqSz);
memcpy(out + seqSz, algoArray, algoSz);
memcpy(out + seqSz + algoSz, digArray, encDigSz);
return encDigSz + algoSz + seqSz;
}
/* return true (1) for Confirmation */
static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz)
{
byte digest[SHA_DIGEST_SIZE]; /* max size */
int hashType, digestSz, ret;
if (cert->signatureOID == MD5wRSA) {
Md5 md5;
InitMd5(&md5);
Md5Update(&md5, cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin);
Md5Final(&md5, digest);
hashType = MD5h;
digestSz = MD5_DIGEST_SIZE;
}
else if (cert->signatureOID == SHAwRSA || cert->signatureOID == SHAwDSA) {
Sha sha;
InitSha(&sha);
ShaUpdate(&sha, cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin);
ShaFinal(&sha, digest);
hashType = SHAh;
digestSz = SHA_DIGEST_SIZE;
}
else
return 0; /* ASN_SIG_HASH_E; */
if (cert->keyOID == RSAk) {
RsaKey pubKey;
byte encodedSig[MAX_ENCODED_SIG_SZ];
byte plain[MAX_SIG_SZ];
word32 idx = 0;
int sigSz, verifySz;
InitRsaKey(&pubKey);
if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0)
return 0; /* ASN_KEY_DECODE_E; */
sigSz = EncodeSignature(encodedSig, digest, digestSz, hashType);
if ( (verifySz = RsaSSL_Verify(cert->signature, cert->sigLength, plain,
sizeof(plain), &pubKey)) < 0)
ret = 0; /* ASN_VERIFY_E; */
else {
/* make sure we're right justified */
if (sigSz != verifySz || memcmp(plain, encodedSig, sigSz) != 0)
ret = 0; /* ASN_VERIFY_MATCH_E; */
else
ret = 1; /* match */
}
FreeRsaKey(&pubKey);
return ret;
}
else
return 0; /* ASN_SIG_KEY_E; */
return 0; /* not confirmed */
}
int ParseCert(DecodedCert* cert, word32 inSz, int type, int verify,
Signer* signers)
{
word32 confirmOID;
int ret;
int confirm = 0;
if ((ret = DecodeToKey(cert, inSz, verify)) < 0)
return ret;
if (cert->srcIdx != cert->sigIndex)
cert->srcIdx = cert->sigIndex;
if ((ret = GetAlgoId(cert, &confirmOID)) < 0)
return ret;
if ((ret = GetSignature(cert)) < 0)
return ret;
if (confirmOID != cert->signatureOID)
return ASN_SIG_OID_E;
if (verify && type != CA_TYPE) {
while (signers) {
if (memcmp(cert->issuerHash, signers->hash, SHA_DIGEST_SIZE)
== 0) {
/* other confirm */
if (!ConfirmSignature(cert, signers->publicKey,
signers->pubKeySize))
return ASN_SIG_CONFIRM_E;
else {
confirm = 1;
break;
}
}
signers = signers->next;
}
if (!confirm)
return ASN_SIG_CONFIRM_E;
}
return 0;
}
Signer* MakeSigner(void)
{
Signer* signer = (Signer*) malloc(sizeof(Signer));
if (signer) {
signer->name = 0;
signer->publicKey = 0;
signer->next = 0;
}
return signer;
}
void FreeSigners(Signer* signer)
{
Signer* next = signer;
while( (signer = next) ) {
next = signer->next;
free(signer->name);
free(signer->publicKey);
free(signer);
}
}
void CTaoCryptErrorString(int error, char* buffer)
{
const int max = MAX_ERROR_SZ; /* shorthand */
#ifdef NO_ERROR_STRINGS
strncpy(buffer, "no support for error strings built in", max);
#else
switch (error) {
case OPEN_RAN_E :
strncpy(buffer, "opening random device error", max);
break;
case READ_RAN_E :
strncpy(buffer, "reading random device error", max);
break;
case WINCRYPT_E :
strncpy(buffer, "windows crypt init error", max);
break;
case CRYPTGEN_E :
strncpy(buffer, "windows crypt generation error", max);
break;
case MP_INIT_E :
strncpy(buffer, "mp_init error state", max);
break;
case MP_READ_E :
strncpy(buffer, "mp_read error state", max);
break;
case MP_EXPTMOD_E :
strncpy(buffer, "mp_exptmod error state", max);
break;
case MP_TO_E :
strncpy(buffer, "mp_to_xxx error state, can't convert", max);
break;
case MP_SUB_E :
strncpy(buffer, "mp_sub error state, can't subtract", max);
break;
case MP_ADD_E :
strncpy(buffer, "mp_add error state, can't add", max);
break;
case MP_MUL_E :
strncpy(buffer, "mp_mul error state, can't multiply", max);
break;
case MP_MULMOD_E :
strncpy(buffer, "mp_mulmod error state, can't multiply mod", max);
break;
case MP_MOD_E :
strncpy(buffer, "mp_mod error state, can't mod", max);
break;
case MP_INVMOD_E :
strncpy(buffer, "mp_invmod error state, can't inv mod", max);
break;
case MEMORY_E :
strncpy(buffer, "out of memory error", max);
break;
case RSA_WRONG_TYPE_E :
strncpy(buffer, "RSA wrong block type for RSA function", max);
break;
case RSA_BUFFER_E :
strncpy(buffer, "RSA buffer error, too small", max);
break;
case ASN_PARSE_E :
strncpy(buffer, "ASN parsing error, invalid input", max);
break;
case ASN_VERSION_E :
strncpy(buffer, "ASN version error, invalid number", max);
break;
case ASN_GETINT_E :
strncpy(buffer, "ASN get big int error, invalid data", max);
break;
case ASN_RSA_KEY_E :
strncpy(buffer, "ASN key init error, invalid input", max);
break;
case ASN_OBJECT_ID_E :
strncpy(buffer, "ASN object id error, invalid id", max);
break;
case ASN_TAG_NULL_E :
strncpy(buffer, "ASN tag error, not null", max);
break;
case ASN_EXPECT_0_E :
strncpy(buffer, "ASN expect error, not zero", max);
break;
case ASN_BITSTR_E :
strncpy(buffer, "ASN bit string error, wrong id", max);
break;
case ASN_UNKNOWN_OID_E :
strncpy(buffer, "ASN oid error, unknown sum id", max);
break;
case ASN_DATE_SZ_E :
strncpy(buffer, "ASN date error, bad size", max);
break;
case ASN_BEFORE_DATE_E :
strncpy(buffer, "ASN date error, current date before", max);
break;
case ASN_AFTER_DATE_E :
strncpy(buffer, "ASN date error, current date after", max);
break;
case ASN_SIG_OID_E :
strncpy(buffer, "ASN signature error, mismatched oid", max);
break;
case ASN_TIME_E :
strncpy(buffer, "ASN time error, unkown time type", max);
break;
case ASN_INPUT_E :
strncpy(buffer, "ASN input error, not enough data", max);
break;
case ASN_SIG_CONFIRM_E :
strncpy(buffer, "ASN sig error, confirm failure", max);
break;
case ASN_SIG_HASH_E :
strncpy(buffer, "ASN sig error, unsupported hash type", max);
break;
case ASN_SIG_KEY_E :
strncpy(buffer, "ASN sig error, unsupported key type", max);
break;
case ASN_DH_KEY_E :
strncpy(buffer, "ASN key init error, invalid input", max);
break;
default:
strncpy(buffer, "unknown error number", max);
}
#endif
}
--- New file ---
+++ extra/cyassl/ctaocrypt/src/coding.c 07/04/30 22:33:38
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#include "coding.h"
#include <assert.h>
enum {
BAD = 0xFF, /* invalid encoding */
PAD = '=',
PEM_LINE_SZ = 64
};
static
const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
BAD, BAD, BAD, BAD, BAD, BAD, BAD,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25,
BAD, BAD, BAD, BAD, BAD, BAD,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49, 50, 51
};
int Base64Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
{
word32 i = 0;
word32 j = 0;
word32 e = 0;
word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );
plainSz = (plainSz * 3 + 3) / 4;
if (plainSz > *outLen) return -1;
while (inLen > 3) {
byte b1, b2, b3;
byte e1 = in[j++];
byte e2 = in[j++];
byte e3 = in[j++];
byte e4 = in[j++];
int pad3 = 0;
int pad4 = 0;
if (e1 == 0) /* end file 0's */
break;
if (e3 == PAD)
pad3 = 1;
if (e4 == PAD)
pad4 = 1;
e1 = base64Decode[e1 - 0x2B];
e2 = base64Decode[e2 - 0x2B];
e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B];
e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B];
b1 = (e1 << 2) | (e2 >> 4);
b2 = ((e2 & 0xF) << 4) | (e3 >> 2);
b3 = ((e3 & 0x3) << 6) | e4;
out[i++] = b1;
if (!pad3)
out[i++] = b2;
if (!pad4)
out[i++] = b3;
else
break;
inLen -= 4;
if ((++e % 16) == 0) {
byte endLine = in[j++];
inLen--;
while (endLine == ' ') { /* allow trailing whitespace */
endLine = in[j++];
inLen--;
}
if (endLine == '\r') {
endLine = in[j++];
inLen--;
}
if (endLine != '\n')
return -1;
}
}
*outLen = i;
return 0;
}
#ifdef BUILD_CTAOCRYPT_EXTRA
static
const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'+', '/'
};
/* porting assistance from yaSSL by Raphael HUCK */
int Base64Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
{
word32 i = 0,
j = 0,
n = 0; /* new line counter */
word32 outSz = (inLen + 3 - 1) / 3 * 4;
outSz += (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */
if (outSz > *outLen) return -1;
while (inLen > 2) {
byte b1 = in[j++];
byte b2 = in[j++];
byte b3 = in[j++];
// encoded idx
byte e1 = b1 >> 2;
byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
byte e3 = ((b2 & 0xF) << 2) | (b3 >> 6);
byte e4 = b3 & 0x3F;
// store
out[i++] = base64Encode[e1];
out[i++] = base64Encode[e2];
out[i++] = base64Encode[e3];
out[i++] = base64Encode[e4];
inLen -= 3;
if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen)
out[i++] = '\n';
}
/* last integral */
if (inLen) {
int twoBytes = (inLen == 2);
byte b1 = in[j++];
byte b2 = (twoBytes) ? in[j++] : 0;
byte e1 = b1 >> 2;
byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
byte e3 = (b2 & 0xF) << 2;
out[i++] = base64Encode[e1];
out[i++] = base64Encode[e2];
out[i++] = (twoBytes) ? base64Encode[e3] : PAD;
out[i++] = PAD;
}
out[i++] = '\n';
assert(i == outSz);
return 0;
}
#endif /* BUILD_CTAOCRYPT_EXTRA */
--- New file ---
+++ extra/cyassl/ctaocrypt/src/des3.c 07/04/30 22:33:38
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_DES3
#include "des3.h"
#include "misc.c"
#include <string.h>
/* permuted choice table (key) */
static const byte pc1[] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/* number left rotations of pc1 */
static const byte totrot[] = {
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
};
/* permuted choice key (table) */
static const byte pc2[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
/* End of DES-defined tables */
/* bit 0 is left-most in byte */
static const int bytebit[] = {
0200,0100,040,020,010,04,02,01
};
const word32 Spbox[8][64] = {
{
0x01010400,0x00000000,0x00010000,0x01010404,
0x01010004,0x00010404,0x00000004,0x00010000,
0x00000400,0x01010400,0x01010404,0x00000400,
0x01000404,0x01010004,0x01000000,0x00000004,
0x00000404,0x01000400,0x01000400,0x00010400,
0x00010400,0x01010000,0x01010000,0x01000404,
0x00010004,0x01000004,0x01000004,0x00010004,
0x00000000,0x00000404,0x00010404,0x01000000,
0x00010000,0x01010404,0x00000004,0x01010000,
0x01010400,0x01000000,0x01000000,0x00000400,
0x01010004,0x00010000,0x00010400,0x01000004,
0x00000400,0x00000004,0x01000404,0x00010404,
0x01010404,0x00010004,0x01010000,0x01000404,
0x01000004,0x00000404,0x00010404,0x01010400,
0x00000404,0x01000400,0x01000400,0x00000000,
0x00010004,0x00010400,0x00000000,0x01010004},
{
0x80108020,0x80008000,0x00008000,0x00108020,
0x00100000,0x00000020,0x80100020,0x80008020,
0x80000020,0x80108020,0x80108000,0x80000000,
0x80008000,0x00100000,0x00000020,0x80100020,
0x00108000,0x00100020,0x80008020,0x00000000,
0x80000000,0x00008000,0x00108020,0x80100000,
0x00100020,0x80000020,0x00000000,0x00108000,
0x00008020,0x80108000,0x80100000,0x00008020,
0x00000000,0x00108020,0x80100020,0x00100000,
0x80008020,0x80100000,0x80108000,0x00008000,
0x80100000,0x80008000,0x00000020,0x80108020,
0x00108020,0x00000020,0x00008000,0x80000000,
0x00008020,0x80108000,0x00100000,0x80000020,
0x00100020,0x80008020,0x80000020,0x00100020,
0x00108000,0x00000000,0x80008000,0x00008020,
0x80000000,0x80100020,0x80108020,0x00108000},
{
0x00000208,0x08020200,0x00000000,0x08020008,
0x08000200,0x00000000,0x00020208,0x08000200,
0x00020008,0x08000008,0x08000008,0x00020000,
0x08020208,0x00020008,0x08020000,0x00000208,
0x08000000,0x00000008,0x08020200,0x00000200,
0x00020200,0x08020000,0x08020008,0x00020208,
0x08000208,0x00020200,0x00020000,0x08000208,
0x00000008,0x08020208,0x00000200,0x08000000,
0x08020200,0x08000000,0x00020008,0x00000208,
0x00020000,0x08020200,0x08000200,0x00000000,
0x00000200,0x00020008,0x08020208,0x08000200,
0x08000008,0x00000200,0x00000000,0x08020008,
0x08000208,0x00020000,0x08000000,0x08020208,
0x00000008,0x00020208,0x00020200,0x08000008,
0x08020000,0x08000208,0x00000208,0x08020000,
0x00020208,0x00000008,0x08020008,0x00020200},
{
0x00802001,0x00002081,0x00002081,0x00000080,
0x00802080,0x00800081,0x00800001,0x00002001,
0x00000000,0x00802000,0x00802000,0x00802081,
0x00000081,0x00000000,0x00800080,0x00800001,
0x00000001,0x00002000,0x00800000,0x00802001,
0x00000080,0x00800000,0x00002001,0x00002080,
0x00800081,0x00000001,0x00002080,0x00800080,
0x00002000,0x00802080,0x00802081,0x00000081,
0x00800080,0x00800001,0x00802000,0x00802081,
0x00000081,0x00000000,0x00000000,0x00802000,
0x00002080,0x00800080,0x00800081,0x00000001,
0x00802001,0x00002081,0x00002081,0x00000080,
0x00802081,0x00000081,0x00000001,0x00002000,
0x00800001,0x00002001,0x00802080,0x00800081,
0x00002001,0x00002080,0x00800000,0x00802001,
0x00000080,0x00800000,0x00002000,0x00802080},
{
0x00000100,0x02080100,0x02080000,0x42000100,
0x00080000,0x00000100,0x40000000,0x02080000,
0x40080100,0x00080000,0x02000100,0x40080100,
0x42000100,0x42080000,0x00080100,0x40000000,
0x02000000,0x40080000,0x40080000,0x00000000,
0x40000100,0x42080100,0x42080100,0x02000100,
0x42080000,0x40000100,0x00000000,0x42000000,
0x02080100,0x02000000,0x42000000,0x00080100,
0x00080000,0x42000100,0x00000100,0x02000000,
0x40000000,0x02080000,0x42000100,0x40080100,
0x02000100,0x40000000,0x42080000,0x02080100,
0x40080100,0x00000100,0x02000000,0x42080000,
0x42080100,0x00080100,0x42000000,0x42080100,
0x02080000,0x00000000,0x40080000,0x42000000,
0x00080100,0x02000100,0x40000100,0x00080000,
0x00000000,0x40080000,0x02080100,0x40000100},
{
0x20000010,0x20400000,0x00004000,0x20404010,
0x20400000,0x00000010,0x20404010,0x00400000,
0x20004000,0x00404010,0x00400000,0x20000010,
0x00400010,0x20004000,0x20000000,0x00004010,
0x00000000,0x00400010,0x20004010,0x00004000,
0x00404000,0x20004010,0x00000010,0x20400010,
0x20400010,0x00000000,0x00404010,0x20404000,
0x00004010,0x00404000,0x20404000,0x20000000,
0x20004000,0x00000010,0x20400010,0x00404000,
0x20404010,0x00400000,0x00004010,0x20000010,
0x00400000,0x20004000,0x20000000,0x00004010,
0x20000010,0x20404010,0x00404000,0x20400000,
0x00404010,0x20404000,0x00000000,0x20400010,
0x00000010,0x00004000,0x20400000,0x00404010,
0x00004000,0x00400010,0x20004010,0x00000000,
0x20404000,0x20000000,0x00400010,0x20004010},
{
0x00200000,0x04200002,0x04000802,0x00000000,
0x00000800,0x04000802,0x00200802,0x04200800,
0x04200802,0x00200000,0x00000000,0x04000002,
0x00000002,0x04000000,0x04200002,0x00000802,
0x04000800,0x00200802,0x00200002,0x04000800,
0x04000002,0x04200000,0x04200800,0x00200002,
0x04200000,0x00000800,0x00000802,0x04200802,
0x00200800,0x00000002,0x04000000,0x00200800,
0x04000000,0x00200800,0x00200000,0x04000802,
0x04000802,0x04200002,0x04200002,0x00000002,
0x00200002,0x04000000,0x04000800,0x00200000,
0x04200800,0x00000802,0x00200802,0x04200800,
0x00000802,0x04000002,0x04200802,0x04200000,
0x00200800,0x00000000,0x00000002,0x04200802,
0x00000000,0x00200802,0x04200000,0x00000800,
0x04000002,0x04000800,0x00000800,0x00200002},
{
0x10001040,0x00001000,0x00040000,0x10041040,
0x10000000,0x10001040,0x00000040,0x10000000,
0x00040040,0x10040000,0x10041040,0x00041000,
0x10041000,0x00041040,0x00001000,0x00000040,
0x10040000,0x10000040,0x10001000,0x00001040,
0x00041000,0x00040040,0x10040040,0x10041000,
0x00001040,0x00000000,0x00000000,0x10040040,
0x10000040,0x10001000,0x00041040,0x00040000,
0x00041040,0x00040000,0x10041000,0x00001000,
0x00000040,0x10040040,0x00001000,0x00041040,
0x10001000,0x00000040,0x10000040,0x10040000,
0x10040040,0x10000000,0x00040000,0x10001040,
0x00000000,0x10041040,0x00040040,0x10000040,
0x10040000,0x10001000,0x10001040,0x00000000,
0x10041040,0x00041000,0x00041000,0x00001040,
0x00001040,0x00040040,0x10000000,0x10041000}
};
static INLINE void IPERM(word32* left, word32* right)
{
word32 work;
*right = rotlFixed(*right, 4U);
work = (*left ^ *right) & 0xf0f0f0f0;
*left ^= work;
*right = rotrFixed(*right^work, 20U);
work = (*left ^ *right) & 0xffff0000;
*left ^= work;
*right = rotrFixed(*right^work, 18U);
work = (*left ^ *right) & 0x33333333;
*left ^= work;
*right = rotrFixed(*right^work, 6U);
work = (*left ^ *right) & 0x00ff00ff;
*left ^= work;
*right = rotlFixed(*right^work, 9U);
work = (*left ^ *right) & 0xaaaaaaaa;
*left = rotlFixed(*left^work, 1U);
*right ^= work;
}
static INLINE void FPERM(word32* left, word32* right)
{
word32 work;
*right = rotrFixed(*right, 1U);
work = (*left ^ *right) & 0xaaaaaaaa;
*right ^= work;
*left = rotrFixed(*left^work, 9U);
work = (*left ^ *right) & 0x00ff00ff;
*right ^= work;
*left = rotlFixed(*left^work, 6U);
work = (*left ^ *right) & 0x33333333;
*right ^= work;
*left = rotlFixed(*left^work, 18U);
work = (*left ^ *right) & 0xffff0000;
*right ^= work;
*left = rotlFixed(*left^work, 20U);
work = (*left ^ *right) & 0xf0f0f0f0;
*right ^= work;
*left = rotrFixed(*left^work, 4U);
}
static void DesSetKey(const byte* key, int dir, word32* out)
{
byte buffer[56+56+8];
byte *const pc1m = buffer; /* place to modify pc1 into */
byte *const pcr = pc1m + 56; /* place to rotate pc1 into */
byte *const ks = pcr + 56;
register int i,j,l;
int m;
for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
l = pc1[j] - 1; /* integer bit location */
m = l & 07; /* find bit */
pc1m[j] = (key[l >> 3] & /* find which key byte l is in */
bytebit[m]) /* and which bit of that byte */
? 1 : 0; /* and store 1-bit result */
}
for (i = 0; i < 16; i++) { /* key chunk for each iteration */
memset(ks, 0, 8); /* Clear key schedule */
for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28];
/* rotate left and right halves independently */
for (j = 0; j < 48; j++){ /* select bits individually */
/* check bit that goes to ks[j] */
if (pcr[pc2[j] - 1]){
/* mask it in if it's there */
l= j % 6;
ks[j/6] |= bytebit[l] >> 2;
}
}
/* Now convert to odd/even interleaved form for use in F */
out[2*i] = ((word32)ks[0] << 24)
| ((word32)ks[2] << 16)
| ((word32)ks[4] << 8)
| ((word32)ks[6]);
out[2*i + 1] = ((word32)ks[1] << 24)
| ((word32)ks[3] << 16)
| ((word32)ks[5] << 8)
| ((word32)ks[7]);
}
// reverse key schedule order
if (dir == DES_DECRYPTION)
for (i = 0; i < 16; i += 2) {
word32 swap = out[i];
out[i] = out[DES_KEY_SIZE - 2 - i];
out[DES_KEY_SIZE - 2 - i] = swap;
swap = out[i + 1];
out[i + 1] = out[DES_KEY_SIZE - 1 - i];
out[DES_KEY_SIZE - 1 - i] = swap;
}
}
static INLINE int Reverse(int dir)
{
return !dir;
}
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
{
DesSetKey(key, dir, des->key);
memcpy(des->reg, iv, DES_BLOCK_SIZE);
}
void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
{
DesSetKey(key + (dir == DES_ENCRYPTION ? 0 : 16), dir, des->key[0]);
DesSetKey(key + 8, Reverse(dir), des->key[1]);
DesSetKey(key + (dir == DES_DECRYPTION ? 0 : 16), dir, des->key[2]);
memcpy(des->reg, iv, DES_BLOCK_SIZE);
}
void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
{
word32 l = *lIn, r = *rIn, i;
for (i=0; i<8; i++)
{
word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
l ^= Spbox[6][(work) & 0x3f]
^ Spbox[4][(work >> 8) & 0x3f]
^ Spbox[2][(work >> 16) & 0x3f]
^ Spbox[0][(work >> 24) & 0x3f];
work = r ^ kptr[4*i+1];
l ^= Spbox[7][(work) & 0x3f]
^ Spbox[5][(work >> 8) & 0x3f]
^ Spbox[3][(work >> 16) & 0x3f]
^ Spbox[1][(work >> 24) & 0x3f];
work = rotrFixed(l, 4U) ^ kptr[4*i+2];
r ^= Spbox[6][(work) & 0x3f]
^ Spbox[4][(work >> 8) & 0x3f]
^ Spbox[2][(work >> 16) & 0x3f]
^ Spbox[0][(work >> 24) & 0x3f];
work = l ^ kptr[4*i+3];
r ^= Spbox[7][(work) & 0x3f]
^ Spbox[5][(work >> 8) & 0x3f]
^ Spbox[3][(work >> 16) & 0x3f]
^ Spbox[1][(work >> 24) & 0x3f];
}
*lIn = l; *rIn = r;
}
static void DesProcessBlock(Des* des, const byte* in, byte* out)
{
word32 l, r;
memcpy(&l, in, sizeof(l));
memcpy(&r, in + sizeof(l), sizeof(r));
#ifdef LITTLE_ENDIAN_ORDER
l = ByteReverseWord32(l);
r = ByteReverseWord32(r);
#endif
IPERM(&l,&r);
DesRawProcessBlock(&l, &r, des->key);
FPERM(&l,&r);
#ifdef LITTLE_ENDIAN_ORDER
l = ByteReverseWord32(l);
r = ByteReverseWord32(r);
#endif
memcpy(out, &r, sizeof(r));
memcpy(out + sizeof(r), &l, sizeof(l));
}
static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
{
word32 l, r;
memcpy(&l, in, sizeof(l));
memcpy(&r, in + sizeof(l), sizeof(r));
#ifdef LITTLE_ENDIAN_ORDER
l = ByteReverseWord32(l);
r = ByteReverseWord32(r);
#endif
IPERM(&l,&r);
DesRawProcessBlock(&l, &r, des->key[0]);
DesRawProcessBlock(&r, &l, des->key[1]);
DesRawProcessBlock(&l, &r, des->key[2]);
FPERM(&l,&r);
#ifdef LITTLE_ENDIAN_ORDER
l = ByteReverseWord32(l);
r = ByteReverseWord32(r);
#endif
memcpy(out, &r, sizeof(r));
memcpy(out + sizeof(r), &l, sizeof(l));
}
void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
{
word32 blocks = sz / DES_BLOCK_SIZE;
while (blocks--) {
xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
memcpy(out, des->reg, DES_BLOCK_SIZE);
out += DES_BLOCK_SIZE;
in += DES_BLOCK_SIZE;
}
}
void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
{
word32 blocks = sz / DES_BLOCK_SIZE;
byte hold[16];
while (blocks--) {
memcpy(des->tmp, in, DES_BLOCK_SIZE);
DesProcessBlock(des, (byte*)des->tmp, out);
xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
memcpy(hold, des->reg, DES_BLOCK_SIZE);
memcpy(des->reg, des->tmp, DES_BLOCK_SIZE);
memcpy(des->tmp, hold, DES_BLOCK_SIZE);
out += DES_BLOCK_SIZE;
in += DES_BLOCK_SIZE;
}
}
void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
{
word32 blocks = sz / DES_BLOCK_SIZE;
while (blocks--) {
xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
memcpy(out, des->reg, DES_BLOCK_SIZE);
out += DES_BLOCK_SIZE;
in += DES_BLOCK_SIZE;
}
}
void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
{
word32 blocks = sz / DES_BLOCK_SIZE;
byte hold[16];
while (blocks--) {
memcpy(des->tmp, in, DES_BLOCK_SIZE);
Des3ProcessBlock(des, (byte*)des->tmp, out);
xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
memcpy(hold, des->reg, DES_BLOCK_SIZE);
memcpy(des->reg, des->tmp, DES_BLOCK_SIZE);
memcpy(des->tmp, hold, DES_BLOCK_SIZE);
out += DES_BLOCK_SIZE;
in += DES_BLOCK_SIZE;
}
}
#endif /* NO_DES3 */
--- New file ---
+++ extra/cyassl/ctaocrypt/src/dh.c 06/04/05 03:37:01
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_DH
#include "dh.h"
#include "error.h"
#include <assert.h>
#include <math.h>
#ifndef min
static INLINE word32 min(word32 a, word32 b)
{
return a > b ? b : a;
}
#endif /* min */
void InitDhKey(DhKey* key)
{
key->p.dp = 0;
key->g.dp = 0;
}
void FreeDhKey(DhKey* key)
{
mp_clear(&key->p);
mp_clear(&key->g);
}
static word32 DiscreteLogWorkFactor(word32 n)
{
/* assuming discrete log takes about the same time as factoring */
if (n<5)
return 0;
else
return (word32)(2.4 * pow((double)n, 1.0/3.0) *
pow(log((double)n), 2.0/3.0) - 5);
}
static void GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz)
{
word32 sz = mp_unsigned_bin_size(&key->p);
sz = min(sz, 2 * DiscreteLogWorkFactor(sz * BIT_SIZE) / BIT_SIZE + 1);
RNG_GenerateBlock(rng, priv, sz);
priv[0] |= 0x0C;
*privSz = sz;
}
static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz,
byte* pub, word32* pubSz)
{
int ret = 0;
mp_int x;
mp_int y;
if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
return MP_INIT_E;
if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
ret = MP_READ_E;
if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
ret = MP_EXPTMOD_E;
if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
ret = MP_TO_E;
if (ret == 0)
*pubSz = mp_unsigned_bin_size(&y);
mp_clear(&y);
mp_clear(&x);
return ret;
}
int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz,
byte* pub, word32* pubSz)
{
GeneratePrivate(key, rng, priv, privSz);
return GeneratePublic(key, priv, *privSz, pub, pubSz);
}
int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
word32 privSz, const byte* otherPub, word32 pubSz)
{
int ret = 0;
mp_int x;
mp_int y;
mp_int z;
if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
return MP_INIT_E;
if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
ret = MP_READ_E;
if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
ret = MP_READ_E;
if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
ret = MP_EXPTMOD_E;
if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
ret = MP_TO_E;
if (ret == 0)
*agreeSz = mp_unsigned_bin_size(&z);
mp_clear(&z);
mp_clear(&y);
mp_clear(&x);
return ret;
}
#endif /* NO_DH */
--- New file ---
+++ extra/cyassl/ctaocrypt/src/dsa.c 06/05/15 00:17:09
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_DSA
#include "dsa.h"
#include "sha.h"
#include "random.h"
#include "error.h"
#include <assert.h>
enum {
DSA_HALF_SIZE = 20, /* r and s size */
DSA_SIG_SIZE = 40 /* signaure size */
};
#ifndef min
static INLINE word32 min(word32 a, word32 b)
{
return a > b ? b : a;
}
#endif /* min */
void InitDsaKey(DsaKey* key)
{
key->type = -1; /* haven't decdied yet */
key->p.dp = 0; /* public alloc parts */
key->q.dp = 0;
key->g.dp = 0;
key->y.dp = 0;
key->x.dp = 0; /* private alloc parts */
}
void FreeDsaKey(DsaKey* key)
{
if (key->type == DSA_PRIVATE)
mp_clear(&key->x);
mp_clear(&key->y);
mp_clear(&key->g);
mp_clear(&key->q);
mp_clear(&key->p);
}
int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng)
{
mp_int k, kInv, r, s, H;
int ret = 0, sz;
byte buffer[DSA_HALF_SIZE];
if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY)
return MP_INIT_E;
sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q));
/* generate k */
RNG_GenerateBlock(rng, buffer, sz);
buffer[0] |= 0x0C;
if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)
ret = MP_READ_E;
if (mp_cmp_d(&k, 1) != MP_GT) assert(0);
/* inverse k mod q */
if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)
ret = MP_INVMOD_E;
/* generate r, r = (g exp k mod p) mod q */
if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY)
ret = MP_EXPTMOD_E;
if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)
ret = MP_MOD_E;
/* generate H from sha digest */
if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY)
ret = MP_READ_E;
/* generate s, s = (kInv * (H + x*r)) % q */
if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)
ret = MP_MUL_E;
if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)
ret = MP_ADD_E;
if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)
ret = MP_MULMOD_E;
/* write out */
if (ret == 0) {
int rSz = mp_unsigned_bin_size(&r);
int sSz = mp_unsigned_bin_size(&s);
if (rSz == DSA_HALF_SIZE - 1) {
out[0] = 0;
out++;
}
if (mp_to_unsigned_bin(&r, out) != MP_OKAY)
ret = MP_TO_E;
else {
if (sSz == DSA_HALF_SIZE - 1) {
out[rSz] = 0;
out++;
}
ret = mp_to_unsigned_bin(&s, out + rSz);
}
}
mp_clear(&H);
mp_clear(&s);
mp_clear(&r);
mp_clear(&kInv);
mp_clear(&k);
return ret;
}
int DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
{
mp_int w, u1, u2, v, r, s;
int ret = 0;
if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY)
return MP_INIT_E;
/* set r and s from signature */
if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY ||
mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY)
ret = MP_READ_E;
/* sanity checks */
/* put H into u1 from sha digest */
if (ret == 0 && mp_read_unsigned_bin(&u1,digest,SHA_DIGEST_SIZE) != MP_OKAY)
ret = MP_READ_E;
/* w = s invmod q */
if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY)
ret = MP_INVMOD_E;
/* u1 = (H * w) % q */
if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY)
ret = MP_MULMOD_E;
/* u2 = (r * w) % q */
if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY)
ret = MP_MULMOD_E;
/* verify v = ((g^u1 * y^u2) mod p) mod q */
if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY)
ret = MP_EXPTMOD_E;
if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY)
ret = MP_EXPTMOD_E;
if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY)
ret = MP_MULMOD_E;
if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY)
ret = MP_MULMOD_E;
/* do they match */
if (ret == 0 && mp_cmp(&r, &v) == MP_EQ)
*answer = 1;
else
*answer = 0;
mp_clear(&s);
mp_clear(&r);
mp_clear(&u1);
mp_clear(&u2);
mp_clear(&w);
mp_clear(&v);
return ret;
}
#endif /* NO_DSA */
--- New file ---
+++ extra/cyassl/ctaocrypt/src/hmac.c 06/11/23 00:33:56
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef NO_HMAC
#include "hmac.h"
#include <assert.h>
#include <string.h>
static void InitHmac(Hmac* hmac, int type)
{
hmac->innerHashKeyed = 0;
hmac->macType = type;
assert(type == MD5 || type == SHA || type == SHA256);
if (type == MD5)
InitMd5(&hmac->hash.md5);
else if (type == SHA)
InitSha(&hmac->hash.sha);
#ifndef NO_SHA256
else if (type == SHA256)
InitSha256(&hmac->hash.sha256);
#endif
}
void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
{
byte* ip = (byte*) hmac->ipad;
byte* op = (byte*) hmac->opad;
word32 i;
InitHmac(hmac, type);
if (length <= HMAC_BLOCK_SIZE)
memcpy(ip, key, length);
else {
if (hmac->macType == MD5) {
Md5Update(&hmac->hash.md5, key, length);
Md5Final(&hmac->hash.md5, ip);
length = MD5_DIGEST_SIZE;
}
else if (hmac->macType == SHA) {
ShaUpdate(&hmac->hash.sha, key, length);
ShaFinal(&hmac->hash.sha, ip);
length = SHA_DIGEST_SIZE;
}
#ifndef NO_SHA256
else if (hmac->macType == SHA256) {
Sha256Update(&hmac->hash.sha256, key, length);
Sha256Final(&hmac->hash.sha256, ip);
length = SHA256_DIGEST_SIZE;
}
#endif
}
memset(ip + length, 0, HMAC_BLOCK_SIZE - length);
for(i = 0; i < HMAC_BLOCK_SIZE; i++) {
op[i] = ip[i] ^ OPAD;
ip[i] ^= IPAD;
}
}
static void HmacKeyInnerHash(Hmac* hmac)
{
if (hmac->macType == MD5)
Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, HMAC_BLOCK_SIZE);
else if (hmac->macType == SHA)
ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, HMAC_BLOCK_SIZE);
#ifndef NO_SHA256
else if (hmac->macType == SHA256)
Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, HMAC_BLOCK_SIZE);
#endif
hmac->innerHashKeyed = 1;
}
void HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
{
if (!hmac->innerHashKeyed)
HmacKeyInnerHash(hmac);
if (hmac->macType == MD5)
Md5Update(&hmac->hash.md5, msg, length);
else if (hmac->macType == SHA)
ShaUpdate(&hmac->hash.sha, msg, length);
#ifndef NO_SHA256
else if (hmac->macType == SHA256)
Sha256Update(&hmac->hash.sha256, msg, length);
#endif
}
void HmacFinal(Hmac* hmac, byte* hash)
{
if (!hmac->innerHashKeyed)
HmacKeyInnerHash(hmac);
if (hmac->macType == MD5) {
Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash);
Md5Update(&hmac->hash.md5, (byte*) hmac->opad, HMAC_BLOCK_SIZE);
Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE);
Md5Final(&hmac->hash.md5, hash);
}
else if (hmac->macType ==SHA) {
ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash);
ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, HMAC_BLOCK_SIZE);
ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE);
ShaFinal(&hmac->hash.sha, hash);
}
#ifndef NO_SHA256
else if (hmac->macType ==SHA256) {
Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash);
Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, HMAC_BLOCK_SIZE);
Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash,
SHA256_DIGEST_SIZE);
Sha256Final(&hmac->hash.sha256, hash);
}
#endif
hmac->innerHashKeyed = 0;
}
#endif /* NO_HMAC */
--- New file ---
+++ extra/cyassl/ctaocrypt/src/integer.c 06/04/05 03:37:03
/*
Copyright (C) 2000-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
/*
* Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@stripped,
* http://math.libtomcrypt.org
*/
#include "integer.h"
#include <stdlib.h>
/* handle up to 6 inits */
int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
mp_int* f)
{
int res = MP_OKAY;
if (a && ((res = mp_init(a)) != MP_OKAY))
return res;
if (b && ((res = mp_init(b)) != MP_OKAY)) {
mp_clear(a);
return res;
}
if (c && ((res = mp_init(c)) != MP_OKAY)) {
mp_clear(a); mp_clear(b);
return res;
}
if (d && ((res = mp_init(d)) != MP_OKAY)) {
mp_clear(a); mp_clear(b); mp_clear(c);
return res;
}
if (e && ((res = mp_init(e)) != MP_OKAY)) {
mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d);
return res;
}
if (f && ((res = mp_init(f)) != MP_OKAY)) {
mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); mp_clear(e);
return res;
}
return res;
}
/* init a new mp_int */
int mp_init (mp_int * a)
{
int i;
/* allocate memory required and clear it */
a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
if (a->dp == NULL) {
return MP_MEM;
}
/* set the digits to zero */
for (i = 0; i < MP_PREC; i++) {
a->dp[i] = 0;
}
/* set the used to zero, allocated digits to the default precision
* and sign to positive */
a->used = 0;
a->alloc = MP_PREC;
a->sign = MP_ZPOS;
return MP_OKAY;
}
/* clear one (frees) */
void
mp_clear (mp_int * a)
{
int i;
/* only do anything if a hasn't been freed previously */
if (a->dp != NULL) {
/* first zero the digits */
for (i = 0; i < a->used; i++) {
a->dp[i] = 0;
}
/* free ram */
XFREE(a->dp);
/* reset members to make debugging easier */
a->dp = NULL;
a->alloc = a->used = 0;
a->sign = MP_ZPOS;
}
}
/* get the size for an unsigned equivalent */
int mp_unsigned_bin_size (mp_int * a)
{
int size = mp_count_bits (a);
return (size / 8 + ((size & 7) != 0 ? 1 : 0));
}
/* returns the number of bits in an int */
int
mp_count_bits (mp_int * a)
{
int r;
mp_digit q;
/* shortcut */
if (a->used == 0) {
return 0;
}
/* get number of digits and add that */
r = (a->used - 1) * DIGIT_BIT;
/* take the last digit and count the bits in it */
q = a->dp[a->used - 1];
while (q > ((mp_digit) 0)) {
++r;
q >>= ((mp_digit) 1);
}
return r;
}
/* store in unsigned [big endian] format */
int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
{
int x, res;
mp_int t;
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
return res;
}
x = 0;
while (mp_iszero (&t) == 0) {
#ifndef MP_8BIT
b[x++] = (unsigned char) (t.dp[0] & 255);
#else
b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
#endif
if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
mp_clear (&t);
return res;
}
}
bn_reverse (b, x);
mp_clear (&t);
return MP_OKAY;
}
/* creates "a" then copies b into it */
int mp_init_copy (mp_int * a, mp_int * b)
{
int res;
if ((res = mp_init (a)) != MP_OKAY) {
return res;
}
return mp_copy (b, a);
}
/* copy, b = a */
int
mp_copy (mp_int * a, mp_int * b)
{
int res, n;
/* if dst == src do nothing */
if (a == b) {
return MP_OKAY;
}
/* grow dest */
if (b->alloc < a->used) {
if ((res = mp_grow (b, a->used)) != MP_OKAY) {
return res;
}
}
/* zero b and copy the parameters over */
{
register mp_digit *tmpa, *tmpb;
/* pointer aliases */
/* source */
tmpa = a->dp;
/* destination */
tmpb = b->dp;
/* copy all the digits */
for (n = 0; n < a->used; n++) {
*tmpb++ = *tmpa++;
}
/* clear high digits */
for (; n < b->used; n++) {
*tmpb++ = 0;
}
}
/* copy used count and sign */
b->used = a->used;
b->sign = a->sign;
return MP_OKAY;
}
/* grow as required */
int mp_grow (mp_int * a, int size)
{
int i;
mp_digit *tmp;
/* if the alloc size is smaller alloc more ram */
if (a->alloc < size) {
/* ensure there are always at least MP_PREC digits extra on top */
size += (MP_PREC * 2) - (size % MP_PREC);
/* reallocate the array a->dp
*
* We store the return in a temporary variable
* in case the operation failed we don't want
* to overwrite the dp member of a.
*/
tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
if (tmp == NULL) {
/* reallocation failed but "a" is still valid [can be freed] */
return MP_MEM;
}
/* reallocation succeeded so set a->dp */
a->dp = tmp;
/* zero excess digits */
i = a->alloc;
a->alloc = size;
for (; i < a->alloc; i++) {
a->dp[i] = 0;
}
}
return MP_OKAY;
}
/* reverse an array, used for radix code */
void
bn_reverse (unsigned char *s, int len)
{
int ix, iy;
unsigned char t;
ix = 0;
iy = len - 1;
while (ix < iy) {
t = s[ix];
s[ix] = s[iy];
s[iy] = t;
++ix;
--iy;
}
}
/* shift right by a certain bit count (store quotient in c, optional
remainder in d) */
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
{
mp_digit D, r, rr;
int x, res;
mp_int t;
/* if the shift count is <= 0 then we do no work */
if (b <= 0) {
res = mp_copy (a, c);
if (d != NULL) {
mp_zero (d);
}
return res;
}
if ((res = mp_init (&t)) != MP_OKAY) {
return res;
}
/* get the remainder */
if (d != NULL) {
if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
mp_clear (&t);
return res;
}
}
/* copy */
if ((res = mp_copy (a, c)) != MP_OKAY) {
mp_clear (&t);
return res;
}
/* shift by as many digits in the bit count */
if (b >= (int)DIGIT_BIT) {
mp_rshd (c, b / DIGIT_BIT);
}
/* shift any bit count < DIGIT_BIT */
D = (mp_digit) (b % DIGIT_BIT);
if (D != 0) {
register mp_digit *tmpc, mask, shift;
/* mask */
mask = (((mp_digit)1) << D) - 1;
/* shift for lsb */
shift = DIGIT_BIT - D;
/* alias */
tmpc = c->dp + (c->used - 1);
/* carry */
r = 0;
for (x = c->used - 1; x >= 0; x--) {
/* get the lower bits of this word in a temp */
rr = *tmpc & mask;
/* shift the current word and mix in the carry bits from the previous
word */
*tmpc = (*tmpc >> D) | (r << shift);
--tmpc;
/* set the carry to the carry bits of the current word found above */
r = rr;
}
}
mp_clamp (c);
if (d != NULL) {
mp_exch (&t, d);
}
mp_clear (&t);
return MP_OKAY;
}
/* set to zero */
void mp_zero (mp_int * a)
{
int n;
mp_digit *tmp;
a->sign = MP_ZPOS;
a->used = 0;
tmp = a->dp;
for (n = 0; n < a->alloc; n++) {
*tmp++ = 0;
}
}
/* trim unused digits
*
* This is used to ensure that leading zero digits are
* trimed and the leading "used" digit will be non-zero
* Typically very fast. Also fixes the sign if there
* are no more leading digits
*/
void
mp_clamp (mp_int * a)
{
/* decrease used while the most significant digit is
* zero.
*/
while (a->used > 0 && a->dp[a->used - 1] == 0) {
--(a->used);
}
/* reset the sign flag if used == 0 */
if (a->used == 0) {
a->sign = MP_ZPOS;
}
}
/* swap the elements of two integers, for cases where you can't simply swap the
* mp_int pointers around
*/
void
mp_exch (mp_int * a, mp_int * b)
{
mp_int t;
t = *a;
*a = *b;
*b = t;
}
/* shift right a certain amount of digits */
void mp_rshd (mp_int * a, int b)
{
int x;
/* if b <= 0 then ignore it */
if (b <= 0) {
return;
}
/* if b > used then simply zero it and return */
if (a->used <= b) {
mp_zero (a);
return;
}
{
register mp_digit *bottom, *top;
/* shift the digits down */
/* bottom */
bottom = a->dp;
/* top [offset into digits] */
top = a->dp + b;
/* this is implemented as a sliding window where
* the window is b-digits long and digits from
* the top of the window are copied to the bottom
*
* e.g.
b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
/\ | ---->
\-------------------/ ---->
*/
for (x = 0; x < (a->used - b); x++) {
*bottom++ = *top++;
}
/* zero the top digits */
for (; x < a->used; x++) {
*bottom++ = 0;
}
}
/* remove excess digits */
a->used -= b;
}
/* calc a value mod 2**b */
int
mp_mod_2d (mp_int * a, int b, mp_int * c)
{
int x, res;
/* if b is <= 0 then zero the int */
if (b <= 0) {
mp_zero (c);
return MP_OKAY;
}
/* if the modulus is larger than the value than return */
if (b >= (int) (a->used * DIGIT_BIT)) {
res = mp_copy (a, c);
return res;
}
/* copy */
if ((res = mp_copy (a, c)) != MP_OKAY) {
return res;
}
/* zero digits above the last digit of the modulus */
for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
c->dp[x] = 0;
}
/* clear the digit that is not completely outside/inside the modulus */
c->dp[b / DIGIT_BIT] &= (mp_digit) ((((mp_digit) 1) <<
(((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
mp_clamp (c);
return MP_OKAY;
}
/* reads a unsigned char array, assumes the msb is stored first [big endian] */
int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
{
int res;
/* make sure there are at least two digits */
if (a->alloc < 2) {
if ((res = mp_grow(a, 2)) != MP_OKAY) {
return res;
}
}
/* zero the int */
mp_zero (a);
/* read the bytes in */
while (c-- > 0) {
if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
return res;
}
#ifndef MP_8BIT
a->dp[0] |= *b++;
a->used += 1;
#else
a->dp[0] = (*b & MP_MASK);
a->dp[1] |= ((*b++ >> 7U) & 1);
a->used += 2;
#endif
}
mp_clamp (a);
return MP_OKAY;
}
/* shift left by a certain bit count */
int mp_mul_2d (mp_int * a, int b, mp_int * c)
{
mp_digit d;
int res;
/* copy */
if (a != c) {
if ((res = mp_copy (a, c)) != MP_OKAY) {
return res;
}
}
if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
return res;
}
}
/* shift by as many digits in the bit count */
if (b >= (int)DIGIT_BIT) {
if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
return res;
}
}
/* shift any bit count < DIGIT_BIT */
d = (mp_digit) (b % DIGIT_BIT);
if (d != 0) {
register mp_digit *tmpc, shift, mask, r, rr;
register int x;
/* bitmask for carries */
mask = (((mp_digit)1) << d) - 1;
/* shift for msbs */
shift = DIGIT_BIT - d;
/* alias */
tmpc = c->dp;
/* carry */
r = 0;
for (x = 0; x < c->used; x++) {
/* get the higher bits of the current word */
rr = (*tmpc >> shift) & mask;
/* shift the current word and OR in the carry */
*tmpc = ((*tmpc << d) | r) & MP_MASK;
++tmpc;
/* set the carry to the carry bits of the current word */
r = rr;
}
/* set final carry */
if (r != 0) {
c->dp[(c->used)++] = r;
}
}
mp_clamp (c);
return MP_OKAY;
}
/* shift left a certain amount of digits */
int mp_lshd (mp_int * a, int b)
{
int x, res;
/* if its less than zero return */
if (b <= 0) {
return MP_OKAY;
}
/* grow to fit the new digits */
if (a->alloc < a->used + b) {
if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
return res;
}
}
{
register mp_digit *top, *bottom;
/* increment the used by the shift amount then copy upwards */
a->used += b;
/* top */
top = a->dp + a->used - 1;
/* base */
bottom = a->dp + a->used - 1 - b;
/* much like mp_rshd this is implemented using a sliding window
* except the window goes the otherway around. Copying from
* the bottom to the top. see bn_mp_rshd.c for more info.
*/
for (x = a->used - 1; x >= b; x--) {
*top-- = *bottom--;
}
/* zero the lower digits */
top = a->dp;
for (x = 0; x < b; x++) {
*top++ = 0;
}
}
return MP_OKAY;
}
/* this is a shell function that calls either the normal or Montgomery
* exptmod functions. Originally the call to the montgomery code was
* embedded in the normal function but that wasted alot of stack space
* for nothing (since 99% of the time the Montgomery code would be called)
*/
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
{
int dr;
/* modulus P must be positive */
if (P->sign == MP_NEG) {
return MP_VAL;
}
/* if exponent X is negative we have to recurse */
if (X->sign == MP_NEG) {
#ifdef BN_MP_INVMOD_C
mp_int tmpG, tmpX;
int err;
/* first compute 1/G mod P */
if ((err = mp_init(&tmpG)) != MP_OKAY) {
return err;
}
if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
mp_clear(&tmpG);
return err;
}
/* now get |X| */
if ((err = mp_init(&tmpX)) != MP_OKAY) {
mp_clear(&tmpG);
return err;
}
if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
mp_clear(&tmpG);
mp_clear(&tmpX);
return err;
}
/* and now compute (1/G)**|X| instead of G**X [X < 0] */
err = mp_exptmod(&tmpG, &tmpX, P, Y);
mp_clear(&tmpG);
mp_clear(&tmpX);
return err;
#else
/* no invmod */
return MP_VAL;
#endif
}
/* modified diminished radix reduction */
#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && \
defined(BN_S_MP_EXPTMOD_C)
if (mp_reduce_is_2k_l(P) == MP_YES) {
return s_mp_exptmod(G, X, P, Y, 1);
}
#endif
#ifdef BN_MP_DR_IS_MODULUS_C
/* is it a DR modulus? */
dr = mp_dr_is_modulus(P);
#else
/* default to no */
dr = 0;
#endif
#ifdef BN_MP_REDUCE_IS_2K_C
/* if not, is it a unrestricted DR modulus? */
if (dr == 0) {
dr = mp_reduce_is_2k(P) << 1;
}
#endif
/* if the modulus is odd or dr != 0 use the montgomery method */
#ifdef BN_MP_EXPTMOD_FAST_C
if (mp_isodd (P) == 1 || dr != 0) {
return mp_exptmod_fast (G, X, P, Y, dr);
} else {
#endif
#ifdef BN_S_MP_EXPTMOD_C
/* otherwise use the generic Barrett reduction technique */
return s_mp_exptmod (G, X, P, Y, 0);
#else
/* no exptmod for evens */
return MP_VAL;
#endif
#ifdef BN_MP_EXPTMOD_FAST_C
}
#endif
}
/* b = |a|
*
* Simple function copies the input and fixes the sign to positive
*/
int
mp_abs (mp_int * a, mp_int * b)
{
int res;
/* copy a to b */
if (a != b) {
if ((res = mp_copy (a, b)) != MP_OKAY) {
return res;
}
}
/* force the sign of b to positive */
b->sign = MP_ZPOS;
return MP_OKAY;
}
/* hac 14.61, pp608 */
int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
{
/* b cannot be negative */
if (b->sign == MP_NEG || mp_iszero(b) == 1) {
return MP_VAL;
}
#ifdef BN_FAST_MP_INVMOD_C
/* if the modulus is odd we can use a faster routine instead */
if (mp_isodd (b) == 1) {
return fast_mp_invmod (a, b, c);
}
#endif
#ifdef BN_MP_INVMOD_SLOW_C
return mp_invmod_slow(a, b, c);
#endif
return MP_VAL;
}
/* computes the modular inverse via binary extended euclidean algorithm,
* that is c = 1/a mod b
*
* Based on slow invmod except this is optimized for the case where b is
* odd as per HAC Note 14.64 on pp. 610
*/
int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
{
mp_int x, y, u, v, B, D;
int res, neg;
/* 2. [modified] b must be odd */
if (mp_iseven (b) == 1) {
return MP_VAL;
}
/* init all our temps */
if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D)) != MP_OKAY) {
return res;
}
/* x == modulus, y == value to invert */
if ((res = mp_copy (b, &x)) != MP_OKAY) {
goto LBL_ERR;
}
/* we need y = |a| */
if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
goto LBL_ERR;
}
/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
if ((res = mp_copy (&x, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_copy (&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
mp_set (&D, 1);
top:
/* 4. while u is even do */
while (mp_iseven (&u) == 1) {
/* 4.1 u = u/2 */
if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
/* 4.2 if B is odd then */
if (mp_isodd (&B) == 1) {
if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* B = B/2 */
if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* 5. while v is even do */
while (mp_iseven (&v) == 1) {
/* 5.1 v = v/2 */
if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
/* 5.2 if D is odd then */
if (mp_isodd (&D) == 1) {
/* D = (D-x)/2 */
if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* D = D/2 */
if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* 6. if u >= v then */
if (mp_cmp (&u, &v) != MP_LT) {
/* u = u - v, B = B - D */
if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
goto LBL_ERR;
}
} else {
/* v - v - u, D = D - B */
if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* if not zero goto step 4 */
if (mp_iszero (&u) == 0) {
goto top;
}
/* now a = C, b = D, gcd == g*v */
/* if v != 1 then there is no inverse */
if (mp_cmp_d (&v, 1) != MP_EQ) {
res = MP_VAL;
goto LBL_ERR;
}
/* b is now the inverse */
neg = a->sign;
while (D.sign == MP_NEG) {
if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
mp_exch (&D, c);
c->sign = neg;
res = MP_OKAY;
LBL_ERR:mp_clear(&x);
mp_clear(&y);
mp_clear(&u);
mp_clear(&v);
mp_clear(&B);
mp_clear(&D);
return res;
}
/* hac 14.61, pp608 */
int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
{
mp_int x, y, u, v, A, B, C, D;
int res;
/* b cannot be negative */
if (b->sign == MP_NEG || mp_iszero(b) == 1) {
return MP_VAL;
}
/* init temps */
if ((res = mp_init_multi(&x, &y, &u, &v,
&A, &B)) != MP_OKAY) {
return res;
}
/* init rest of tmps temps */
if ((res = mp_init_multi(&C, &D, 0, 0, 0, 0)) != MP_OKAY) {
return res;
}
/* x = a, y = b */
if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_copy (b, &y)) != MP_OKAY) {
goto LBL_ERR;
}
/* 2. [modified] if x,y are both even then return an error! */
if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
res = MP_VAL;
goto LBL_ERR;
}
/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
if ((res = mp_copy (&x, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_copy (&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
mp_set (&A, 1);
mp_set (&D, 1);
top:
/* 4. while u is even do */
while (mp_iseven (&u) == 1) {
/* 4.1 u = u/2 */
if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
/* 4.2 if A or B is odd then */
if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
/* A = (A+y)/2, B = (B-x)/2 */
if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* A = A/2, B = B/2 */
if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* 5. while v is even do */
while (mp_iseven (&v) == 1) {
/* 5.1 v = v/2 */
if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
/* 5.2 if C or D is odd then */
if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
/* C = (C+y)/2, D = (D-x)/2 */
if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* C = C/2, D = D/2 */
if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* 6. if u >= v then */
if (mp_cmp (&u, &v) != MP_LT) {
/* u = u - v, A = A - C, B = B - D */
if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
goto LBL_ERR;
}
} else {
/* v - v - u, C = C - A, D = D - B */
if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* if not zero goto step 4 */
if (mp_iszero (&u) == 0)
goto top;
/* now a = C, b = D, gcd == g*v */
/* if v != 1 then there is no inverse */
if (mp_cmp_d (&v, 1) != MP_EQ) {
res = MP_VAL;
goto LBL_ERR;
}
/* if its too low */
while (mp_cmp_d(&C, 0) == MP_LT) {
if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* too big */
while (mp_cmp_mag(&C, b) != MP_LT) {
if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* C is now the inverse */
mp_exch (&C, c);
res = MP_OKAY;
LBL_ERR:mp_clear(&x);
mp_clear(&y);
mp_clear(&u);
mp_clear(&v);
mp_clear(&A);
mp_clear(&B);
mp_clear(&C);
mp_clear(&D);
return res;
}
/* compare maginitude of two ints (unsigned) */
int mp_cmp_mag (mp_int * a, mp_int * b)
{
int n;
mp_digit *tmpa, *tmpb;
/* compare based on # of non-zero digits */
if (a->used > b->used) {
return MP_GT;
}
if (a->used < b->used) {
return MP_LT;
}
/* alias for a */
tmpa = a->dp + (a->used - 1);
/* alias for b */
tmpb = b->dp + (a->used - 1);
/* compare based on digits */
for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
if (*tmpa > *tmpb) {
return MP_GT;
}
if (*tmpa < *tmpb) {
return MP_LT;
}
}
return MP_EQ;
}
/* compare two ints (signed)*/
int
mp_cmp (mp_int * a, mp_int * b)
{
/* compare based on sign */
if (a->sign != b->sign) {
if (a->sign == MP_NEG) {
return MP_LT;
} else {
return MP_GT;
}
}
/* compare digits */
if (a->sign == MP_NEG) {
/* if negative compare opposite direction */
return mp_cmp_mag(b, a);
} else {
return mp_cmp_mag(a, b);
}
}
/* compare a digit */
int mp_cmp_d(mp_int * a, mp_digit b)
{
/* compare based on sign */
if (a->sign == MP_NEG) {
return MP_LT;
}
/* compare based on magnitude */
if (a->used > 1) {
return MP_GT;
}
/* compare the only digit of a to b */
if (a->dp[0] > b) {
return MP_GT;
} else if (a->dp[0] < b) {
return MP_LT;
} else {
return MP_EQ;
}
}
/* set to a digit */
void mp_set (mp_int * a, mp_digit b)
{
mp_zero (a);
a->dp[0] = b & MP_MASK;
a->used = (a->dp[0] != 0) ? 1 : 0;
}
/* c = a mod b, 0 <= c < b */
int
mp_mod (mp_int * a, mp_int * b, mp_int * c)
{
mp_int t;
int res;
if ((res = mp_init (&t)) != MP_OKAY) {
return res;
}
if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
mp_clear (&t);
return res;
}
if (t.sign != b->sign) {
res = mp_add (b, &t, c);
} else {
res = MP_OKAY;
mp_exch (&t, c);
}
mp_clear (&t);
return res;
}
/* slower bit-bang division... also smaller */
int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
{
mp_int ta, tb, tq, q;
int res, n, n2;
/* is divisor zero ? */
if (mp_iszero (b) == 1) {
return MP_VAL;
}
/* if a < b then q=0, r = a */
if (mp_cmp_mag (a, b) == MP_LT) {
if (d != NULL) {
res = mp_copy (a, d);
} else {
res = MP_OKAY;
}
if (c != NULL) {
mp_zero (c);
}
return res;
}
/* init our temps */
if ((res = mp_init_multi(&ta, &tb, &tq, &q, 0, 0) != MP_OKAY)) {
return res;
}
mp_set(&tq, 1);
n = mp_count_bits(a) - mp_count_bits(b);
if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
((res = mp_abs(b, &tb)) != MP_OKAY) ||
((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
goto LBL_ERR;
}
while (n-- >= 0) {
if (mp_cmp(&tb, &ta) != MP_GT) {
if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
goto LBL_ERR;
}
}
if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
goto LBL_ERR;
}
}
/* now q == quotient and ta == remainder */
n = a->sign;
n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
if (c != NULL) {
mp_exch(c, &q);
c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
}
if (d != NULL) {
mp_exch(d, &ta);
d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
}
LBL_ERR:
mp_clear(&ta);
mp_clear(&tb);
mp_clear(&tq);
mp_clear(&q);
return res;
}
/* b = a/2 */
int mp_div_2(mp_int * a, mp_int * b)
{
int x, res, oldused;
/* copy */
if (b->alloc < a->used) {
if ((res = mp_grow (b, a->used)) != MP_OKAY) {
return res;
}
}
oldused = b->used;
b->used = a->used;
{
register mp_digit r, rr, *tmpa, *tmpb;
/* source alias */
tmpa = a->dp + b->used - 1;
/* dest alias */
tmpb = b->dp + b->used - 1;
/* carry */
r = 0;
for (x = b->used - 1; x >= 0; x--) {
/* get the carry for the next iteration */
rr = *tmpa & 1;
/* shift the current digit, add in carry and store */
*tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
/* forward carry to next iteration */
r = rr;
}
/* zero excess digits */
tmpb = b->dp + b->used;
for (x = b->used; x < oldused; x++) {
*tmpb++ = 0;
}
}
b->sign = a->sign;
mp_clamp (b);
return MP_OKAY;
}
/* high level addition (handles signs) */
int mp_add (mp_int * a, mp_int * b, mp_int * c)
{
int sa, sb, res;
/* get sign of both inputs */
sa = a->sign;
sb = b->sign;
/* handle two cases, not four */
if (sa == sb) {
/* both positive or both negative */
/* add their magnitudes, copy the sign */
c->sign = sa;
res = s_mp_add (a, b, c);
} else {
/* one positive, the other negative */
/* subtract the one with the greater magnitude from */
/* the one of the lesser magnitude. The result gets */
/* the sign of the one with the greater magnitude. */
if (mp_cmp_mag (a, b) == MP_LT) {
c->sign = sb;
res = s_mp_sub (b, a, c);
} else {
c->sign = sa;
res = s_mp_sub (a, b, c);
}
}
return res;
}
/* low level addition, based on HAC pp.594, Algorithm 14.7 */
int
s_mp_add (mp_int * a, mp_int * b, mp_int * c)
{
mp_int *x;
int olduse, res, min, max;
/* find sizes, we let |a| <= |b| which means we have to sort
* them. "x" will point to the input with the most digits
*/
if (a->used > b->used) {
min = b->used;
max = a->used;
x = a;
} else {
min = a->used;
max = b->used;
x = b;
}
/* init result */
if (c->alloc < max + 1) {
if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
return res;
}
}
/* get old used digit count and set new one */
olduse = c->used;
c->used = max + 1;
{
register mp_digit u, *tmpa, *tmpb, *tmpc;
register int i;
/* alias for digit pointers */
/* first input */
tmpa = a->dp;
/* second input */
tmpb = b->dp;
/* destination */
tmpc = c->dp;
/* zero the carry */
u = 0;
for (i = 0; i < min; i++) {
/* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
*tmpc = *tmpa++ + *tmpb++ + u;
/* U = carry bit of T[i] */
u = *tmpc >> ((mp_digit)DIGIT_BIT);
/* take away carry bit from T[i] */
*tmpc++ &= MP_MASK;
}
/* now copy higher words if any, that is in A+B
* if A or B has more digits add those in
*/
if (min != max) {
for (; i < max; i++) {
/* T[i] = X[i] + U */
*tmpc = x->dp[i] + u;
/* U = carry bit of T[i] */
u = *tmpc >> ((mp_digit)DIGIT_BIT);
/* take away carry bit from T[i] */
*tmpc++ &= MP_MASK;
}
}
/* add carry */
*tmpc++ = u;
/* clear digits above oldused */
for (i = c->used; i < olduse; i++) {
*tmpc++ = 0;
}
}
mp_clamp (c);
return MP_OKAY;
}
/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
int
s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
{
int olduse, res, min, max;
/* find sizes */
min = b->used;
max = a->used;
/* init result */
if (c->alloc < max) {
if ((res = mp_grow (c, max)) != MP_OKAY) {
return res;
}
}
olduse = c->used;
c->used = max;
{
register mp_digit u, *tmpa, *tmpb, *tmpc;
register int i;
/* alias for digit pointers */
tmpa = a->dp;
tmpb = b->dp;
tmpc = c->dp;
/* set carry to zero */
u = 0;
for (i = 0; i < min; i++) {
/* T[i] = A[i] - B[i] - U */
*tmpc = *tmpa++ - *tmpb++ - u;
/* U = carry bit of T[i]
* Note this saves performing an AND operation since
* if a carry does occur it will propagate all the way to the
* MSB. As a result a single shift is enough to get the carry
*/
u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
/* Clear carry from T[i] */
*tmpc++ &= MP_MASK;
}
/* now copy higher words if any, e.g. if A has more digits than B */
for (; i < max; i++) {
/* T[i] = A[i] - U */
*tmpc = *tmpa++ - u;
/* U = carry bit of T[i] */
u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
/* Clear carry from T[i] */
*tmpc++ &= MP_MASK;
}
/* clear digits above used (since we may not have grown result above) */
for (i = c->used; i < olduse; i++) {
*tmpc++ = 0;
}
}
mp_clamp (c);
return MP_OKAY;
}
/* high level subtraction (handles signs) */
int
mp_sub (mp_int * a, mp_int * b, mp_int * c)
{
int sa, sb, res;
sa = a->sign;
sb = b->sign;
if (sa != sb) {
/* subtract a negative from a positive, OR */
/* subtract a positive from a negative. */
/* In either case, ADD their magnitudes, */
/* and use the sign of the first number. */
c->sign = sa;
res = s_mp_add (a, b, c);
} else {
/* subtract a positive from a positive, OR */
/* subtract a negative from a negative. */
/* First, take the difference between their */
/* magnitudes, then... */
if (mp_cmp_mag (a, b) != MP_LT) {
/* Copy the sign from the first */
c->sign = sa;
/* The first has a larger or equal magnitude */
res = s_mp_sub (a, b, c);
} else {
/* The result has the *opposite* sign from */
/* the first number. */
c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
/* The second has a larger magnitude */
res = s_mp_sub (b, a, c);
}
}
return res;
}
/* determines if reduce_2k_l can be used */
int mp_reduce_is_2k_l(mp_int *a)
{
int ix, iy;
if (a->used == 0) {
return MP_NO;
} else if (a->used == 1) {
return MP_YES;
} else if (a->used > 1) {
/* if more than half of the digits are -1 we're sold */
for (iy = ix = 0; ix < a->used; ix++) {
if (a->dp[ix] == MP_MASK) {
++iy;
}
}
return (iy >= (a->used/2)) ? MP_YES : MP_NO;
}
return MP_NO;
}
/* determines if mp_reduce_2k can be used */
int mp_reduce_is_2k(mp_int *a)
{
int ix, iy, iw;
mp_digit iz;
if (a->used == 0) {
return MP_NO;
} else if (a->used == 1) {
return MP_YES;
} else if (a->used > 1) {
iy = mp_count_bits(a);
iz = 1;
iw = 1;
/* Test every bit from the second digit up, must be 1 */
for (ix = DIGIT_BIT; ix < iy; ix++) {
if ((a->dp[iw] & iz) == 0) {
return MP_NO;
}
iz <<= 1;
if (iz > (mp_digit)MP_MASK) {
++iw;
iz = 1;
}
}
}
return MP_YES;
}
/* determines if a number is a valid DR modulus */
int mp_dr_is_modulus(mp_int *a)
{
int ix;
/* must be at least two digits */
if (a->used < 2) {
return 0;
}
/* must be of the form b**k - a [a <= b] so all
* but the first digit must be equal to -1 (mod b).
*/
for (ix = 1; ix < a->used; ix++) {
if (a->dp[ix] != MP_MASK) {
return 0;
}
}
return 1;
}
/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
*
* Uses a left-to-right k-ary sliding window to compute the modular
* exponentiation.
* The value of k changes based on the size of the exponent.
*
* Uses Montgomery or Diminished Radix reduction [whichever appropriate]
*/
#ifdef MP_LOW_MEM
#define TAB_SIZE 32
#else
#define TAB_SIZE 256
#endif
int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
int redmode)
{
mp_int M[TAB_SIZE], res;
mp_digit buf, mp;
int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
/* use a pointer to the reduction algorithm. This allows us to use
* one of many reduction algorithms without modding the guts of
* the code with if statements everywhere.
*/
int (*redux)(mp_int*,mp_int*,mp_digit);
/* find window size */
x = mp_count_bits (X);
if (x <= 7) {
winsize = 2;
} else if (x <= 36) {
winsize = 3;
} else if (x <= 140) {
winsize = 4;
} else if (x <= 450) {
winsize = 5;
} else if (x <= 1303) {
winsize = 6;
} else if (x <= 3529) {
winsize = 7;
} else {
winsize = 8;
}
#ifdef MP_LOW_MEM
if (winsize > 5) {
winsize = 5;
}
#endif
/* init M array */
/* init first cell */
if ((err = mp_init(&M[1])) != MP_OKAY) {
return err;
}
/* now init the second half of the array */
for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
if ((err = mp_init(&M[x])) != MP_OKAY) {
for (y = 1<<(winsize-1); y < x; y++) {
mp_clear (&M[y]);
}
mp_clear(&M[1]);
return err;
}
}
/* determine and setup reduction code */
if (redmode == 0) {
#ifdef BN_MP_MONTGOMERY_SETUP_C
/* now setup montgomery */
if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
goto LBL_M;
}
#else
err = MP_VAL;
goto LBL_M;
#endif
/* automatically pick the comba one if available (saves quite a few
calls/ifs) */
#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
if (((P->used * 2 + 1) < MP_WARRAY) &&
P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
redux = fast_mp_montgomery_reduce;
} else
#endif
{
#ifdef BN_MP_MONTGOMERY_REDUCE_C
/* use slower baseline Montgomery method */
redux = mp_montgomery_reduce;
#else
err = MP_VAL;
goto LBL_M;
#endif
}
} else if (redmode == 1) {
#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
/* setup DR reduction for moduli of the form B**k - b */
mp_dr_setup(P, &mp);
redux = mp_dr_reduce;
#else
err = MP_VAL;
goto LBL_M;
#endif
} else {
#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
/* setup DR reduction for moduli of the form 2**k - b */
if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
goto LBL_M;
}
redux = mp_reduce_2k;
#else
err = MP_VAL;
goto LBL_M;
#endif
}
/* setup result */
if ((err = mp_init (&res)) != MP_OKAY) {
goto LBL_M;
}
/* create M table
*
*
* The first half of the table is not computed though accept for M[0] and M[1]
*/
if (redmode == 0) {
#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
/* now we need R mod m */
if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
goto LBL_RES;
}
#else
err = MP_VAL;
goto LBL_RES;
#endif
/* now set M[1] to G * R mod m */
if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
} else {
mp_set(&res, 1);
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
}
/* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times*/
if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_RES;
}
for (x = 0; x < (winsize - 1); x++) {
if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* create upper table */
for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* set initial mode and bit cnt */
mode = 0;
bitcnt = 1;
buf = 0;
digidx = X->used - 1;
bitcpy = 0;
bitbuf = 0;
for (;;) {
/* grab next digit as required */
if (--bitcnt == 0) {
/* if digidx == -1 we are out of digits so break */
if (digidx == -1) {
break;
}
/* read next digit and reset bitcnt */
buf = X->dp[digidx--];
bitcnt = (int)DIGIT_BIT;
}
/* grab the next msb from the exponent */
y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
buf <<= (mp_digit)1;
/* if the bit is zero and mode == 0 then we ignore it
* These represent the leading zero bits before the first 1 bit
* in the exponent. Technically this opt is not required but it
* does lower the # of trivial squaring/reductions used
*/
if (mode == 0 && y == 0) {
continue;
}
/* if the bit is zero and mode == 1 then we square */
if (mode == 1 && y == 0) {
if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
continue;
}
/* else we add it to the window */
bitbuf |= (y << (winsize - ++bitcpy));
mode = 2;
if (bitcpy == winsize) {
/* ok window is filled so square as required and multiply */
/* square first */
for (x = 0; x < winsize; x++) {
if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* then multiply */
if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
/* empty window and reset */
bitcpy = 0;
bitbuf = 0;
mode = 1;
}
}
/* if bits remain then square/multiply */
if (mode == 2 && bitcpy > 0) {
/* square then multiply if the bit is set */
for (x = 0; x < bitcpy; x++) {
if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
/* get next bit of the window */
bitbuf <<= 1;
if ((bitbuf & (1 << winsize)) != 0) {
/* then multiply */
if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
}
}
if (redmode == 0) {
/* fixup result if Montgomery reduction is used
* recall that any value in a Montgomery system is
* actually multiplied by R mod n. So we have
* to reduce one more time to cancel out the factor
* of R.
*/
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* swap res with Y */
mp_exch (&res, Y);
err = MP_OKAY;
LBL_RES:mp_clear (&res);
LBL_M:
mp_clear(&M[1]);
for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
mp_clear (&M[x]);
}
return err;
}
/* setups the montgomery reduction stuff */
int
mp_montgomery_setup (mp_int * n, mp_digit * rho)
{
mp_digit x, b;
/* fast inversion mod 2**k
*
* Based on the fact that
*
* XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
* => 2*X*A - X*X*A*A = 1
* => 2*(1) - (1) = 1
*/
b = n->dp[0];
if ((b & 1) == 0) {
return MP_VAL;
}
x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
x *= 2 - b * x; /* here x*a==1 mod 2**8 */
#if !defined(MP_8BIT)
x *= 2 - b * x; /* here x*a==1 mod 2**16 */
#endif
#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
x *= 2 - b * x; /* here x*a==1 mod 2**32 */
#endif
#ifdef MP_64BIT
x *= 2 - b * x; /* here x*a==1 mod 2**64 */
#endif
/* rho = -1/m mod b */
/* TAO, switched mp_word casts to mp_digit to shut up compiler */
*rho = (((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK;
return MP_OKAY;
}
/* computes xR**-1 == x (mod N) via Montgomery Reduction
*
* This is an optimized implementation of montgomery_reduce
* which uses the comba method to quickly calculate the columns of the
* reduction.
*
* Based on Algorithm 14.32 on pp.601 of HAC.
*/
int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
{
int ix, res, olduse;
mp_word W[MP_WARRAY];
/* get old used count */
olduse = x->used;
/* grow a as required */
if (x->alloc < n->used + 1) {
if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
return res;
}
}
/* first we have to get the digits of the input into
* an array of double precision words W[...]
*/
{
register mp_word *_W;
register mp_digit *tmpx;
/* alias for the W[] array */
_W = W;
/* alias for the digits of x*/
tmpx = x->dp;
/* copy the digits of a into W[0..a->used-1] */
for (ix = 0; ix < x->used; ix++) {
*_W++ = *tmpx++;
}
/* zero the high words of W[a->used..m->used*2] */
for (; ix < n->used * 2 + 1; ix++) {
*_W++ = 0;
}
}
/* now we proceed to zero successive digits
* from the least significant upwards
*/
for (ix = 0; ix < n->used; ix++) {
/* mu = ai * m' mod b
*
* We avoid a double precision multiplication (which isn't required)
* by casting the value down to a mp_digit. Note this requires
* that W[ix-1] have the carry cleared (see after the inner loop)
*/
register mp_digit mu;
mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
/* a = a + mu * m * b**i
*
* This is computed in place and on the fly. The multiplication
* by b**i is handled by offseting which columns the results
* are added to.
*
* Note the comba method normally doesn't handle carries in the
* inner loop In this case we fix the carry from the previous
* column since the Montgomery reduction requires digits of the
* result (so far) [see above] to work. This is
* handled by fixing up one carry after the inner loop. The
* carry fixups are done in order so after these loops the
* first m->used words of W[] have the carries fixed
*/
{
register int iy;
register mp_digit *tmpn;
register mp_word *_W;
/* alias for the digits of the modulus */
tmpn = n->dp;
/* Alias for the columns set by an offset of ix */
_W = W + ix;
/* inner loop */
for (iy = 0; iy < n->used; iy++) {
*_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
}
}
/* now fix carry for next digit, W[ix+1] */
W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
}
/* now we have to propagate the carries and
* shift the words downward [all those least
* significant digits we zeroed].
*/
{
register mp_digit *tmpx;
register mp_word *_W, *_W1;
/* nox fix rest of carries */
/* alias for current word */
_W1 = W + ix;
/* alias for next word, where the carry goes */
_W = W + ++ix;
for (; ix <= n->used * 2 + 1; ix++) {
*_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
}
/* copy out, A = A/b**n
*
* The result is A/b**n but instead of converting from an
* array of mp_word to mp_digit than calling mp_rshd
* we just copy them in the right order
*/
/* alias for destination word */
tmpx = x->dp;
/* alias for shifted double precision result */
_W = W + n->used;
for (ix = 0; ix < n->used + 1; ix++) {
*tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
}
/* zero oldused digits, if the input a was larger than
* m->used+1 we'll have to clear the digits
*/
for (; ix < olduse; ix++) {
*tmpx++ = 0;
}
}
/* set the max used and clamp */
x->used = n->used + 1;
mp_clamp (x);
/* if A >= m then A = A - m */
if (mp_cmp_mag (x, n) != MP_LT) {
return s_mp_sub (x, n, x);
}
return MP_OKAY;
}
/* computes xR**-1 == x (mod N) via Montgomery Reduction */
int
mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
{
int ix, res, digs;
mp_digit mu;
/* can the fast reduction [comba] method be used?
*
* Note that unlike in mul you're safely allowed *less*
* than the available columns [255 per default] since carries
* are fixed up in the inner loop.
*/
digs = n->used * 2 + 1;
if ((digs < MP_WARRAY) &&
n->used <
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
return fast_mp_montgomery_reduce (x, n, rho);
}
/* grow the input as required */
if (x->alloc < digs) {
if ((res = mp_grow (x, digs)) != MP_OKAY) {
return res;
}
}
x->used = digs;
for (ix = 0; ix < n->used; ix++) {
/* mu = ai * rho mod b
*
* The value of rho must be precalculated via
* montgomery_setup() such that
* it equals -1/n0 mod b this allows the
* following inner loop to reduce the
* input one digit at a time
*/
mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
/* a = a + mu * m * b**i */
{
register int iy;
register mp_digit *tmpn, *tmpx, u;
register mp_word r;
/* alias for digits of the modulus */
tmpn = n->dp;
/* alias for the digits of x [the input] */
tmpx = x->dp + ix;
/* set the carry to zero */
u = 0;
/* Multiply and add in place */
for (iy = 0; iy < n->used; iy++) {
/* compute product and sum */
r = ((mp_word)mu) * ((mp_word)*tmpn++) +
((mp_word) u) + ((mp_word) * tmpx);
/* get carry */
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
/* fix digit */
*tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
}
/* At this point the ix'th digit of x should be zero */
/* propagate carries upwards as required*/
while (u) {
*tmpx += u;
u = *tmpx >> DIGIT_BIT;
*tmpx++ &= MP_MASK;
}
}
}
/* at this point the n.used'th least
* significant digits of x are all zero
* which means we can shift x to the
* right by n.used digits and the
* residue is unchanged.
*/
/* x = x/b**n.used */
mp_clamp(x);
mp_rshd (x, n->used);
/* if x >= n then x = x - n */
if (mp_cmp_mag (x, n) != MP_LT) {
return s_mp_sub (x, n, x);
}
return MP_OKAY;
}
/* determines the setup value */
void mp_dr_setup(mp_int *a, mp_digit *d)
{
/* the casts are required if DIGIT_BIT is one less than
* the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
*/
*d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
((mp_word)a->dp[0]));
}
/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
*
* Based on algorithm from the paper
*
* "Generating Efficient Primes for Discrete Log Cryptosystems"
* Chae Hoon Lim, Pil Joong Lee,
* POSTECH Information Research Laboratories
*
* The modulus must be of a special format [see manual]
*
* Has been modified to use algorithm 7.10 from the LTM book instead
*
* Input x must be in the range 0 <= x <= (n-1)**2
*/
int
mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
{
int err, i, m;
mp_word r;
mp_digit mu, *tmpx1, *tmpx2;
/* m = digits in modulus */
m = n->used;
/* ensure that "x" has at least 2m digits */
if (x->alloc < m + m) {
if ((err = mp_grow (x, m + m)) != MP_OKAY) {
return err;
}
}
/* top of loop, this is where the code resumes if
* another reduction pass is required.
*/
top:
/* aliases for digits */
/* alias for lower half of x */
tmpx1 = x->dp;
/* alias for upper half of x, or x/B**m */
tmpx2 = x->dp + m;
/* set carry to zero */
mu = 0;
/* compute (x mod B**m) + k * [x/B**m] inline and inplace */
for (i = 0; i < m; i++) {
r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
*tmpx1++ = (mp_digit)(r & MP_MASK);
mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
}
/* set final carry */
*tmpx1++ = mu;
/* zero words above m */
for (i = m + 1; i < x->used; i++) {
*tmpx1++ = 0;
}
/* clamp, sub and return */
mp_clamp (x);
/* if x >= n then subtract and reduce again
* Each successive "recursion" makes the input smaller and smaller.
*/
if (mp_cmp_mag (x, n) != MP_LT) {
s_mp_sub(x, n, x);
goto top;
}
return MP_OKAY;
}
/* reduces a modulo n where n is of the form 2**p - d */
int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
{
mp_int q;
int p, res;
if ((res = mp_init(&q)) != MP_OKAY) {
return res;
}
p = mp_count_bits(n);
top:
/* q = a/2**p, a = a mod 2**p */
if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
goto ERR;
}
if (d != 1) {
/* q = q * d */
if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
goto ERR;
}
}
/* a = a + q */
if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
goto ERR;
}
if (mp_cmp_mag(a, n) != MP_LT) {
s_mp_sub(a, n, a);
goto top;
}
ERR:
mp_clear(&q);
return res;
}
/* determines the setup value */
int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
{
int res, p;
mp_int tmp;
if ((res = mp_init(&tmp)) != MP_OKAY) {
return res;
}
p = mp_count_bits(a);
if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
mp_clear(&tmp);
return res;
}
if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
mp_clear(&tmp);
return res;
}
*d = tmp.dp[0];
mp_clear(&tmp);
return MP_OKAY;
}
/* computes a = 2**b
*
* Simple algorithm which zeroes the int, grows it then just sets one bit
* as required.
*/
int
mp_2expt (mp_int * a, int b)
{
int res;
/* zero a as per default */
mp_zero (a);
/* grow a to accomodate the single bit */
if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
return res;
}
/* set the used count of where the bit will go */
a->used = b / DIGIT_BIT + 1;
/* put the single bit in its place */
a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
return MP_OKAY;
}
/* multiply by a digit */
int
mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
{
mp_digit u, *tmpa, *tmpc;
mp_word r;
int ix, res, olduse;
/* make sure c is big enough to hold a*b */
if (c->alloc < a->used + 1) {
if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
return res;
}
}
/* get the original destinations used count */
olduse = c->used;
/* set the sign */
c->sign = a->sign;
/* alias for a->dp [source] */
tmpa = a->dp;
/* alias for c->dp [dest] */
tmpc = c->dp;
/* zero carry */
u = 0;
/* compute columns */
for (ix = 0; ix < a->used; ix++) {
/* compute product and carry sum for this term */
r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
/* mask off higher bits to get a single digit */
*tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
/* send carry into next iteration */
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
}
/* store final carry [if any] and increment ix offset */
*tmpc++ = u;
++ix;
/* now zero digits above the top */
while (ix++ < olduse) {
*tmpc++ = 0;
}
/* set used count */
c->used = a->used + 1;
mp_clamp(c);
return MP_OKAY;
}
/* d = a * b (mod c) */
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
{
int res;
mp_int t;
if ((res = mp_init (&t)) != MP_OKAY) {
return res;
}
if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
mp_clear (&t);
return res;
}
res = mp_mod (&t, c, d);
mp_clear (&t);
return res;
}
/* computes b = a*a */
int
mp_sqr (mp_int * a, mp_int * b)
{
int res;
{
#ifdef BN_FAST_S_MP_SQR_C
/* can we use the fast comba multiplier? */
if ((a->used * 2 + 1) < MP_WARRAY &&
a->used <
(1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
res = fast_s_mp_sqr (a, b);
} else
#endif
#ifdef BN_S_MP_SQR_C
res = s_mp_sqr (a, b);
#else
res = MP_VAL;
#endif
}
b->sign = MP_ZPOS;
return res;
}
/* high level multiplication (handles sign) */
int mp_mul (mp_int * a, mp_int * b, mp_int * c)
{
int res, neg;
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
{
/* can we use the fast multiplier?
*
* The fast multiplier can be used if the output will
* have less than MP_WARRAY digits and the number of
* digits won't affect carry propagation
*/
int digs = a->used + b->used + 1;
#ifdef BN_FAST_S_MP_MUL_DIGS_C
if ((digs < MP_WARRAY) &&
MIN(a->used, b->used) <=
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
res = fast_s_mp_mul_digs (a, b, c, digs);
} else
#endif
#ifdef BN_S_MP_MUL_DIGS_C
res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
#else
res = MP_VAL;
#endif
}
c->sign = (c->used > 0) ? neg : MP_ZPOS;
return res;
}
/* b = a*2 */
int mp_mul_2(mp_int * a, mp_int * b)
{
int x, res, oldused;
/* grow to accomodate result */
if (b->alloc < a->used + 1) {
if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
return res;
}
}
oldused = b->used;
b->used = a->used;
{
register mp_digit r, rr, *tmpa, *tmpb;
/* alias for source */
tmpa = a->dp;
/* alias for dest */
tmpb = b->dp;
/* carry */
r = 0;
for (x = 0; x < a->used; x++) {
/* get what will be the *next* carry bit from the
* MSB of the current digit
*/
rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
/* now shift up this digit, add in the carry [from the previous] */
*tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
/* copy the carry that would be from the source
* digit into the next iteration
*/
r = rr;
}
/* new leading digit? */
if (r != 0) {
/* add a MSB which is always 1 at this point */
*tmpb = 1;
++(b->used);
}
/* now zero any excess digits on the destination
* that we didn't write to
*/
tmpb = b->dp + b->used;
for (x = b->used; x < oldused; x++) {
*tmpb++ = 0;
}
}
b->sign = a->sign;
return MP_OKAY;
}
/* divide by three (based on routine from MPI and the GMP manual) */
int
mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
{
mp_int q;
mp_word w, t;
mp_digit b;
int res, ix;
/* b = 2**DIGIT_BIT / 3 */
b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
return res;
}
q.used = a->used;
q.sign = a->sign;
w = 0;
for (ix = a->used - 1; ix >= 0; ix--) {
w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
if (w >= 3) {
/* multiply w by [1/3] */
t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
/* now subtract 3 * [w/3] from w, to get the remainder */
w -= t+t+t;
/* fixup the remainder as required since
* the optimization is not exact.
*/
while (w >= 3) {
t += 1;
w -= 3;
}
} else {
t = 0;
}
q.dp[ix] = (mp_digit)t;
}
/* [optional] store the remainder */
if (d != NULL) {
*d = (mp_digit)w;
}
/* [optional] store the quotient */
if (c != NULL) {
mp_clamp(&q);
mp_exch(&q, c);
}
mp_clear(&q);
return res;
}
/* init an mp_init for a given size */
int mp_init_size (mp_int * a, int size)
{
int x;
/* pad size so there are always extra digits */
size += (MP_PREC * 2) - (size % MP_PREC);
/* alloc mem */
a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
if (a->dp == NULL) {
return MP_MEM;
}
/* set the members */
a->used = 0;
a->alloc = size;
a->sign = MP_ZPOS;
/* zero the digits */
for (x = 0; x < size; x++) {
a->dp[x] = 0;
}
return MP_OKAY;
}
/* the jist of squaring...
* you do like mult except the offset of the tmpx [one that
* starts closer to zero] can't equal the offset of tmpy.
* So basically you set up iy like before then you min it with
* (ty-tx) so that it never happens. You double all those
* you add in the inner loop
After that loop you do the squares and add them in.
*/
int fast_s_mp_sqr (mp_int * a, mp_int * b)
{
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY], *tmpx;
mp_word W1;
/* grow the destination as required */
pa = a->used + a->used;
if (b->alloc < pa) {
if ((res = mp_grow (b, pa)) != MP_OKAY) {
return res;
}
}
/* number of output digits to produce */
W1 = 0;
for (ix = 0; ix < pa; ix++) {
int tx, ty, iy;
mp_word _W;
mp_digit *tmpy;
/* clear counter */
_W = 0;
/* get offsets into the two bignums */
ty = MIN(a->used-1, ix);
tx = ix - ty;
/* setup temp aliases */
tmpx = a->dp + tx;
tmpy = a->dp + ty;
/* this is the number of times the loop will iterrate, essentially
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = MIN(a->used-tx, ty+1);
/* now for squaring tx can never equal ty
* we halve the distance since they approach at a rate of 2x
* and we have to round because odd cases need to be executed
*/
iy = MIN(iy, (ty-tx+1)>>1);
/* execute loop */
for (iz = 0; iz < iy; iz++) {
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
}
/* double the inner product and add carry */
_W = _W + _W + W1;
/* even columns have the square term in them */
if ((ix&1) == 0) {
_W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
}
/* store it */
W[ix] = (mp_digit)(_W & MP_MASK);
/* make next carry */
W1 = _W >> ((mp_word)DIGIT_BIT);
}
/* setup dest */
olduse = b->used;
b->used = a->used+a->used;
{
mp_digit *tmpb;
tmpb = b->dp;
for (ix = 0; ix < pa; ix++) {
*tmpb++ = W[ix] & MP_MASK;
}
/* clear unused digits [that existed in the old copy of c] */
for (; ix < olduse; ix++) {
*tmpb++ = 0;
}
}
mp_clamp (b);
return MP_OKAY;
}
/* Fast (comba) multiplier
*
* This is the fast column-array [comba] multiplier. It is
* designed to compute the columns of the product first
* then handle the carries afterwards. This has the effect
* of making the nested loops that compute the columns very
* simple and schedulable on super-scalar processors.
*
* This has been modified to produce a variable number of
* digits of output so if say only a half-product is required
* you don't have to compute the upper half (a feature
* required for fast Barrett reduction).
*
* Based on Algorithm 14.12 on pp.595 of HAC.
*
*/
int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
{
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY];
register mp_word _W;
/* grow the destination as required */
if (c->alloc < digs) {
if ((res = mp_grow (c, digs)) != MP_OKAY) {
return res;
}
}
/* number of output digits to produce */
pa = MIN(digs, a->used + b->used);
/* clear the carry */
_W = 0;
for (ix = 0; ix < pa; ix++) {
int tx, ty;
int iy;
mp_digit *tmpx, *tmpy;
/* get offsets into the two bignums */
ty = MIN(b->used-1, ix);
tx = ix - ty;
/* setup temp aliases */
tmpx = a->dp + tx;
tmpy = b->dp + ty;
/* this is the number of times the loop will iterrate, essentially
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = MIN(a->used-tx, ty+1);
/* execute loop */
for (iz = 0; iz < iy; ++iz) {
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
}
/* store term */
W[ix] = ((mp_digit)_W) & MP_MASK;
/* make next carry */
_W = _W >> ((mp_word)DIGIT_BIT);
}
/* setup dest */
olduse = c->used;
c->used = pa;
{
register mp_digit *tmpc;
tmpc = c->dp;
for (ix = 0; ix < pa+1; ix++) {
/* now extract the previous digit [below the carry] */
*tmpc++ = W[ix];
}
/* clear unused digits [that existed in the old copy of c] */
for (; ix < olduse; ix++) {
*tmpc++ = 0;
}
}
mp_clamp (c);
return MP_OKAY;
}
/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
int s_mp_sqr (mp_int * a, mp_int * b)
{
mp_int t;
int res, ix, iy, pa;
mp_word r;
mp_digit u, tmpx, *tmpt;
pa = a->used;
if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
return res;
}
/* default used is maximum possible size */
t.used = 2*pa + 1;
for (ix = 0; ix < pa; ix++) {
/* first calculate the digit at 2*ix */
/* calculate double precision result */
r = ((mp_word) t.dp[2*ix]) +
((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
/* store lower part in result */
t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
/* get the carry */
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
/* left hand side of A[ix] * A[iy] */
tmpx = a->dp[ix];
/* alias for where to store the results */
tmpt = t.dp + (2*ix + 1);
for (iy = ix + 1; iy < pa; iy++) {
/* first calculate the product */
r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
/* now calculate the double precision result, note we use
* addition instead of *2 since it's easier to optimize
*/
r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
/* store lower part */
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
/* get carry */
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
}
/* propagate upwards */
while (u != ((mp_digit) 0)) {
r = ((mp_word) *tmpt) + ((mp_word) u);
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
}
}
mp_clamp (&t);
mp_exch (&t, b);
mp_clear (&t);
return MP_OKAY;
}
/* multiplies |a| * |b| and only computes upto digs digits of result
* HAC pp. 595, Algorithm 14.12 Modified so you can control how
* many digits of output are created.
*/
int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
{
mp_int t;
int res, pa, pb, ix, iy;
mp_digit u;
mp_word r;
mp_digit tmpx, *tmpt, *tmpy;
/* can we use the fast multiplier? */
if (((digs) < MP_WARRAY) &&
MIN (a->used, b->used) <
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
return fast_s_mp_mul_digs (a, b, c, digs);
}
if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
return res;
}
t.used = digs;
/* compute the digits of the product directly */
pa = a->used;
for (ix = 0; ix < pa; ix++) {
/* set the carry to zero */
u = 0;
/* limit ourselves to making digs digits of output */
pb = MIN (b->used, digs - ix);
/* setup some aliases */
/* copy of the digit from a used within the nested loop */
tmpx = a->dp[ix];
/* an alias for the destination shifted ix places */
tmpt = t.dp + ix;
/* an alias for the digits of b */
tmpy = b->dp;
/* compute the columns of the output and propagate the carry */
for (iy = 0; iy < pb; iy++) {
/* compute the column as a mp_word */
r = ((mp_word)*tmpt) +
((mp_word)tmpx) * ((mp_word)*tmpy++) +
((mp_word) u);
/* the new column is the lower part of the result */
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
/* get the carry word from the result */
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
}
/* set carry if it is placed below digs */
if (ix + iy < digs) {
*tmpt = u;
}
}
mp_clamp (&t);
mp_exch (&t, c);
mp_clear (&t);
return MP_OKAY;
}
/*
* shifts with subtractions when the result is greater than b.
*
* The method is slightly modified to shift B unconditionally upto just under
* the leading bit of b. This saves alot of multiple precision shifting.
*/
int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
{
int x, bits, res;
/* how many bits of last digit does b use */
bits = mp_count_bits (b) % DIGIT_BIT;
if (b->used > 1) {
if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
return res;
}
} else {
mp_set(a, 1);
bits = 1;
}
/* now compute C = A * B mod b */
for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
return res;
}
if (mp_cmp_mag (a, b) != MP_LT) {
if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
return res;
}
}
}
return MP_OKAY;
}
#ifdef MP_LOW_MEM
#define TAB_SIZE 32
#else
#define TAB_SIZE 256
#endif
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
{
mp_int M[TAB_SIZE], res, mu;
mp_digit buf;
int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
int (*redux)(mp_int*,mp_int*,mp_int*);
/* find window size */
x = mp_count_bits (X);
if (x <= 7) {
winsize = 2;
} else if (x <= 36) {
winsize = 3;
} else if (x <= 140) {
winsize = 4;
} else if (x <= 450) {
winsize = 5;
} else if (x <= 1303) {
winsize = 6;
} else if (x <= 3529) {
winsize = 7;
} else {
winsize = 8;
}
#ifdef MP_LOW_MEM
if (winsize > 5) {
winsize = 5;
}
#endif
/* init M array */
/* init first cell */
if ((err = mp_init(&M[1])) != MP_OKAY) {
return err;
}
/* now init the second half of the array */
for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
if ((err = mp_init(&M[x])) != MP_OKAY) {
for (y = 1<<(winsize-1); y < x; y++) {
mp_clear (&M[y]);
}
mp_clear(&M[1]);
return err;
}
}
/* create mu, used for Barrett reduction */
if ((err = mp_init (&mu)) != MP_OKAY) {
goto LBL_M;
}
if (redmode == 0) {
if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
goto LBL_MU;
}
redux = mp_reduce;
} else {
if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
goto LBL_MU;
}
redux = mp_reduce_2k_l;
}
/* create M table
*
* The M table contains powers of the base,
* e.g. M[x] = G**x mod P
*
* The first half of the table is not
* computed though accept for M[0] and M[1]
*/
if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
goto LBL_MU;
}
/* compute the value at M[1<<(winsize-1)] by squaring
* M[1] (winsize-1) times
*/
if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_MU;
}
for (x = 0; x < (winsize - 1); x++) {
/* square it */
if ((err = mp_sqr (&M[1 << (winsize - 1)],
&M[1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_MU;
}
/* reduce modulo P */
if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
goto LBL_MU;
}
}
/* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
* for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
*/
for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
goto LBL_MU;
}
if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
goto LBL_MU;
}
}
/* setup result */
if ((err = mp_init (&res)) != MP_OKAY) {
goto LBL_MU;
}
mp_set (&res, 1);
/* set initial mode and bit cnt */
mode = 0;
bitcnt = 1;
buf = 0;
digidx = X->used - 1;
bitcpy = 0;
bitbuf = 0;
| Thread |
|---|
| • bk commit into 5.0 tree (msvensson:1.2457) | msvensson | 4 May |