another question, and a small patch
Vladimir Vukicevic
vladimir@helixcode.com
Mon, 12 Jun 2000 11:32:18 -0400
Okay, I got my issues worked out -- now, it's mainly speed. My code
basically does this.. reads 128-byte blocks from an input file, does a
gcry_mpi_scan on the blocks, then makes a SEXP from that MPI, does
a pk_encrypt(), and then writes the resulting MPI a/b pair to a
file. (I'm using ElGamal.) The problem is that it's ridiculously slow;
encoding a simple 6k file takes about 8 seconds, which is completely
unacceptable. By contrast, gpg -e takes 0.06 sec. So, I'm obviously
doing something that's rather stupid. I'm currently read()'ing blocks
one by one, an optimization would be to mmap the input file; but that
shouldn't be that big of a bottleneck. Any thoughts on this speed
problem?
I also ran into some problems with the sexp implementation.. The
problem is if you have a sexp such as that returned from pk_encrypt:
(enc-data (elg (a MPI) (b MPI))), there was no way previously to get
at any of that data using the car/cdr functions. You had to search for
the token. These patches make car 'do the right thing' (I think), by
checking to see if the first elt is a list, and if so to give you the
list itself, not just the same object back. Also, sexp_release wasn't
implemented, so I implemented that as well. Plus, the small patch that
attempts to stick the right export symbols into the .so (it still
doesn't work quite right).
Index: gcrypt/Makefile.am
===================================================================
RCS file: /home/koch/cvs/gnupg/gcrypt/Makefile.am,v
retrieving revision 1.13
diff -u -r1.13 Makefile.am
--- gcrypt/Makefile.am 2000/01/31 15:26:58 1.13
+++ gcrypt/Makefile.am 2000/06/12 15:21:51
@@ -43,8 +43,14 @@
# libtool's --export-symbols-regex does not work in 1.3.2
# so we do it ourself
libgcrypt.sym: $(libgcrypt_la_OBJECTS)
- $(NM) $(libgcrypt_la_OBJECTS) \
- | $(AWK) '$$2=="T" && $$3 ~ /^gcry_/ {print $$3}' >libgcrypt.sym
+ $(NM) $(libgcrypt_la_OBJECTS) \
+ | $(AWK) '$$2=="T" && $$3 ~ /^gcry_/ {print $$3}' >libgcrypt-local.sym
+ (cd ../mpi; $(NM) *.lo | $(AWK) '$$2=="T" && $$3 ~ /^gcry_/ {print $$3}' > libmpi.sym)
+ (cd ../cipher; $(NM) *.lo | $(AWK) '$$2=="T" && $$3 ~ /^gcry_/ {print $$3}' > libcipher.sym)
+ (cd ../util; $(NM) *.lo | $(AWK) '$$2=="T" && $$3 ~ /^gcry_/ {print $$3}' > libutil.sym)
+ cat libgcrypt-local.sym ../mpi/libmpi.sym ../cipher/libcipher.sym ../util/libutil.sym > libgcrypt.sym
+
+
Index: gcrypt/sexp.c
===================================================================
RCS file: /home/koch/cvs/gnupg/gcrypt/sexp.c,v
retrieving revision 1.9
diff -u -r1.9 sexp.c
--- gcrypt/sexp.c 2000/01/27 16:50:43 1.9
+++ gcrypt/sexp.c 2000/06/12 15:21:51
@@ -219,7 +219,35 @@
void
gcry_sexp_release( GCRY_SEXP sexp )
{
- /* FIXME! */
+ /* Note that this will do a deep release, i.e. release the mpi's
+ * and data buf's that are pointed to by this sexp. This, in theory,
+ * is the wrong thing to do -- the "Right Thing" would be to do
+ * refcounting here.
+ */
+
+ if (sexp == NULL) return;
+
+#if 0
+ fprintf (stderr, "SEXP_RELEASE: ");
+ gcry_sexp_dump (sexp);
+#endif
+
+ /* Release across */
+ gcry_sexp_release (sexp->next);
+
+ /* Then release down, if present */
+ if (sexp->type == ntLIST) {
+ gcry_sexp_release (sexp->u.list);
+ } else if (sexp->type == ntMPI) {
+ gcry_mpi_release (sexp->u.mpi);
+ } else if (sexp->type == ntDATA) {
+ /* Nothing special -- taken care of in following g10_free */
+ } else {
+ /* there should be no other types */
+ BUG();
+ }
+
+ g10_free (sexp);
}
@@ -478,7 +506,10 @@
GCRY_SEXP
gcry_sexp_car( GCRY_SEXP list )
{
- return list;
+ if( list && list->type == ntLIST )
+ list = list->u.list;
+
+ return list;
}
/****************
@@ -524,6 +555,8 @@
GCRY_SEXP
gcry_sexp_cdr( GCRY_SEXP list )
{
+ if( list && list->type == ntLIST && !list->next )
+ list = list->u.list;
if( list && (list = list->next) )
return list;
return NULL;