diff --git a/Doxyfile b/Doxyfile index 9e2eccc..fc6d509 100644 --- a/Doxyfile +++ b/Doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = LibTomCrypt # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.03 +PROJECT_NUMBER = 1.04 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/TODO b/TODO index c93ef6f..828e094 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,10 @@ -Things ideal for 1.04 +Things ideal for 1.05 -- ASN.1 SET and UTCtime +- ASN.1 SET and UTCtime and CHOICE (hint for choice do it as a sep list and just use error codes to know when you got a hit) - Start working towards making the bignum code plugable - Add OID for ciphers and PRNGs to their descriptors - Document the ASN.1 a bit more verbosely ;-) - Some ASN.1 demo programs [for now read the source code!] +- export ECC functions globally - Look into other ECC point muls and consider a "precomp" interface diff --git a/changes b/changes index 5e56f67..bc943a8 100644 --- a/changes +++ b/changes @@ -1,3 +1,11 @@ +June 15th, 2005 +v1.04 + -- Fixed off by one [bit] error in dsa_make_key() it was too high by one bit [not a security problem just inconsistent] + -- ECC-224 curve was wrong [it was an ok curve just not NIST, so no security flaw just interoperability]. + -- Removed point compression since it slows down ECC ops to save a measly couple bytes. + This makes the ecc export format incompatible with 1.03 [it shouldn't change in the future] + -- Removed ECC-160 from timing and added the other curves + June 9th, 2005 v1.03 -- Users may want to note that on a P4/GCC3.4 platform "-fno-regmove" greatly accelerates the ciphers/hashes. @@ -1300,6 +1308,6 @@ v0.02 -- Changed RC5 to only allow 12 to 24 rounds v0.01 -- We will call this the first version. /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */ -/* $Revision: 1.92 $ */ -/* $Date: 2005/06/09 01:06:59 $ */ +/* $Revision: 1.97 $ */ +/* $Date: 2005/06/14 23:09:41 $ */ diff --git a/crypt.tex b/crypt.tex index 9e17fe2..3342666 100644 --- a/crypt.tex +++ b/crypt.tex @@ -47,7 +47,7 @@ \def\gap{\vspace{0.5ex}} \makeindex \begin{document} -\title{LibTomCrypt \\ Version 1.03} +\title{LibTomCrypt \\ Version 1.04} \author{Tom St Denis \\ \\ tomstdenis@gmail.com \\ @@ -3022,26 +3022,25 @@ than ideally simple manner. In the case of LibTomCrypt it is meant \textbf{sole \begin{small} \begin{verbatim} ECCPublicKey ::= SEQUENCE { - flags BIT STRING(2), -- public/private flag (always zero), - -- compressed point + flags BIT STRING(1), -- public/private flag (always zero), keySize INTEGER, -- Curve size (in bits) divided by eight -- and rounded down, e.g. 521 => 65 pubkey.x INTEGER, -- The X co-ordinate of the public key point + pubkey.y INTEGER, -- The Y co-ordinate of the public key point } ECCPrivateKey ::= SEQUENCE { - flags BIT STRING(2), -- public/private flag (always one), - -- compressed point + flags BIT STRING(1), -- public/private flag (always one), keySize INTEGER, -- Curve size (in bits) divided by eight -- and rounded down, e.g. 521 => 65 pubkey.x INTEGER, -- The X co-ordinate of the public key point + pubkey.y INTEGER, -- The Y co-ordinate of the public key point secret.k INTEGER, -- The secret key scalar } \end{verbatim} \end{small} -The first flags bit denotes whether the key is public (zero) or private (one). The compressed point bit is equal to zero if $(x^3 - 3x + b)^{(p+1)/4} \mbox{ mod }p$ is -congruent to the keys $y$ co-ordinate. The bit is one if the $y$ co-ordinate is the negative of the computed square root. +The first flags bit denotes whether the key is public (zero) or private (one). \section{Core Functions} @@ -4492,5 +4491,5 @@ but should at least maintain the same level of state entropy. \end{document} % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $ -% $Revision: 1.32 $ -% $Date: 2005/06/09 00:36:17 $ +% $Revision: 1.33 $ +% $Date: 2005/06/14 22:53:24 $ diff --git a/doc/crypt.pdf b/doc/crypt.pdf index a50ea92..03c54cf 100644 Binary files a/doc/crypt.pdf and b/doc/crypt.pdf differ diff --git a/makefile b/makefile index d3681f2..f719cea 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ # Modified by Clay Culver # The version -VERSION=1.03 +VERSION=1.04 # Compiler and Linker Names #CC=gcc @@ -321,5 +321,5 @@ zipup: no_oops docs # $Source: /cvs/libtom/libtomcrypt/makefile,v $ -# $Revision: 1.67 $ -# $Date: 2005/06/09 00:39:26 $ +# $Revision: 1.68 $ +# $Date: 2005/06/14 22:53:24 $ diff --git a/makefile.shared b/makefile.shared index aa653da..fb68a23 100644 --- a/makefile.shared +++ b/makefile.shared @@ -6,7 +6,7 @@ # Tom St Denis # The version -VERSION=0:103 +VERSION=0:104 # Compiler and Linker Names CC=libtool --mode=compile gcc @@ -222,5 +222,5 @@ timing: library $(LIBTEST) $(TIMINGS) gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(MPISHARED) # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $ -# $Revision: 1.16 $ -# $Date: 2005/06/08 23:37:40 $ +# $Revision: 1.17 $ +# $Date: 2005/06/14 22:53:25 $ diff --git a/src/headers/tomcrypt.h b/src/headers/tomcrypt.h index a5c1548..c072ef5 100644 --- a/src/headers/tomcrypt.h +++ b/src/headers/tomcrypt.h @@ -16,8 +16,8 @@ extern "C" { #endif /* version */ -#define CRYPT 0x0103 -#define SCRYPT "1.03" +#define CRYPT 0x0104 +#define SCRYPT "1.04" /* max size of either a cipher/hash block or symmetric key [largest of the two] */ #define MAXBLOCKSIZE 128 diff --git a/src/pk/dsa/dsa_make_key.c b/src/pk/dsa/dsa_make_key.c index a43da12..b71bcf8 100644 --- a/src/pk/dsa/dsa_make_key.c +++ b/src/pk/dsa/dsa_make_key.c @@ -70,15 +70,15 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, } /* force magnitude */ - buf[0] = 1; + buf[0] |= 0xC0; /* force even */ - buf[modulus_size - group_size] &= ~1; + buf[modulus_size - group_size - 1] &= ~1; - if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size+1)) != MP_OKAY) { goto error; } + if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size)) != MP_OKAY) { goto error; } if ((err = mp_mul(&key->q, &tmp2, &key->p)) != MP_OKAY) { goto error; } if ((err = mp_add_d(&key->p, 1, &key->p)) != MP_OKAY) { goto error; } - + /* now loop until p is prime */ for (;;) { if ((err = is_prime(&key->p, &res)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/ecc/ecc.c b/src/pk/ecc/ecc.c index 605b0fb..b030066 100644 --- a/src/pk/ecc/ecc.c +++ b/src/pk/ecc/ecc.c @@ -60,19 +60,20 @@ static const struct { "ECC-224", /* prime */ - "400000000000000000000000000000000000BV", + "3/////////////////////0000000000000001", /* B */ - "21HkWGL2CxJIp", + "2q1Gg530Ipg/L1CbPGHB2trx/OkYSBEKCZLV+q", /* order */ - "4000000000000000000Kxnixk9t8MLzMiV264/", + "3//////////////////nQYuBZmFXFTAKLSN2ez", /* Gx */ - "jpqOf1BHus6Yd/pyhyVpP", + "2t3WozQxI/Vp8JaBbA0y7JLi8H8ZGoWDOHN1qX", + /* Gy */ - "3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck", + "2zDsE8jVSZ+qmYt+RDGtMWMWT7P4JLWPc507uq", }, #endif #ifdef ECC256 @@ -819,89 +820,6 @@ void ecc_free(ecc_key *key) mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); } -static int compress_y_point(ecc_point *pt, int idx, int *result) -{ - mp_int tmp, tmp2, p; - int err; - - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(result != NULL); - - if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) { - return mpi_to_ltc_error(err); - } - - /* get x^3 - 3x + b */ - if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */ - if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY) { goto error; } /* tmp = pX^3 */ - if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */ - if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */ - if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp + p */ - if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY) { goto error; } /* p = prime */ - if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp mod p */ - - /* now find square root */ - if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */ - if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */ - if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */ - - /* if tmp equals the y point give a 0, otherwise 1 */ - if (mp_cmp(&tmp, &pt->y) == 0) { - *result = 0; - } else { - *result = 1; - } - - err = CRYPT_OK; - goto done; -error: - err = mpi_to_ltc_error(err); -done: - mp_clear_multi(&p, &tmp, &tmp2, NULL); - return err; -} - -static int expand_y_point(ecc_point *pt, int idx, int result) -{ - mp_int tmp, tmp2, p; - int err; - - LTC_ARGCHK(pt != NULL); - - if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) { - return CRYPT_MEM; - } - - /* get x^3 - 3x + b */ - if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */ - if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY) { goto error; } /* tmp = pX^3 */ - if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */ - if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */ - if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp + p */ - if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY) { goto error; } /* p = prime */ - if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp mod p */ - - /* now find square root */ - if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */ - if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */ - if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */ - - /* if result==0, then y==tmp, otherwise y==p-tmp */ - if (result == 0) { - if ((err = mp_copy(&tmp, &pt->y) != MP_OKAY)) { goto error; } - } else { - if ((err = mp_sub(&p, &tmp, &pt->y) != MP_OKAY)) { goto error; } - } - - err = CRYPT_OK; - goto done; -error: - err = mpi_to_ltc_error(err); -done: - mp_clear_multi(&p, &tmp, &tmp2, NULL); - return err; -} - /** Export an ECC key as a binary packet @param out [out] Destination for the key @@ -912,8 +830,8 @@ done: */ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) { - int cp, err; - unsigned char flags[2]; + int err; + unsigned char flags[1]; unsigned long key_size; LTC_ARGCHK(out != NULL); @@ -929,29 +847,25 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key return CRYPT_INVALID_ARG; } - /* compress the y part */ - if ((err = compress_y_point(&key->pubkey, key->idx, &cp)) != CRYPT_OK) { - return err; - } - flags[1] = cp; - /* we store the NIST byte size */ key_size = sets[key->idx].size; if (type == PK_PRIVATE) { flags[0] = 1; err = der_encode_sequence_multi(out, outlen, - LTC_ASN1_BIT_STRING, 2UL, flags, + LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, &key->pubkey.y, LTC_ASN1_INTEGER, 1UL, &key->k, LTC_ASN1_EOL, 0UL, NULL); } else { flags[0] = 0; err = der_encode_sequence_multi(out, outlen, - LTC_ASN1_BIT_STRING, 2UL, flags, + LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, &key->pubkey.y, LTC_ASN1_EOL, 0UL, NULL); } @@ -968,7 +882,7 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) { unsigned long key_size; - unsigned char flags[2]; + unsigned char flags[1]; int err; LTC_ARGCHK(in != NULL); @@ -981,7 +895,7 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) /* find out what type of key it is */ if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_BIT_STRING, 2UL, &flags, + LTC_ASN1_BIT_STRING, 1UL, &flags, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } @@ -991,9 +905,10 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) /* private key */ key->type = PK_PRIVATE; if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_BIT_STRING, 2UL, flags, + LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, &key->pubkey.y, LTC_ASN1_INTEGER, 1UL, &key->k, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; @@ -1003,9 +918,10 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) /* private key */ key->type = PK_PUBLIC; if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_BIT_STRING, 2UL, flags, + LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, &key->pubkey.y, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } @@ -1018,11 +934,6 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) goto error; } - /* compute y */ - if ((err = expand_y_point(&key->pubkey, key->idx, flags[1])) != CRYPT_OK) { - goto error; - } - /* set z */ mp_set(&key->pubkey.z, 1); diff --git a/testprof/ecc_test.c b/testprof/ecc_test.c index 4ec3e8a..1b0f6b8 100644 --- a/testprof/ecc_test.c +++ b/testprof/ecc_test.c @@ -67,7 +67,7 @@ int ecc_tests (void) return 1; } if (memcmp (buf[0], buf[2], x)) { - fprintf(stderr, "Failed. Content didn't match."); + fprintf(stderr, "Failed. Contents didn't match."); return 1; } ecc_free (&usera); diff --git a/testprof/x86_prof.c b/testprof/x86_prof.c index 7fbe8e1..94ca73c 100644 --- a/testprof/x86_prof.c +++ b/testprof/x86_prof.c @@ -724,7 +724,7 @@ void time_ecc(void) unsigned char buf[2][4096]; unsigned long i, x, y, z; int err; - static unsigned long sizes[] = {160/8, 256/8, 521/8, 100000}; + static unsigned long sizes[] = {192/8, 256/8, 384/8, 521/8, 100000}; for (x = sizes[i=0]; x < 100000; x = sizes[++i]) { t2 = 0;