patch for cipher/sha512.c (u64 numbers)

David Shaw dshaw at jabberwocky.com
Fri May 9 23:04:02 CEST 2003


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Fri, May 09, 2003 at 02:07:44PM -0500, Tim Mooney wrote:
> >On Fri, May 09, 2003 at 09:05:43AM -0400, David Shaw wrote:
> >> On Thu, May 08, 2003 at 05:01:12PM +0200, Werner Koch wrote:
> >> > On Tue, 6 May 2003 16:50:52 +0200, Christoph Moench-Tegeder said:
> >> >
> >> > > In cipher/sha512.c u64 (long long int on most platforms) constants
> >> > > are without modifier 'LL' in assignments. At least HP's cc in ANSI
> >> >
> >> > To my knowledge the LL suffix is not C-89 and thus we can't use it.
> >> > The simple solution is to fix HP's compiler or write an autoconf test
> >> > to detect such a broken compiler.
> >>
> >> Yes, LL is C99.  I think I can make an autoconf test without too much
> >> trouble.
> >
> >Okay, here's what I'm thinking:
> >
> >1) c89 does not guarantee that 64-bit ints are available, and does not
> >support LL.
> >
> >2) c99 does guarantee 64-bit ints, and does support LL.
> >
> >3) Some/many supposedly "c89" compilers support 64-bit ints and LL
> >anyway as an extension.
> >
> >So the answer is to always use LL in the code, and try and weed out
> >any compilers that don't support LL in autoconf.  This will work on
> >all c99 compilers, and any c89 compilers that support 64-bit ints.  If
> >it is a pure c89 compiler (and therefore doesn't support 64-bit ints),
> >it doesn't matter if it supports LL or not.
> 
> I don't think that's quite correct.  c89 says nothing about the
> availability of 64-bit ints.  The size of short int vs. int vs. long int
> is implementation dependant.  A `long int' could be a 64 bit type with
> a pure c89 compiler quite easily.

Of course.  I said that c89 does not guarantee that 64-bit ints are
available.  It doesn't.  If I recall, the only thing it does guarantee
on the subject is that a long is at least 32 bits wide.

> What c89 doesn't include is the `long long int' type or the LL "postfix".
> On a pure 32 bit architecture, the `long long int' extension to c89
> may be the only way to get a 64 bit type, but on a 64 bit architecture
> `long long int' might be larger than 64 bits, especially for those
> platforms that have some or all of the c99 bits.
> 
> That also means that blindly using `LL' as the postfix might be incorrect,
> since a long long int might be 128 bits.

Hmm.  I wasn't very concerned with this case, since the values that I
am tagging with LL *are* 64-bit values.  It should cause no harm in
the SHA results to store that in a >=64-bit variable (and I'd love
someone with a 64 bit machine to verify that if possible).  It would
break if LL indicated something less than <64 bits of course (or did
not exist at all), but the autoconf test should flag that.

> >  The only thing this test
> >won't handle is a c89 compiler that does support 64-bit ints, but does
> >not support LL.  I can live with that, especially since the digest
> >code in question is optional anyway.
> 
> You're talking about several vendor compilers in 64 bit mode.  The
> Solaris, Tru64, and IRIX compilers have all added bits and peices of c99
> in recent versions, but all of them supported a 64 bit type *that was not
> long long int* well before they supported `LL'.

The point of using LL was to avoid a problem with compilers which do
support >=64-bit types, but truncate 64-bit constants to 32 bits if
there is no LL.  If doing this causes more breakage than help, then I
should reconsider.

> What would be better is to use AC_SIZEOF to find a 64 bit type, trying
> first `long' and then `long long'.  Next, check for the `int64_t', and if
> it doesn't exist, use AC_TYPEDEF to define the "right sized" integer type
> to it.

See include/types.h ;) The changes I was discussing are actually on
top of a set of type checks that were already in the code.  "u64" is
typedeffed to an unsigned 64-bit type.  It tries all of "unsigned
int", "unsigned long", "unsigned long long", and "uint64_t" in that
order.

>  At the same time, define a
> 
> (for long == 8 bytes):
> 
> 	#define	INT64_INITIALIZER	L
> 	#define	INT64_FORMATTER		ld
> 
> (for long long == 8 bytes):
> 
> 	#define	INT64_INITIALIZER	LL
> 	#define	INT64_FORMATTER		lld		/* or whatever it is for long long */

Good idea.  In C99 I could use UINT64_C() for this, but alas...

David
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
Comment: http://www.jabberwocky.com/david/keys.asc

iD8DBQE+vAnt4mZch0nhy8kRAjI8AJ9paozoUP03Ns+Nb/GhiZRlM84A6gCgh5Bp
wBEUA+IIKmX/+FA3838zIRw=
=LJ1j
-----END PGP SIGNATURE-----




More information about the Gnupg-devel mailing list