From jussi.kivilinna at iki.fi Sun Sep 1 15:54:09 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 01 Sep 2013 16:54:09 +0300 Subject: [PATCH 1/3] serpent-avx2-amd64: Move register clearing to assembly Message-ID: <20130901135409.23231.16575.stgit@localhost6.localdomain6> * cipher/serpent-avx2-amd64.S (_gcry_serpent_avx2_ctr_enc) (_gcry_serpent_avx2_cbc_dec, _gcry_serpent_avx2_cfb_dec): Change last 'vzeroupper' to 'vzeroall'. * cipher/serpent.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec) (_gcry_serpent_avx2_cfb_dec) [USE_AVX2]: Remove register clearing with 'vzeroall'. -- AVX2 implementation was already clearing upper halfs of YMM registers at end of assembly functions to prevent long SSE<->AVX transition stalls present on Intel CPUs. Patch changes these 'vzeroupper' instructions to 'vzeroall' to fully clear YMM registers. After this change register clearing in serpent.c in not needed. Signed-off-by: Jussi Kivilinna --- cipher/serpent-avx2-amd64.S | 6 +++--- cipher/serpent.c | 9 --------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/cipher/serpent-avx2-amd64.S b/cipher/serpent-avx2-amd64.S index 7586c0c..c726e7b 100644 --- a/cipher/serpent-avx2-amd64.S +++ b/cipher/serpent-avx2-amd64.S @@ -730,7 +730,7 @@ _gcry_serpent_avx2_ctr_enc: vmovdqu RB2, (6 * 32)(%rsi); vmovdqu RB3, (7 * 32)(%rsi); - vzeroupper; + vzeroall; ret .size _gcry_serpent_avx2_ctr_enc,.-_gcry_serpent_avx2_ctr_enc; @@ -799,7 +799,7 @@ _gcry_serpent_avx2_cbc_dec: vmovdqu RB2, (6 * 32)(%rsi); vmovdqu RB3, (7 * 32)(%rsi); - vzeroupper; + vzeroall; ret .size _gcry_serpent_avx2_cbc_dec,.-_gcry_serpent_avx2_cbc_dec; @@ -870,7 +870,7 @@ _gcry_serpent_avx2_cfb_dec: vmovdqu RB2, (6 * 32)(%rsi); vmovdqu RB3, (7 * 32)(%rsi); - vzeroupper; + vzeroall; ret .size _gcry_serpent_avx2_cfb_dec,.-_gcry_serpent_avx2_cfb_dec; diff --git a/cipher/serpent.c b/cipher/serpent.c index bf03fe7..430a7e9 100644 --- a/cipher/serpent.c +++ b/cipher/serpent.c @@ -845,9 +845,6 @@ _gcry_serpent_ctr_enc(void *context, unsigned char *ctr, if (did_use_avx2) { - /* clear avx2 registers used by serpent-sse2 */ - asm volatile ("vzeroall;\n":::); - /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; @@ -937,9 +934,6 @@ _gcry_serpent_cbc_dec(void *context, unsigned char *iv, if (did_use_avx2) { - /* clear avx2 registers used by serpent-sse2 */ - asm volatile ("vzeroall;\n":::); - /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; @@ -1023,9 +1017,6 @@ _gcry_serpent_cfb_dec(void *context, unsigned char *iv, if (did_use_avx2) { - /* clear avx2 registers used by serpent-sse2 */ - asm volatile ("vzeroall;\n":::); - /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; From jussi.kivilinna at iki.fi Sun Sep 1 15:54:14 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 01 Sep 2013 16:54:14 +0300 Subject: [PATCH 2/3] camellia-aesni-avx-amd64: Move register clearing to assembly functions In-Reply-To: <20130901135409.23231.16575.stgit@localhost6.localdomain6> References: <20130901135409.23231.16575.stgit@localhost6.localdomain6> Message-ID: <20130901135414.23231.94087.stgit@localhost6.localdomain6> * cipher/camellia-aesni-avx-amd64.S (_gcry_camellia_aesni_avx_ctr_enc) (_gcry_camellia_aesni_avx_cbc_dec) (_gcry_camellia_aesni_avx_cfb_dec): Add 'vzeroupper' at head and 'vzeroall' at tail. * cipher/camellia-glue.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec) (_gcry_serpent_avx2_cfb_dec) [USE_AESNI_AVX]: Remove register clearing. -- Patch moves register clearing with 'vzeroall' to assembly functions and adds missing 'vzeroupper' instructions at head of assembly functions. Signed-off-by: Jussi Kivilinna --- cipher/camellia-aesni-avx-amd64.S | 12 ++++++++++++ cipher/camellia-glue.c | 9 --------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/cipher/camellia-aesni-avx-amd64.S b/cipher/camellia-aesni-avx-amd64.S index b0ef5fd..9873d98 100644 --- a/cipher/camellia-aesni-avx-amd64.S +++ b/cipher/camellia-aesni-avx-amd64.S @@ -958,6 +958,8 @@ _gcry_camellia_aesni_avx_ctr_enc: * %rcx: iv (big endian, 128bit) */ + vzeroupper; + subq $(16 * 16), %rsp; movq %rsp, %rax; @@ -1054,6 +1056,8 @@ _gcry_camellia_aesni_avx_ctr_enc: %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, %xmm8, %rsi); + vzeroall; + ret; .size _gcry_camellia_aesni_avx_ctr_enc,.-_gcry_camellia_aesni_avx_ctr_enc; @@ -1069,6 +1073,8 @@ _gcry_camellia_aesni_avx_cbc_dec: * %rcx: iv */ + vzeroupper; + movq %rcx, %r9; cmpl $128, key_bitlength(CTX); @@ -1114,6 +1120,8 @@ _gcry_camellia_aesni_avx_cbc_dec: movq %r10, (0)(%r9); movq %r11, (8)(%r9); + vzeroall; + ret; .size _gcry_camellia_aesni_avx_cbc_dec,.-_gcry_camellia_aesni_avx_cbc_dec; @@ -1129,6 +1137,8 @@ _gcry_camellia_aesni_avx_cfb_dec: * %rcx: iv */ + vzeroupper; + subq $(16 * 16), %rsp; movq %rsp, %rax; @@ -1179,6 +1189,8 @@ _gcry_camellia_aesni_avx_cfb_dec: %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, %xmm8, %rsi); + vzeroall; + ret; .size _gcry_camellia_aesni_avx_cfb_dec,.-_gcry_camellia_aesni_avx_cfb_dec; diff --git a/cipher/camellia-glue.c b/cipher/camellia-glue.c index 6e2319d..7d8a4cd 100644 --- a/cipher/camellia-glue.c +++ b/cipher/camellia-glue.c @@ -344,9 +344,6 @@ _gcry_camellia_ctr_enc(void *context, unsigned char *ctr, if (did_use_aesni_avx) { - /* clear AVX registers */ - asm volatile ("vzeroall;\n":::); - if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *)) burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *); } @@ -440,9 +437,6 @@ _gcry_camellia_cbc_dec(void *context, unsigned char *iv, if (did_use_aesni_avx) { - /* clear AVX registers */ - asm volatile ("vzeroall;\n":::); - if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *)) burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *); } @@ -531,9 +525,6 @@ _gcry_camellia_cfb_dec(void *context, unsigned char *iv, if (did_use_aesni_avx) { - /* clear AVX registers */ - asm volatile ("vzeroall;\n":::); - if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *)) burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *); } From jussi.kivilinna at iki.fi Sun Sep 1 15:54:19 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 01 Sep 2013 16:54:19 +0300 Subject: [PATCH 3/3] camellia-aesni-avx2-amd64: Move register clearing to assembly functions In-Reply-To: <20130901135409.23231.16575.stgit@localhost6.localdomain6> References: <20130901135409.23231.16575.stgit@localhost6.localdomain6> Message-ID: <20130901135419.23231.4425.stgit@localhost6.localdomain6> * cipher/camellia-aesni-avx2-amd64.S (_gcry_camellia_aesni_avx2_ctr_enc): Add 'vzeroall'. (_gcry_camellia_aesni_avx2_cbc_dec) (_gcry_camellia_aesni_avx2_cfb_dec): Add 'vzeroupper' at head and 'vzeroall' at tail. * cipher/camellia-glue.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec) (_gcry_serpent_avx2_cfb_dec) [USE_AESNI_AVX2]: Remove register clearing. -- Patch moves register clearing with 'vzeroall' to assembly functions and adds missing 'vzeroupper' instructions at head of assembly functions. Signed-off-by: Jussi Kivilinna --- cipher/camellia-aesni-avx2-amd64.S | 10 ++++++++++ cipher/camellia-glue.c | 9 --------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/cipher/camellia-aesni-avx2-amd64.S b/cipher/camellia-aesni-avx2-amd64.S index da427b4..7e31323 100644 --- a/cipher/camellia-aesni-avx2-amd64.S +++ b/cipher/camellia-aesni-avx2-amd64.S @@ -1104,6 +1104,8 @@ _gcry_camellia_aesni_avx2_ctr_enc: %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9, %ymm8, %rsi); + vzeroall; + ret; .size _gcry_camellia_aesni_avx2_ctr_enc,.-_gcry_camellia_aesni_avx2_ctr_enc; @@ -1119,6 +1121,8 @@ _gcry_camellia_aesni_avx2_cbc_dec: * %rcx: iv */ + vzeroupper; + movq %rcx, %r9; cmpl $128, key_bitlength(CTX); @@ -1171,6 +1175,8 @@ _gcry_camellia_aesni_avx2_cbc_dec: movq %rax, (0)(%r9); movq %rcx, (8)(%r9); + vzeroall; + ret; .size _gcry_camellia_aesni_avx2_cbc_dec,.-_gcry_camellia_aesni_avx2_cbc_dec; @@ -1186,6 +1192,8 @@ _gcry_camellia_aesni_avx2_cfb_dec: * %rcx: iv */ + vzeroupper; + movq %rsp, %r10; subq $(16 * 32), %rsp; andq $~31, %rsp; @@ -1240,6 +1248,8 @@ _gcry_camellia_aesni_avx2_cfb_dec: %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9, %ymm8, %rsi); + vzeroall; + ret; .size _gcry_camellia_aesni_avx2_cfb_dec,.-_gcry_camellia_aesni_avx2_cfb_dec; diff --git a/cipher/camellia-glue.c b/cipher/camellia-glue.c index 7d8a4cd..d6d6005 100644 --- a/cipher/camellia-glue.c +++ b/cipher/camellia-glue.c @@ -314,9 +314,6 @@ _gcry_camellia_ctr_enc(void *context, unsigned char *ctr, int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 + 2 * sizeof(void *); - /* clear AVX registers */ - asm volatile ("vzeroall;\n":::); - if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } @@ -408,9 +405,6 @@ _gcry_camellia_cbc_dec(void *context, unsigned char *iv, int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 + 2 * sizeof(void *); - /* clear AVX registers */ - asm volatile ("vzeroall;\n":::); - if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } @@ -496,9 +490,6 @@ _gcry_camellia_cfb_dec(void *context, unsigned char *iv, int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 + 2 * sizeof(void *); - /* clear AVX registers */ - asm volatile ("vzeroall;\n":::); - if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } From dbaryshkov at gmail.com Mon Sep 2 11:28:48 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 2 Sep 2013 13:28:48 +0400 Subject: [PATCH 1/5] Add limited implementation of GOST 28147-89 cipher Message-ID: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> * src/gcrypt.h.in (GCRY_CIPHER_GOST28147): New. * cipher/gost.h, cipher/gost28147.c: New. * configure.ac (available_ciphers): Add gost28147. * src/cipher.h: Add gost28147 definitions. * cipher/cipher.c: Register gost28147. * tests/basic.c (check_ciphers): Enable simple test for gost28147. * doc/gcrypt.texi: document GCRY_CIPHER_GOST28147. -- Add a very basic implementation of GOST 28147-89 cipher: from modes defined in standard only ECB and CFB are supported, sbox is limited to the "test variant" as provided in GOST 34.11-94. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/Makefile.am | 1 + cipher/cipher.c | 4 + cipher/gost.h | 33 ++++++++ cipher/gost28147.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 8 +- doc/gcrypt.texi | 5 ++ src/cipher.h | 1 + src/gcrypt.h.in | 3 +- tests/basic.c | 3 + 9 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 cipher/gost.h create mode 100644 cipher/gost28147.c diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 3dd6f88..f3bd71c 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -62,6 +62,7 @@ dsa.c \ elgamal.c \ ecc.c ecc-curves.c ecc-misc.c ecc-common.h \ idea.c \ +gost28147.c gost.h \ md4.c \ md5.c \ rijndael.c rijndael-tables.h rijndael-amd64.S rijndael-armv6.S \ diff --git a/cipher/cipher.c b/cipher/cipher.c index 08d6165..c5553d6 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -108,6 +108,10 @@ static struct cipher_table_entry { &_gcry_cipher_spec_salsa20, &_gcry_cipher_extraspec_salsa20, GCRY_CIPHER_SALSA20 }, #endif +#if USE_GOST28147 + { &_gcry_cipher_spec_gost28147, + &dummy_extra_spec, GCRY_CIPHER_GOST28147 }, +#endif { NULL } }; diff --git a/cipher/gost.h b/cipher/gost.h new file mode 100644 index 0000000..e1cf033 --- /dev/null +++ b/cipher/gost.h @@ -0,0 +1,33 @@ +/* gost.h - GOST 28147-89 implementation + * Copyright (C) 2012 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef _GCRY_GOST_H +#define _GCRY_GOST_H + +typedef struct { + u32 subst[4][256]; + u32 key[8]; + int subst_set; +} GOST28147_context; + +/* This is a simple interface that will be used by GOST R 34.11-94 */ +extern void _gcry_gost_enc_one (GOST28147_context *c, const byte *key, + byte *out, byte *in); + +#endif diff --git a/cipher/gost28147.c b/cipher/gost28147.c new file mode 100644 index 0000000..5d6d1e7 --- /dev/null +++ b/cipher/gost28147.c @@ -0,0 +1,220 @@ +/* gost28147.c - GOST 28147-89 implementation for Libgcrypt + * Copyright (C) 2012 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +/* GOST 28147-89 defines several modes of encryption: + * - ECB which should be used only for key transfer + * - CFB mode + * - OFB-like mode with additional transformation on keystream + * RFC 5830 names this 'counter encryption' mode + * Original GOST text uses the term 'gammirovanie' + * - MAC mode + * + * This implementation handles ECB and CFB modes via usual libgcrypt handling. + * OFB-like and MAC modes are unsupported. + */ + +#include +#include "types.h" +#include "g10lib.h" +#include "cipher.h" + + +/* This is an s-box from RFC4357, named GostR3411-94-TestParamSet + * For now it is the only s-box supported, as libgcrypt lacks mechanism + * for passing parameters to cipher in a usefull way. */ +unsigned char test_sbox[16 * 8] = { + 0x4, 0xE, 0x5, 0x7, 0x6, 0x4, 0xD, 0x1, + 0xA, 0xB, 0x8, 0xD, 0xC, 0xB, 0xB, 0xF, + 0x9, 0x4, 0x1, 0xA, 0x7, 0xA, 0x4, 0xD, + 0x2, 0xC, 0xD, 0x1, 0x1, 0x0, 0x1, 0x0, + + 0xD, 0x6, 0xA, 0x0, 0x5, 0x7, 0x3, 0x5, + 0x8, 0xD, 0x3, 0x8, 0xF, 0x2, 0xF, 0x7, + 0x0, 0xF, 0x4, 0x9, 0xD, 0x1, 0x5, 0xA, + 0xE, 0xA, 0x2, 0xF, 0x8, 0xD, 0x9, 0x4, + + 0x6, 0x2, 0xE, 0xE, 0x4, 0x3, 0x0, 0x9, + 0xB, 0x3, 0xF, 0x4, 0xA, 0x6, 0xA, 0x2, + 0x1, 0x8, 0xC, 0x6, 0x9, 0x8, 0xE, 0x3, + 0xC, 0x1, 0x7, 0xC, 0xE, 0x5, 0x7, 0xE, + + 0x7, 0x0, 0x6, 0xB, 0x0, 0x9, 0x6, 0x6, + 0xF, 0x7, 0x0, 0x2, 0x3, 0xC, 0x8, 0xB, + 0x5, 0x5, 0x9, 0x5, 0xB, 0xF, 0x2, 0x8, + 0x3, 0x9, 0xB, 0x3, 0x2, 0xE, 0xC, 0xC, +}; + +#include "gost.h" + +static gcry_err_code_t +gost_setkey (void *c, const byte *key, unsigned keylen) +{ + int i; + GOST28147_context *ctx = c; + + if (keylen != 256 / 8) + return GPG_ERR_INV_KEYLEN; + + for (i = 0; i < 8; i++) + { + ctx->key[i] = (key[4 * i + 3] << 24) | + (key[4 * i + 2] << 16) | + (key[4 * i + 1] << 8) | + (key[4 * i + 0] << 0); + } + return GPG_ERR_NO_ERROR; +} + +static void +gost_set_subst (GOST28147_context *ctx, unsigned char *sbox) +{ + unsigned i, j; + for (i = 0; i < 4; i++) + { + for (j = 0; j < 256; j++) + { + ctx->subst[i][j] = sbox[ (j & 0xf) * 8 + 2 * i + 0] | + (sbox[ (j >> 4) * 8 + 2 * i + 1] << 4); + } + } + ctx->subst_set = 1; +} + +static u32 +gost_val (GOST28147_context *ctx, u32 cm1, int subkey) +{ + cm1 += ctx->key[subkey]; + cm1 = (ctx->subst[0][ (cm1 >> 0) & 0xff] << 0) | + (ctx->subst[1][ (cm1 >> 8) & 0xff] << 8) | + (ctx->subst[2][ (cm1 >> 16) & 0xff] << 16) | + (ctx->subst[3][ (cm1 >> 24) & 0xff] << 24); + return (cm1 << 11) | (cm1 >> 21); +} + +static void +gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) +{ + GOST28147_context *ctx = c; + u32 n1, n2; + + if (!ctx->subst_set) + gost_set_subst (ctx, test_sbox); + + n1 = (inbuf[0] << 0) | + (inbuf[1] << 8) | + (inbuf[2] << 16) | + (inbuf[3] << 24); + n2 = (inbuf[4] << 0) | + (inbuf[5] << 8) | + (inbuf[6] << 16) | + (inbuf[7] << 24); + + n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); + n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); + n2 ^= gost_val (ctx, n1, 4); n1 ^= gost_val (ctx, n2, 5); + n2 ^= gost_val (ctx, n1, 6); n1 ^= gost_val (ctx, n2, 7); + + n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); + n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); + n2 ^= gost_val (ctx, n1, 4); n1 ^= gost_val (ctx, n2, 5); + n2 ^= gost_val (ctx, n1, 6); n1 ^= gost_val (ctx, n2, 7); + + n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); + n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); + n2 ^= gost_val (ctx, n1, 4); n1 ^= gost_val (ctx, n2, 5); + n2 ^= gost_val (ctx, n1, 6); n1 ^= gost_val (ctx, n2, 7); + + n2 ^= gost_val (ctx, n1, 7); n1 ^= gost_val (ctx, n2, 6); + n2 ^= gost_val (ctx, n1, 5); n1 ^= gost_val (ctx, n2, 4); + n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); + n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); + + outbuf[0 + 0] = (n2 >> (0 * 8)) & 0xff; + outbuf[1 + 0] = (n2 >> (1 * 8)) & 0xff; + outbuf[2 + 0] = (n2 >> (2 * 8)) & 0xff; + outbuf[3 + 0] = (n2 >> (3 * 8)) & 0xff; + outbuf[0 + 4] = (n1 >> (0 * 8)) & 0xff; + outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; + outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; + outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; +} + +void _gcry_gost_enc_one (GOST28147_context *c, const byte *key, + byte *out, byte *in) +{ + gost_setkey (c, key, 32); + gost_encrypt_block (c, out, in); +} + +static void +gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) +{ + GOST28147_context *ctx = c; + u32 n1, n2; + + if (!ctx->subst_set) + gost_set_subst (ctx, test_sbox); + + n1 = (inbuf[0] << 0) | + (inbuf[1] << 8) | + (inbuf[2] << 16) | + (inbuf[3] << 24); + n2 = (inbuf[4] << 0) | + (inbuf[5] << 8) | + (inbuf[6] << 16) | + (inbuf[7] << 24); + + n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); + n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); + n2 ^= gost_val (ctx, n1, 4); n1 ^= gost_val (ctx, n2, 5); + n2 ^= gost_val (ctx, n1, 6); n1 ^= gost_val (ctx, n2, 7); + + n2 ^= gost_val (ctx, n1, 7); n1 ^= gost_val (ctx, n2, 6); + n2 ^= gost_val (ctx, n1, 5); n1 ^= gost_val (ctx, n2, 4); + n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); + n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); + + n2 ^= gost_val (ctx, n1, 7); n1 ^= gost_val (ctx, n2, 6); + n2 ^= gost_val (ctx, n1, 5); n1 ^= gost_val (ctx, n2, 4); + n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); + n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); + + n2 ^= gost_val (ctx, n1, 7); n1 ^= gost_val (ctx, n2, 6); + n2 ^= gost_val (ctx, n1, 5); n1 ^= gost_val (ctx, n2, 4); + n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); + n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); + + outbuf[0 + 0] = (n2 >> (0 * 8)) & 0xff; + outbuf[1 + 0] = (n2 >> (1 * 8)) & 0xff; + outbuf[2 + 0] = (n2 >> (2 * 8)) & 0xff; + outbuf[3 + 0] = (n2 >> (3 * 8)) & 0xff; + outbuf[0 + 4] = (n1 >> (0 * 8)) & 0xff; + outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; + outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; + outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; +} + +gcry_cipher_spec_t _gcry_cipher_spec_gost28147 = + { + "GOST28147", NULL, NULL, 8, 256, + sizeof (GOST28147_context), + gost_setkey, + gost_encrypt_block, + gost_decrypt_block, + }; diff --git a/configure.ac b/configure.ac index 959327a..21ca88d 100644 --- a/configure.ac +++ b/configure.ac @@ -184,7 +184,7 @@ LIBGCRYPT_CONFIG_HOST="$host" # Definitions for symmetric ciphers. available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed" -available_ciphers="$available_ciphers camellia idea salsa20" +available_ciphers="$available_ciphers camellia idea salsa20 gost28147" enabled_ciphers="" # Definitions for public-key ciphers. @@ -1473,6 +1473,12 @@ if test "$found" = "1" ; then AC_DEFINE(USE_SALSA20, 1, [Defined if this module should be included]) fi +LIST_MEMBER(gost28147, $enabled_ciphers) +if test "$found" = "1" ; then + GCRYPT_CIPHERS="$GCRYPT_CIPHERS gost28147.lo" + AC_DEFINE(USE_GOST28147, 1, [Defined if this module should be included]) +fi + LIST_MEMBER(dsa, $enabled_pubkey_ciphers) if test "$found" = "1" ; then GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS dsa.lo" diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 770a245..d5b5955 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -1579,6 +1579,11 @@ The Camellia cipher by NTT. See @cindex Salsa20 This is the Salsa20 stream cipher. + at item GCRY_CIPHER_GOST28147 + at cindex GOST 28147-89 +The GOST 28147-89 cipher, defined in the respective GOST standard. +Translation of this GOST into English is provided in the RFC-5830. + @end table @node Available cipher modes diff --git a/src/cipher.h b/src/cipher.h index bb92758..9e725bc 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -196,6 +196,7 @@ extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192; extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256; extern gcry_cipher_spec_t _gcry_cipher_spec_idea; extern gcry_cipher_spec_t _gcry_cipher_spec_salsa20; +extern gcry_cipher_spec_t _gcry_cipher_spec_gost28147; extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes; extern cipher_extra_spec_t _gcry_cipher_extraspec_aes; diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 06d6663..8be0bf0 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -820,7 +820,8 @@ enum gcry_cipher_algos GCRY_CIPHER_CAMELLIA128 = 310, GCRY_CIPHER_CAMELLIA192 = 311, GCRY_CIPHER_CAMELLIA256 = 312, - GCRY_CIPHER_SALSA20 = 313 + GCRY_CIPHER_SALSA20 = 313, + GCRY_CIPHER_GOST28147 = 314 }; /* The Rijndael algorithm is basically AES, so provide some macros. */ diff --git a/tests/basic.c b/tests/basic.c index 46e213c..9c210df 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -2162,6 +2162,9 @@ check_ciphers (void) #if USE_IDEA GCRY_CIPHER_IDEA, #endif +#if USE_GOST28147 + GCRY_CIPHER_GOST28147, +#endif 0 }; static int algos2[] = { -- 1.8.4.rc3 From dbaryshkov at gmail.com Mon Sep 2 11:28:49 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 2 Sep 2013 13:28:49 +0400 Subject: [PATCH 2/5] Separate common md block code In-Reply-To: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> References: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1378114132-7587-2-git-send-email-dbaryshkov@gmail.com> * cipher/hash-common.c, cipher/hash-common.h: add _gcry_md_block_write() a new function to handle block md operations. Currently implementation is limited to 64 bytes buffer and u32 blocks counter. * cipher/md4.c, cipher/md5.c, cipher/rmd.h, cipher/rmd160.c, cipher/sha1.c, cipher/sha256.c, cipher/tiger.c: convert to use _gcry_md_block_write(). whirpool and sha512 are left as before, as sha512 uses 128 bytes buffer and u64 blocks counter and whirpool does not have trivial block handling structure. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/hash-common.c | 42 ++++++++++++++++++ cipher/hash-common.h | 19 ++++++-- cipher/md4.c | 109 +++++++++++++++------------------------------- cipher/md5.c | 110 +++++++++++++++------------------------------- cipher/rmd.h | 5 +-- cipher/rmd160.c | 104 +++++++++++++++---------------------------- cipher/sha1.c | 121 +++++++++++++++------------------------------------ cipher/sha256.c | 113 +++++++++++++++++------------------------------ cipher/tiger.c | 112 ++++++++++++++++------------------------------- 9 files changed, 279 insertions(+), 456 deletions(-) diff --git a/cipher/hash-common.c b/cipher/hash-common.c index 8c413bc..e267da1 100644 --- a/cipher/hash-common.c +++ b/cipher/hash-common.c @@ -91,3 +91,45 @@ _gcry_hash_selftest_check_one (int algo, return result; } + +void +_gcry_md_block_write( void *context, const void *inbuf_arg, size_t inlen) +{ + const unsigned char *inbuf = inbuf_arg; + gcry_md_block_ctx_t *hd = context; + + if ( hd->buf == NULL || hd->bwrite == NULL) + return; + + if( hd->count == hd->blocksize ) /* flush the buffer */ + { + hd->bwrite( hd, hd->buf ); + _gcry_burn_stack (hd->stack_burn); + hd->count = 0; + hd->nblocks++; + } + if( !inbuf ) + return; + + if( hd->count ) + { + for( ; inlen && hd->count < hd->blocksize; inlen-- ) + hd->buf[hd->count++] = *inbuf++; + _gcry_md_block_write( hd, NULL, 0 ); + if( !inlen ) + return; + } + + while( inlen >= hd->blocksize) + { + hd->bwrite( hd, inbuf ); + hd->count = 0; + hd->nblocks++; + inlen -= hd->blocksize; + inbuf += hd->blocksize; + } + _gcry_burn_stack (hd->stack_burn); + for( ; inlen && hd->count < hd->blocksize; inlen-- ) + hd->buf[hd->count++] = *inbuf++; + +} diff --git a/cipher/hash-common.h b/cipher/hash-common.h index fdebef4..9553dcf 100644 --- a/cipher/hash-common.h +++ b/cipher/hash-common.h @@ -26,8 +26,21 @@ const char * _gcry_hash_selftest_check_one int datamode, const void *data, size_t datalen, const void *expect, size_t expectlen); - - - +/* Type for the md_write helper function for block MD. */ +typedef void (*_gcry_md_block_write_t) (void *c, const unsigned char *buf); + +typedef struct gcry_md_block_ctx +{ + u32 nblocks; + int count; + byte buf[64]; + size_t blocksize; + _gcry_md_block_write_t bwrite; + size_t stack_burn; +} gcry_md_block_ctx_t; + + +void +_gcry_md_block_write( void *context, const void *inbuf_arg, size_t inlen); #endif /*GCRY_HASH_COMMON_H*/ diff --git a/cipher/md4.c b/cipher/md4.c index 22fbf8d..9e75fbc 100644 --- a/cipher/md4.c +++ b/cipher/md4.c @@ -56,15 +56,16 @@ #include "cipher.h" #include "bithelp.h" +#include "hash-common.h" typedef struct { + gcry_md_block_ctx_t bctx; u32 A,B,C,D; /* chaining variables */ - u32 nblocks; - byte buf[64]; - int count; } MD4_CONTEXT; +static void +transform ( void *c, const unsigned char *data ); static void md4_init( void *context ) @@ -76,8 +77,11 @@ md4_init( void *context ) ctx->C = 0x98badcfe; ctx->D = 0x10325476; - ctx->nblocks = 0; - ctx->count = 0; + ctx->bctx.nblocks = 0; + ctx->bctx.count = 0; + ctx->bctx.blocksize = 64; + ctx->bctx.stack_burn = 80+6*sizeof(void*); + ctx->bctx.bwrite = transform; } #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) @@ -89,8 +93,9 @@ md4_init( void *context ) * transform 64 bytes */ static void -transform ( MD4_CONTEXT *ctx, const unsigned char *data ) +transform ( void *c, const unsigned char *data ) { + MD4_CONTEXT *ctx = c; u32 in[16]; register u32 A = ctx->A; register u32 B = ctx->B; @@ -187,50 +192,6 @@ transform ( MD4_CONTEXT *ctx, const unsigned char *data ) -/* The routine updates the message-digest context to - * account for the presence of each of the characters inBuf[0..inLen-1] - * in the message whose digest is being computed. - */ -static void -md4_write ( void *context, const void *inbuf_arg, size_t inlen) -{ - const unsigned char *inbuf = inbuf_arg; - MD4_CONTEXT *hd = context; - - if( hd->count == 64 ) /* flush the buffer */ - { - transform( hd, hd->buf ); - _gcry_burn_stack (80+6*sizeof(void*)); - hd->count = 0; - hd->nblocks++; - } - if( !inbuf ) - return; - - if( hd->count ) - { - for( ; inlen && hd->count < 64; inlen-- ) - hd->buf[hd->count++] = *inbuf++; - md4_write( hd, NULL, 0 ); - if( !inlen ) - return; - } - _gcry_burn_stack (80+6*sizeof(void*)); - - while( inlen >= 64 ) - { - transform( hd, inbuf ); - hd->count = 0; - hd->nblocks++; - inlen -= 64; - inbuf += 64; - } - for( ; inlen && hd->count < 64; inlen-- ) - hd->buf[hd->count++] = *inbuf++; -} - - - /* The routine final terminates the message-digest computation and * ends with the desired message digest in mdContext->digest[0...15]. * The handle is prepared for a new MD4 cycle. @@ -244,15 +205,15 @@ md4_final( void *context ) u32 t, msb, lsb; byte *p; - md4_write(hd, NULL, 0); /* flush */; + _gcry_md_block_write(hd, NULL, 0); /* flush */; - t = hd->nblocks; + t = hd->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 26; /* add the count */ t = lsb; - if( (lsb += hd->count) < t ) + if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -260,33 +221,33 @@ md4_final( void *context ) msb <<= 3; msb |= t >> 29; - if( hd->count < 56 ) /* enough room */ + if( hd->bctx.count < 56 ) /* enough room */ { - hd->buf[hd->count++] = 0x80; /* pad */ - while( hd->count < 56 ) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ + while( hd->bctx.count < 56 ) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else /* need one extra block */ { - hd->buf[hd->count++] = 0x80; /* pad character */ - while( hd->count < 64 ) - hd->buf[hd->count++] = 0; - md4_write(hd, NULL, 0); /* flush */; - memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ + while( hd->bctx.count < 64 ) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write(hd, NULL, 0); /* flush */; + memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->buf[56] = lsb ; - hd->buf[57] = lsb >> 8; - hd->buf[58] = lsb >> 16; - hd->buf[59] = lsb >> 24; - hd->buf[60] = msb ; - hd->buf[61] = msb >> 8; - hd->buf[62] = msb >> 16; - hd->buf[63] = msb >> 24; - transform( hd, hd->buf ); + hd->bctx.buf[56] = lsb ; + hd->bctx.buf[57] = lsb >> 8; + hd->bctx.buf[58] = lsb >> 16; + hd->bctx.buf[59] = lsb >> 24; + hd->bctx.buf[60] = msb ; + hd->bctx.buf[61] = msb >> 8; + hd->bctx.buf[62] = msb >> 16; + hd->bctx.buf[63] = msb >> 24; + transform( hd, hd->bctx.buf ); _gcry_burn_stack (80+6*sizeof(void*)); - p = hd->buf; + p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN #define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0) @@ -305,7 +266,7 @@ static byte * md4_read (void *context) { MD4_CONTEXT *hd = context; - return hd->buf; + return hd->bctx.buf; } static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */ @@ -322,6 +283,6 @@ static gcry_md_oid_spec_t oid_spec_md4[] = gcry_md_spec_t _gcry_digest_spec_md4 = { "MD4", asn, DIM (asn), oid_spec_md4,16, - md4_init, md4_write, md4_final, md4_read, + md4_init, _gcry_md_block_write, md4_final, md4_read, sizeof (MD4_CONTEXT) }; diff --git a/cipher/md5.c b/cipher/md5.c index a98678a..9857f2c 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -40,15 +40,16 @@ #include "cipher.h" #include "bithelp.h" +#include "hash-common.h" typedef struct { + gcry_md_block_ctx_t bctx; u32 A,B,C,D; /* chaining variables */ - u32 nblocks; - byte buf[64]; - int count; } MD5_CONTEXT; +static void +transform ( void *ctx, const unsigned char *data ); static void md5_init( void *context ) @@ -60,8 +61,11 @@ md5_init( void *context ) ctx->C = 0x98badcfe; ctx->D = 0x10325476; - ctx->nblocks = 0; - ctx->count = 0; + ctx->bctx.nblocks = 0; + ctx->bctx.count = 0; + ctx->bctx.blocksize = 64; + ctx->bctx.stack_burn = 80+6*sizeof(void*); + ctx->bctx.bwrite = transform; } @@ -79,8 +83,9 @@ md5_init( void *context ) * transform n*64 bytes */ static void -transform ( MD5_CONTEXT *ctx, const unsigned char *data ) +transform ( void *c, const unsigned char *data ) { + MD5_CONTEXT *ctx = c; u32 correct_words[16]; register u32 A = ctx->A; register u32 B = ctx->B; @@ -212,51 +217,6 @@ transform ( MD5_CONTEXT *ctx, const unsigned char *data ) -/* The routine updates the message-digest context to - * account for the presence of each of the characters inBuf[0..inLen-1] - * in the message whose digest is being computed. - */ -static void -md5_write( void *context, const void *inbuf_arg , size_t inlen) -{ - const unsigned char *inbuf = inbuf_arg; - MD5_CONTEXT *hd = context; - - if( hd->count == 64 ) /* flush the buffer */ - { - transform( hd, hd->buf ); - _gcry_burn_stack (80+6*sizeof(void*)); - hd->count = 0; - hd->nblocks++; - } - if( !inbuf ) - return; - - if( hd->count ) - { - for( ; inlen && hd->count < 64; inlen-- ) - hd->buf[hd->count++] = *inbuf++; - md5_write( hd, NULL, 0 ); - if( !inlen ) - return; - } - _gcry_burn_stack (80+6*sizeof(void*)); - - while( inlen >= 64 ) - { - transform( hd, inbuf ); - hd->count = 0; - hd->nblocks++; - inlen -= 64; - inbuf += 64; - } - for( ; inlen && hd->count < 64; inlen-- ) - hd->buf[hd->count++] = *inbuf++; - -} - - - /* The routine final terminates the message-digest computation and * ends with the desired message digest in mdContext->digest[0...15]. * The handle is prepared for a new MD5 cycle. @@ -270,15 +230,15 @@ md5_final( void *context) u32 t, msb, lsb; byte *p; - md5_write(hd, NULL, 0); /* flush */; + _gcry_md_block_write(hd, NULL, 0); /* flush */; - t = hd->nblocks; + t = hd->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 26; /* add the count */ t = lsb; - if( (lsb += hd->count) < t ) + if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -286,33 +246,33 @@ md5_final( void *context) msb <<= 3; msb |= t >> 29; - if( hd->count < 56 ) /* enough room */ + if( hd->bctx.count < 56 ) /* enough room */ { - hd->buf[hd->count++] = 0x80; /* pad */ - while( hd->count < 56 ) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ + while( hd->bctx.count < 56 ) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else /* need one extra block */ { - hd->buf[hd->count++] = 0x80; /* pad character */ - while( hd->count < 64 ) - hd->buf[hd->count++] = 0; - md5_write(hd, NULL, 0); /* flush */; - memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ + while( hd->bctx.count < 64 ) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write(hd, NULL, 0); /* flush */; + memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->buf[56] = lsb ; - hd->buf[57] = lsb >> 8; - hd->buf[58] = lsb >> 16; - hd->buf[59] = lsb >> 24; - hd->buf[60] = msb ; - hd->buf[61] = msb >> 8; - hd->buf[62] = msb >> 16; - hd->buf[63] = msb >> 24; - transform( hd, hd->buf ); + hd->bctx.buf[56] = lsb ; + hd->bctx.buf[57] = lsb >> 8; + hd->bctx.buf[58] = lsb >> 16; + hd->bctx.buf[59] = lsb >> 24; + hd->bctx.buf[60] = msb ; + hd->bctx.buf[61] = msb >> 8; + hd->bctx.buf[62] = msb >> 16; + hd->bctx.buf[63] = msb >> 24; + transform( hd, hd->bctx.buf ); _gcry_burn_stack (80+6*sizeof(void*)); - p = hd->buf; + p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN #define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0) @@ -331,7 +291,7 @@ static byte * md5_read( void *context ) { MD5_CONTEXT *hd = (MD5_CONTEXT *) context; - return hd->buf; + return hd->bctx.buf; } static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */ @@ -350,6 +310,6 @@ static gcry_md_oid_spec_t oid_spec_md5[] = gcry_md_spec_t _gcry_digest_spec_md5 = { "MD5", asn, DIM (asn), oid_spec_md5, 16, - md5_init, md5_write, md5_final, md5_read, + md5_init, _gcry_md_block_write, md5_final, md5_read, sizeof (MD5_CONTEXT) }; diff --git a/cipher/rmd.h b/cipher/rmd.h index 6a9fe31..a56ee49 100644 --- a/cipher/rmd.h +++ b/cipher/rmd.h @@ -20,14 +20,13 @@ #ifndef G10_RMD_H #define G10_RMD_H +#include "hash-common.h" /* We need this here because random.c must have direct access. */ typedef struct { + gcry_md_block_ctx_t bctx; u32 h0,h1,h2,h3,h4; - u32 nblocks; - byte buf[64]; - int count; } RMD160_CONTEXT; void _gcry_rmd160_init ( void *context ); diff --git a/cipher/rmd160.c b/cipher/rmd160.c index 179a4d9..5bb32a6 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -139,6 +139,8 @@ * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528 */ +static void +transform ( void *ctx, const unsigned char *data ); void _gcry_rmd160_init (void *context) @@ -150,8 +152,11 @@ _gcry_rmd160_init (void *context) hd->h2 = 0x98BADCFE; hd->h3 = 0x10325476; hd->h4 = 0xC3D2E1F0; - hd->nblocks = 0; - hd->count = 0; + hd->bctx.nblocks = 0; + hd->bctx.count = 0; + hd->bctx.blocksize = 64; + hd->bctx.stack_burn = 108+5*sizeof(void*); + hd->bctx.bwrite = transform; } @@ -160,8 +165,9 @@ _gcry_rmd160_init (void *context) * Transform the message X which consists of 16 32-bit-words */ static void -transform ( RMD160_CONTEXT *hd, const unsigned char *data ) +transform ( void *ctx, const unsigned char *data ) { + RMD160_CONTEXT *hd = ctx; register u32 a,b,c,d,e; u32 aa,bb,cc,dd,ee,t; #ifdef WORDS_BIGENDIAN @@ -397,46 +403,6 @@ transform ( RMD160_CONTEXT *hd, const unsigned char *data ) } -/* Update the message digest with the contents - * of INBUF with length INLEN. - */ -static void -rmd160_write ( void *context, const void *inbuf_arg, size_t inlen) -{ - const unsigned char *inbuf = inbuf_arg; - RMD160_CONTEXT *hd = context; - - if( hd->count == 64 ) /* flush the buffer */ - { - transform( hd, hd->buf ); - _gcry_burn_stack (108+5*sizeof(void*)); - hd->count = 0; - hd->nblocks++; - } - if( !inbuf ) - return; - if( hd->count ) - { - for( ; inlen && hd->count < 64; inlen-- ) - hd->buf[hd->count++] = *inbuf++; - rmd160_write( hd, NULL, 0 ); - if( !inlen ) - return; - } - - while( inlen >= 64 ) - { - transform( hd, inbuf ); - hd->count = 0; - hd->nblocks++; - inlen -= 64; - inbuf += 64; - } - _gcry_burn_stack (108+5*sizeof(void*)); - for( ; inlen && hd->count < 64; inlen-- ) - hd->buf[hd->count++] = *inbuf++; -} - /**************** * Apply the rmd160 transform function on the buffer which must have * a length 64 bytes. Do not use this function together with the @@ -469,15 +435,15 @@ rmd160_final( void *context ) u32 t, msb, lsb; byte *p; - rmd160_write(hd, NULL, 0); /* flush */; + _gcry_md_block_write(hd, NULL, 0); /* flush */; - t = hd->nblocks; + t = hd->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 26; /* add the count */ t = lsb; - if( (lsb += hd->count) < t ) + if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -485,33 +451,33 @@ rmd160_final( void *context ) msb <<= 3; msb |= t >> 29; - if( hd->count < 56 ) /* enough room */ + if( hd->bctx.count < 56 ) /* enough room */ { - hd->buf[hd->count++] = 0x80; /* pad */ - while( hd->count < 56 ) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ + while( hd->bctx.count < 56 ) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else /* need one extra block */ { - hd->buf[hd->count++] = 0x80; /* pad character */ - while( hd->count < 64 ) - hd->buf[hd->count++] = 0; - rmd160_write(hd, NULL, 0); /* flush */; - memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ + while( hd->bctx.count < 64 ) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write(hd, NULL, 0); /* flush */; + memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->buf[56] = lsb ; - hd->buf[57] = lsb >> 8; - hd->buf[58] = lsb >> 16; - hd->buf[59] = lsb >> 24; - hd->buf[60] = msb ; - hd->buf[61] = msb >> 8; - hd->buf[62] = msb >> 16; - hd->buf[63] = msb >> 24; - transform( hd, hd->buf ); + hd->bctx.buf[56] = lsb ; + hd->bctx.buf[57] = lsb >> 8; + hd->bctx.buf[58] = lsb >> 16; + hd->bctx.buf[59] = lsb >> 24; + hd->bctx.buf[60] = msb ; + hd->bctx.buf[61] = msb >> 8; + hd->bctx.buf[62] = msb >> 16; + hd->bctx.buf[63] = msb >> 24; + transform( hd, hd->bctx.buf ); _gcry_burn_stack (108+5*sizeof(void*)); - p = hd->buf; + p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN #define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \ *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0) @@ -531,7 +497,7 @@ rmd160_read( void *context ) { RMD160_CONTEXT *hd = context; - return hd->buf; + return hd->bctx.buf; } @@ -546,9 +512,9 @@ _gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length ) RMD160_CONTEXT hd; _gcry_rmd160_init ( &hd ); - rmd160_write ( &hd, buffer, length ); + _gcry_md_block_write ( &hd, buffer, length ); rmd160_final ( &hd ); - memcpy ( outbuf, hd.buf, 20 ); + memcpy ( outbuf, hd.bctx.buf, 20 ); } static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */ @@ -567,6 +533,6 @@ static gcry_md_oid_spec_t oid_spec_rmd160[] = gcry_md_spec_t _gcry_digest_spec_rmd160 = { "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20, - _gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read, + _gcry_rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read, sizeof (RMD160_CONTEXT) }; diff --git a/cipher/sha1.c b/cipher/sha1.c index 4b784ac..6777348 100644 --- a/cipher/sha1.c +++ b/cipher/sha1.c @@ -51,18 +51,15 @@ /* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */ /* #endif */ -#define TRANSFORM(x,d,n) transform ((x), (d), (n)) - - typedef struct { + gcry_md_block_ctx_t bctx; u32 h0,h1,h2,h3,h4; - u32 nblocks; - unsigned char buf[64]; - int count; } SHA1_CONTEXT; +static void +transform (void *c, const unsigned char *data); static void sha1_init (void *context) @@ -74,8 +71,11 @@ sha1_init (void *context) hd->h2 = 0x98badcfe; hd->h3 = 0x10325476; hd->h4 = 0xc3d2e1f0; - hd->nblocks = 0; - hd->count = 0; + hd->bctx.nblocks = 0; + hd->bctx.count = 0; + hd->bctx.blocksize = 64; + hd->bctx.stack_burn = 88+4*sizeof(void*); + hd->bctx.bwrite = transform; } @@ -105,15 +105,13 @@ sha1_init (void *context) * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA. */ static void -transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks) +transform (void *ctx, const unsigned char *data) { + SHA1_CONTEXT *hd = ctx; register u32 a, b, c, d, e; /* Local copies of the chaining variables. */ register u32 tm; /* Helper. */ u32 x[16]; /* The array we work on. */ - /* Loop over all blocks. */ - for ( ;nblocks; nblocks--) - { #ifdef WORDS_BIGENDIAN memcpy (x, data, 64); data += 64; @@ -226,53 +224,6 @@ transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks) hd->h2 += c; hd->h3 += d; hd->h4 += e; - } -} - - -/* Update the message digest with the contents - * of INBUF with length INLEN. - */ -static void -sha1_write( void *context, const void *inbuf_arg, size_t inlen) -{ - const unsigned char *inbuf = inbuf_arg; - SHA1_CONTEXT *hd = context; - size_t nblocks; - - if (hd->count == 64) /* Flush the buffer. */ - { - TRANSFORM( hd, hd->buf, 1 ); - _gcry_burn_stack (88+4*sizeof(void*)); - hd->count = 0; - hd->nblocks++; - } - if (!inbuf) - return; - - if (hd->count) - { - for (; inlen && hd->count < 64; inlen--) - hd->buf[hd->count++] = *inbuf++; - sha1_write (hd, NULL, 0); - if (!inlen) - return; - } - - nblocks = inlen / 64; - if (nblocks) - { - TRANSFORM (hd, inbuf, nblocks); - hd->count = 0; - hd->nblocks += nblocks; - inlen -= nblocks * 64; - inbuf += nblocks * 64; - } - _gcry_burn_stack (88+4*sizeof(void*)); - - /* Save remaining bytes. */ - for (; inlen && hd->count < 64; inlen--) - hd->buf[hd->count++] = *inbuf++; } @@ -291,15 +242,15 @@ sha1_final(void *context) u32 t, msb, lsb; unsigned char *p; - sha1_write(hd, NULL, 0); /* flush */; + _gcry_md_block_write (hd, NULL, 0); /* flush */; - t = hd->nblocks; + t = hd->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 26; /* add the count */ t = lsb; - if( (lsb += hd->count) < t ) + if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -307,33 +258,33 @@ sha1_final(void *context) msb <<= 3; msb |= t >> 29; - if( hd->count < 56 ) /* enough room */ + if( hd->bctx.count < 56 ) /* enough room */ { - hd->buf[hd->count++] = 0x80; /* pad */ - while( hd->count < 56 ) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ + while( hd->bctx.count < 56 ) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else /* need one extra block */ { - hd->buf[hd->count++] = 0x80; /* pad character */ - while( hd->count < 64 ) - hd->buf[hd->count++] = 0; - sha1_write(hd, NULL, 0); /* flush */; - memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ + while( hd->bctx.count < 64 ) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write(hd, NULL, 0); /* flush */; + memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->buf[56] = msb >> 24; - hd->buf[57] = msb >> 16; - hd->buf[58] = msb >> 8; - hd->buf[59] = msb ; - hd->buf[60] = lsb >> 24; - hd->buf[61] = lsb >> 16; - hd->buf[62] = lsb >> 8; - hd->buf[63] = lsb ; - TRANSFORM( hd, hd->buf, 1 ); + hd->bctx.buf[56] = msb >> 24; + hd->bctx.buf[57] = msb >> 16; + hd->bctx.buf[58] = msb >> 8; + hd->bctx.buf[59] = msb ; + hd->bctx.buf[60] = lsb >> 24; + hd->bctx.buf[61] = lsb >> 16; + hd->bctx.buf[62] = lsb >> 8; + hd->bctx.buf[63] = lsb ; + transform( hd, hd->bctx.buf ); _gcry_burn_stack (88+4*sizeof(void*)); - p = hd->buf; + p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) #else /* little endian */ @@ -354,7 +305,7 @@ sha1_read( void *context ) { SHA1_CONTEXT *hd = context; - return hd->buf; + return hd->bctx.buf; } /**************** @@ -367,9 +318,9 @@ _gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length) SHA1_CONTEXT hd; sha1_init (&hd); - sha1_write (&hd, buffer, length); + _gcry_md_block_write (&hd, buffer, length); sha1_final (&hd); - memcpy (outbuf, hd.buf, 20); + memcpy (outbuf, hd.bctx.buf, 20); } @@ -468,7 +419,7 @@ static gcry_md_oid_spec_t oid_spec_sha1[] = gcry_md_spec_t _gcry_digest_spec_sha1 = { "SHA1", asn, DIM (asn), oid_spec_sha1, 20, - sha1_init, sha1_write, sha1_final, sha1_read, + sha1_init, _gcry_md_block_write, sha1_final, sha1_read, sizeof (SHA1_CONTEXT) }; md_extra_spec_t _gcry_digest_extraspec_sha1 = diff --git a/cipher/sha256.c b/cipher/sha256.c index 309fa3b..1785699 100644 --- a/cipher/sha256.c +++ b/cipher/sha256.c @@ -46,12 +46,12 @@ #include "hash-common.h" typedef struct { + gcry_md_block_ctx_t bctx; u32 h0,h1,h2,h3,h4,h5,h6,h7; - u32 nblocks; - byte buf[64]; - int count; } SHA256_CONTEXT; +static void +transform (void *c, const unsigned char *data); static void sha256_init (void *context) @@ -67,8 +67,11 @@ sha256_init (void *context) hd->h6 = 0x1f83d9ab; hd->h7 = 0x5be0cd19; - hd->nblocks = 0; - hd->count = 0; + hd->bctx.nblocks = 0; + hd->bctx.count = 0; + hd->bctx.blocksize = 64; + hd->bctx.stack_burn = 74*4+32; + hd->bctx.bwrite = transform; } @@ -86,8 +89,11 @@ sha224_init (void *context) hd->h6 = 0x64f98fa7; hd->h7 = 0xbefa4fa4; - hd->nblocks = 0; - hd->count = 0; + hd->bctx.nblocks = 0; + hd->bctx.count = 0; + hd->bctx.blocksize = 64; + hd->bctx.stack_burn = 74*4+32; + hd->bctx.bwrite = transform; } @@ -140,8 +146,9 @@ Sum1 (u32 x) static void -transform (SHA256_CONTEXT *hd, const unsigned char *data) +transform (void *ctx, const unsigned char *data) { + SHA256_CONTEXT *hd = ctx; static const u32 K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, @@ -260,46 +267,6 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data) #undef R -/* Update the message digest with the contents of INBUF with length - INLEN. */ -static void -sha256_write (void *context, const void *inbuf_arg, size_t inlen) -{ - const unsigned char *inbuf = inbuf_arg; - SHA256_CONTEXT *hd = context; - - if (hd->count == 64) - { /* flush the buffer */ - transform (hd, hd->buf); - _gcry_burn_stack (74*4+32); - hd->count = 0; - hd->nblocks++; - } - if (!inbuf) - return; - if (hd->count) - { - for (; inlen && hd->count < 64; inlen--) - hd->buf[hd->count++] = *inbuf++; - sha256_write (hd, NULL, 0); - if (!inlen) - return; - } - - while (inlen >= 64) - { - transform (hd, inbuf); - hd->count = 0; - hd->nblocks++; - inlen -= 64; - inbuf += 64; - } - _gcry_burn_stack (74*4+32); - for (; inlen && hd->count < 64; inlen--) - hd->buf[hd->count++] = *inbuf++; -} - - /* The routine finally terminates the computation and returns the digest. The handle is prepared for a new cycle, but adding bytes @@ -312,15 +279,15 @@ sha256_final(void *context) u32 t, msb, lsb; byte *p; - sha256_write (hd, NULL, 0); /* flush */; + _gcry_md_block_write (hd, NULL, 0); /* flush */; - t = hd->nblocks; + t = hd->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 26; /* add the count */ t = lsb; - if ((lsb += hd->count) < t) + if ((lsb += hd->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -328,33 +295,33 @@ sha256_final(void *context) msb <<= 3; msb |= t >> 29; - if (hd->count < 56) + if (hd->bctx.count < 56) { /* enough room */ - hd->buf[hd->count++] = 0x80; /* pad */ - while (hd->count < 56) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ + while (hd->bctx.count < 56) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else { /* need one extra block */ - hd->buf[hd->count++] = 0x80; /* pad character */ - while (hd->count < 64) - hd->buf[hd->count++] = 0; - sha256_write (hd, NULL, 0); /* flush */; - memset (hd->buf, 0, 56 ); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ + while (hd->bctx.count < 64) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write (hd, NULL, 0); /* flush */; + memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->buf[56] = msb >> 24; - hd->buf[57] = msb >> 16; - hd->buf[58] = msb >> 8; - hd->buf[59] = msb; - hd->buf[60] = lsb >> 24; - hd->buf[61] = lsb >> 16; - hd->buf[62] = lsb >> 8; - hd->buf[63] = lsb; - transform (hd, hd->buf); + hd->bctx.buf[56] = msb >> 24; + hd->bctx.buf[57] = msb >> 16; + hd->bctx.buf[58] = msb >> 8; + hd->bctx.buf[59] = msb; + hd->bctx.buf[60] = lsb >> 24; + hd->bctx.buf[61] = lsb >> 16; + hd->bctx.buf[62] = lsb >> 8; + hd->bctx.buf[63] = lsb; + transform (hd, hd->bctx.buf); _gcry_burn_stack (74*4+32); - p = hd->buf; + p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) #else /* little endian */ @@ -377,7 +344,7 @@ sha256_read (void *context) { SHA256_CONTEXT *hd = context; - return hd->buf; + return hd->bctx.buf; } @@ -534,7 +501,7 @@ static gcry_md_oid_spec_t oid_spec_sha256[] = gcry_md_spec_t _gcry_digest_spec_sha224 = { "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28, - sha224_init, sha256_write, sha256_final, sha256_read, + sha224_init, _gcry_md_block_write, sha256_final, sha256_read, sizeof (SHA256_CONTEXT) }; md_extra_spec_t _gcry_digest_extraspec_sha224 = @@ -545,7 +512,7 @@ md_extra_spec_t _gcry_digest_extraspec_sha224 = gcry_md_spec_t _gcry_digest_spec_sha256 = { "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32, - sha256_init, sha256_write, sha256_final, sha256_read, + sha256_init, _gcry_md_block_write, sha256_final, sha256_read, sizeof (SHA256_CONTEXT) }; md_extra_spec_t _gcry_digest_extraspec_sha256 = diff --git a/cipher/tiger.c b/cipher/tiger.c index d4ad514..49d3919 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -27,16 +27,15 @@ #include "g10lib.h" #include "cipher.h" +#include "hash-common.h" /* We really need a 64 bit type for this code. */ #ifdef HAVE_U64_TYPEDEF typedef struct { + gcry_md_block_ctx_t bctx; u64 a, b, c; - byte buf[64]; - int count; - u32 nblocks; int variant; /* 0 = old code, 1 = fixed code, 2 - TIGER2. */ } TIGER_CONTEXT; @@ -589,6 +588,9 @@ static u64 sbox4[256] = { }; static void +transform ( void *ctx, const unsigned char *data ); + +static void do_init (void *context, int variant) { TIGER_CONTEXT *hd = context; @@ -596,8 +598,11 @@ do_init (void *context, int variant) hd->a = 0x0123456789abcdefLL; hd->b = 0xfedcba9876543210LL; hd->c = 0xf096a5b4c3b2e187LL; - hd->nblocks = 0; - hd->count = 0; + hd->bctx.nblocks = 0; + hd->bctx.count = 0; + hd->bctx.blocksize = 64; + hd->bctx.stack_burn = 21*8+11*sizeof(void*); + hd->bctx.bwrite = transform; hd->variant = variant; } @@ -687,8 +692,9 @@ key_schedule( u64 *x ) * Transform the message DATA which consists of 512 bytes (8 words) */ static void -transform ( TIGER_CONTEXT *hd, const unsigned char *data ) +transform ( void *ctx, const unsigned char *data ) { + TIGER_CONTEXT *hd = ctx; u64 a,b,c,aa,bb,cc; u64 x[8]; #ifdef WORDS_BIGENDIAN @@ -733,48 +739,6 @@ transform ( TIGER_CONTEXT *hd, const unsigned char *data ) -/* Update the message digest with the contents - * of INBUF with length INLEN. - */ -static void -tiger_write ( void *context, const void *inbuf_arg, size_t inlen) -{ - const unsigned char *inbuf = inbuf_arg; - TIGER_CONTEXT *hd = context; - - if( hd->count == 64 ) /* flush the buffer */ - { - transform( hd, hd->buf ); - _gcry_burn_stack (21*8+11*sizeof(void*)); - hd->count = 0; - hd->nblocks++; - } - if( !inbuf ) - return; - if( hd->count ) - { - for( ; inlen && hd->count < 64; inlen-- ) - hd->buf[hd->count++] = *inbuf++; - tiger_write( hd, NULL, 0 ); - if( !inlen ) - return; - } - - while( inlen >= 64 ) - { - transform( hd, inbuf ); - hd->count = 0; - hd->nblocks++; - inlen -= 64; - inbuf += 64; - } - _gcry_burn_stack (21*8+11*sizeof(void*)); - for( ; inlen && hd->count < 64; inlen-- ) - hd->buf[hd->count++] = *inbuf++; -} - - - /* The routine terminates the computation */ static void @@ -785,15 +749,15 @@ tiger_final( void *context ) byte *p; byte pad = hd->variant == 2? 0x80 : 0x01; - tiger_write(hd, NULL, 0); /* flush */; + _gcry_md_block_write(hd, NULL, 0); /* flush */; - t = hd->nblocks; + t = hd->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 26; /* add the count */ t = lsb; - if( (lsb += hd->count) < t ) + if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -801,33 +765,33 @@ tiger_final( void *context ) msb <<= 3; msb |= t >> 29; - if( hd->count < 56 ) /* enough room */ + if( hd->bctx.count < 56 ) /* enough room */ { - hd->buf[hd->count++] = pad; - while( hd->count < 56 ) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = pad; + while( hd->bctx.count < 56 ) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else /* need one extra block */ { - hd->buf[hd->count++] = pad; /* pad character */ - while( hd->count < 64 ) - hd->buf[hd->count++] = 0; - tiger_write(hd, NULL, 0); /* flush */; - memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = pad; /* pad character */ + while( hd->bctx.count < 64 ) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write(hd, NULL, 0); /* flush */; + memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->buf[56] = lsb ; - hd->buf[57] = lsb >> 8; - hd->buf[58] = lsb >> 16; - hd->buf[59] = lsb >> 24; - hd->buf[60] = msb ; - hd->buf[61] = msb >> 8; - hd->buf[62] = msb >> 16; - hd->buf[63] = msb >> 24; - transform( hd, hd->buf ); + hd->bctx.buf[56] = lsb ; + hd->bctx.buf[57] = lsb >> 8; + hd->bctx.buf[58] = lsb >> 16; + hd->bctx.buf[59] = lsb >> 24; + hd->bctx.buf[60] = msb ; + hd->bctx.buf[61] = msb >> 8; + hd->bctx.buf[62] = msb >> 16; + hd->bctx.buf[63] = msb >> 24; + transform( hd, hd->bctx.buf ); _gcry_burn_stack (21*8+11*sizeof(void*)); - p = hd->buf; + p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN #define X(a) do { *(u64*)p = hd->a ; p += 8; } while(0) #else /* little endian */ @@ -861,7 +825,7 @@ tiger_read( void *context ) { TIGER_CONTEXT *hd = context; - return hd->buf; + return hd->bctx.buf; } @@ -872,7 +836,7 @@ tiger_read( void *context ) gcry_md_spec_t _gcry_digest_spec_tiger = { "TIGER192", NULL, 0, NULL, 24, - tiger_init, tiger_write, tiger_final, tiger_read, + tiger_init, _gcry_md_block_write, tiger_final, tiger_read, sizeof (TIGER_CONTEXT) }; @@ -894,7 +858,7 @@ static gcry_md_oid_spec_t oid_spec_tiger1[] = gcry_md_spec_t _gcry_digest_spec_tiger1 = { "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24, - tiger1_init, tiger_write, tiger_final, tiger_read, + tiger1_init, _gcry_md_block_write, tiger_final, tiger_read, sizeof (TIGER_CONTEXT) }; @@ -904,7 +868,7 @@ gcry_md_spec_t _gcry_digest_spec_tiger1 = gcry_md_spec_t _gcry_digest_spec_tiger2 = { "TIGER2", NULL, 0, NULL, 24, - tiger2_init, tiger_write, tiger_final, tiger_read, + tiger2_init, _gcry_md_block_write, tiger_final, tiger_read, sizeof (TIGER_CONTEXT) }; -- 1.8.4.rc3 From dbaryshkov at gmail.com Mon Sep 2 11:28:50 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 2 Sep 2013 13:28:50 +0400 Subject: [PATCH 3/5] Add basic implementation of GOST R 34.11-94 message digest In-Reply-To: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> References: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1378114132-7587-3-git-send-email-dbaryshkov@gmail.com> * src/gcrypt.h.in (GCRY_MD_GOSTR3411_94): New. * cipher/gostr3411-94.c: New. * configure.ac (available_digests): Add gostr3411-94. * src/cipher.h: Add gostr3411-94 definitions. * cipher/md.c: Register GOST R 34.11-94. * tests/basic.c (check_digests): Add 4 tests for GOST R 34.11-94 hash algo. Two are defined in the standard itself, two other are more or less common tests - an empty string an exclamation mark. * doc/gcrypt.texi: Add an entry describing GOST R 34.11-94 to the MD algorithms table. -- Add simple implementation of GOST R 34.11-94 hash function. Currently there is no way to specify hash parameters (it always uses GOST R 34.11-94 test parameters). Signed-off-by: Dmitry Eremin-Solenikov --- cipher/Makefile.am | 1 + cipher/gostr3411-94.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++ cipher/md.c | 4 + configure.ac | 12 ++- doc/gcrypt.texi | 4 + src/cipher.h | 1 + src/gcrypt.h.in | 3 +- tests/basic.c | 18 ++++ 8 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 cipher/gostr3411-94.c diff --git a/cipher/Makefile.am b/cipher/Makefile.am index f3bd71c..f0aaebe 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -63,6 +63,7 @@ elgamal.c \ ecc.c ecc-curves.c ecc-misc.c ecc-common.h \ idea.c \ gost28147.c gost.h \ +gostr3411-94.c \ md4.c \ md5.c \ rijndael.c rijndael-tables.h rijndael-amd64.S rijndael-armv6.S \ diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c new file mode 100644 index 0000000..fa4bfb2 --- /dev/null +++ b/cipher/gostr3411-94.c @@ -0,0 +1,271 @@ +/* gostr3411-94.c - GOST R 34.11-94 hash function + * Copyright (C) 2012 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + + +#include +#include +#include +#include + +#include "g10lib.h" +#include "bithelp.h" +#include "cipher.h" +#include "hash-common.h" + +#include "gost.h" + +typedef struct { + gcry_md_block_ctx_t bctx; + GOST28147_context hd; + byte h[32]; + byte sigma[32]; + u32 len; +} GOSTR3411_CONTEXT; + +static void +transform (void *c, const unsigned char *data); + +static void +gost3411_init (void *context) +{ + GOSTR3411_CONTEXT *hd = context; + + memset (&hd->hd, 0, sizeof(hd->hd)); + memset (hd->h, 0, 32); + memset (hd->sigma, 0, 32); + + hd->bctx.nblocks = 0; + hd->bctx.count = 0; + hd->bctx.blocksize = 32; + hd->bctx.bwrite = transform; +} + +static void +do_p (unsigned char *p, unsigned char *u, unsigned char *v) +{ + int i, k; + for (k = 0; k < 8; k++) + { + for (i = 0; i < 4; i++) + { + p[i + 4 * k] = u[8 * i + k] ^ v[8 * i + k]; + } + } +} + +static void +do_a (unsigned char *u) +{ + unsigned char temp[8]; + int i; + memcpy (temp, u, 8); + memmove (u, u+8, 24); + for (i = 0; i < 8; i++) + { + u[24 + i] = u[i] ^ temp[i]; + } +} +/* apply do_a twice: 1 2 3 4 -> 3 4 1^2 2^3 */ +static void +do_a2 (unsigned char *u) +{ + unsigned char temp[16]; + int i; + memcpy (temp, u, 16); + memcpy (u, u + 16, 16); + for (i = 0; i < 8; i++) + { + u[16 + i] = temp[i] ^ temp[8 + i]; + u[24 + i] = u[i] ^ temp[8 + i]; + } +} + +static void +do_apply_c2 (unsigned char *u) +{ + u[ 1] ^= 0xff; + u[ 3] ^= 0xff; + u[ 5] ^= 0xff; + u[ 7] ^= 0xff; + + u[ 8] ^= 0xff; + u[10] ^= 0xff; + u[12] ^= 0xff; + u[14] ^= 0xff; + + u[17] ^= 0xff; + u[18] ^= 0xff; + u[20] ^= 0xff; + u[23] ^= 0xff; + + u[24] ^= 0xff; + u[28] ^= 0xff; + u[29] ^= 0xff; + u[31] ^= 0xff; +} + +#define do_phi_step(e, i) \ + e[(0 + 2*i) % 32] ^= e[(2 + 2*i) % 32] ^ e[(4 + 2*i) % 32] ^ e[(6 + 2*i) % 32] ^ e[(24 + 2*i) % 32] ^ e[(30 + 2*i) % 32]; \ + e[(1 + 2*i) % 32] ^= e[(3 + 2*i) % 32] ^ e[(5 + 2*i) % 32] ^ e[(7 + 2*i) % 32] ^ e[(25 + 2*i) % 32] ^ e[(31 + 2*i) % 32]; + +static void +do_phi_submix (unsigned char *e, unsigned char *x, int round) +{ + int i; + round *= 2; + for (i = 0; i < 32; i++) + { + e[(i + round) % 32] ^= x[i]; + } +} + +static void +do_add (unsigned char *s, unsigned char *a) +{ + unsigned temp = 0; + int i; + + for (i = 0; i < 32; i++) + { + temp = s[i] + a[i] + (temp >> 8); + s[i] = temp & 0xff; + } +} + +static void +do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) +{ + unsigned char u[32], v[32], s[32]; + unsigned char k[32]; + int i; + + memcpy (u, h, 32); + memcpy (v, m, 32); + + for (i = 0; i < 4; i++) { + do_p (k, u, v); + + _gcry_gost_enc_one (hd, k, s + i*8, h + i*8); + + do_a (u); + if (i == 1) + do_apply_c2 (u); + do_a2 (v); + } + + for (i = 0; i < 5; i++) + { + do_phi_step (s, 0); + do_phi_step (s, 1); + do_phi_step (s, 2); + do_phi_step (s, 3); + do_phi_step (s, 4); + do_phi_step (s, 5); + do_phi_step (s, 6); + do_phi_step (s, 7); + do_phi_step (s, 8); + do_phi_step (s, 9); + /* That is in total 12 + 1 + 61 = 74 = 16 * 4 + 10 rounds */ + if (i == 4) + break; + do_phi_step (s, 10); + do_phi_step (s, 11); + if (i == 0) + do_phi_submix(s, m, 12); + do_phi_step (s, 12); + if (i == 0) + do_phi_submix(s, h, 13); + do_phi_step (s, 13); + do_phi_step (s, 14); + do_phi_step (s, 15); + } + + memcpy (h, s+20, 12); + memcpy (h+12, s, 20); +} + + +static void +transform (void *ctx, const unsigned char *data) +{ + GOSTR3411_CONTEXT *hd = ctx; + byte m[32]; + + memcpy (m, data, 32); + do_hash_step (&hd->hd, hd->h, m); + do_add (hd->sigma, m); +} + +/* + The routine finally terminates the computation and returns the + digest. The handle is prepared for a new cycle, but adding bytes + to the handle will the destroy the returned buffer. Returns: 32 + bytes with the message the digest. */ +static void +gost3411_final (void *context) +{ + GOSTR3411_CONTEXT *hd = context; + size_t padlen = 0; + byte l[32]; + int i; + u32 nblocks; + + if (hd->bctx.count > 0) + { + padlen = 32 - hd->bctx.count; + memset (hd->bctx.buf + hd->bctx.count, 0, padlen); + hd->bctx.count += padlen; + _gcry_md_block_write (hd, NULL, 0); /* flush */; + } + + if (hd->bctx.count != 0) + return; /* Something went wrong */ + + memset (l, 0, 32); + + nblocks = hd->bctx.nblocks; + if (padlen) + { + nblocks --; + l[0] = 256 - padlen * 8; + } + + for (i = 1; i < 32 && nblocks != 0; i++) + { + l[i] = nblocks % 256; + nblocks /= 256; + } + + do_hash_step (&hd->hd, hd->h, l); + do_hash_step (&hd->hd, hd->h, hd->sigma); +} + +static byte * +gost3411_read (void *context) +{ + GOSTR3411_CONTEXT *hd = context; + + return hd->h; +} +gcry_md_spec_t _gcry_digest_spec_gost3411_94 = + { + "GOST_R_34.11-94", NULL, 0, NULL, 32, + gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read, + sizeof (GOSTR3411_CONTEXT) + }; diff --git a/cipher/md.c b/cipher/md.c index 46567a1..348fa7a 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -56,6 +56,10 @@ static struct digest_table_entry { &_gcry_digest_spec_crc24_rfc2440, &dummy_extra_spec, GCRY_MD_CRC24_RFC2440, 1 }, #endif +#ifdef USE_GOST_R_3411_94 + { &_gcry_digest_spec_gost3411_94, + &dummy_extra_spec, GCRY_MD_GOSTR3411_94 }, +#endif #if USE_MD4 { &_gcry_digest_spec_md4, &dummy_extra_spec, GCRY_MD_MD4 }, diff --git a/configure.ac b/configure.ac index 21ca88d..0abfa79 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ available_pubkey_ciphers="dsa elgamal rsa ecc" enabled_pubkey_ciphers="" # Definitions for message digests. -available_digests="crc md4 md5 rmd160 sha1 sha256" +available_digests="crc gostr3411-94 md4 md5 rmd160 sha1 sha256" available_digests_64="sha512 tiger whirlpool" enabled_digests="" @@ -1510,6 +1510,16 @@ if test "$found" = "1" ; then AC_DEFINE(USE_CRC, 1, [Defined if this module should be included]) fi +LIST_MEMBER(gostr3411-94, $enabled_digests) +if test "$found" = "1" ; then + # GOST R 34.11-94 internally uses GOST 28147-89 + LIST_MEMBER(gost28147, $enabled_ciphers) + if test "$found" = "1" ; then + GCRYPT_DIGESTS="$GCRYPT_DIGESTS gostr3411-94.lo" + AC_DEFINE(USE_GOST_R_3411_94, 1, [Defined if this module should be included]) + fi +fi + LIST_MEMBER(md4, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo" diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index d5b5955..3d16713 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -2942,6 +2942,10 @@ cryptographic sense. This is the Whirlpool algorithm which yields a message digest of 64 bytes. + at item GCRY_MD_GOSTR3411_94 +This is the hash algorithm described in GOST R 34.11-94. It yields +message digest of 32 bytes. + @end table @c end table of hash algorithms diff --git a/src/cipher.h b/src/cipher.h index 9e725bc..1787a5e 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -208,6 +208,7 @@ extern cipher_extra_spec_t _gcry_cipher_extraspec_salsa20; extern gcry_md_spec_t _gcry_digest_spec_crc32; extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510; extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; +extern gcry_md_spec_t _gcry_digest_spec_gost3411_94; extern gcry_md_spec_t _gcry_digest_spec_md4; extern gcry_md_spec_t _gcry_digest_spec_md5; extern gcry_md_spec_t _gcry_digest_spec_rmd160; diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 8be0bf0..88286c6 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1065,7 +1065,8 @@ enum gcry_md_algos GCRY_MD_CRC24_RFC2440 = 304, GCRY_MD_WHIRLPOOL = 305, GCRY_MD_TIGER1 = 306, /* TIGER fixed. */ - GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */ + GCRY_MD_TIGER2 = 307, /* TIGER2 variant. */ + GCRY_MD_GOSTR3411_94 = 308, /* GOST R 34.11-94. */ }; /* Flags used with the open function. */ diff --git a/tests/basic.c b/tests/basic.c index 9c210df..fc2e494 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -2532,6 +2532,24 @@ check_digests (void) "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5" "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD" "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" }, +#ifdef USE_GOST_R_3411_94 + { GCRY_MD_GOSTR3411_94, + "This is message, length=32 bytes", + "\xB1\xC4\x66\xD3\x75\x19\xB8\x2E\x83\x19\x81\x9F\xF3\x25\x95\xE0" + "\x47\xA2\x8C\xB6\xF8\x3E\xFF\x1C\x69\x16\xA8\x15\xA6\x37\xFF\xFA" }, + { GCRY_MD_GOSTR3411_94, + "Suppose the original message has length = 50 bytes", + "\x47\x1A\xBA\x57\xA6\x0A\x77\x0D\x3A\x76\x13\x06\x35\xC1\xFB\xEA" + "\x4E\xF1\x4D\xE5\x1F\x78\xB4\xAE\x57\xDD\x89\x3B\x62\xF5\x52\x08" }, + { GCRY_MD_GOSTR3411_94, + "", + "\xCE\x85\xB9\x9C\xC4\x67\x52\xFF\xFE\xE3\x5C\xAB\x9A\x7B\x02\x78" + "\xAB\xB4\xC2\xD2\x05\x5C\xFF\x68\x5A\xF4\x91\x2C\x49\x49\x0F\x8D" }, + { GCRY_MD_GOSTR3411_94, + "!", + "\x5C\x00\xCC\xC2\x73\x4C\xDD\x33\x32\xD3\xD4\x74\x95\x76\xE3\xC1" + "\xA7\xDB\xAF\x0E\x7E\xA7\x4E\x9F\xA6\x02\x41\x3C\x90\xA1\x29\xFA" }, +#endif { 0 }, }; int i; -- 1.8.4.rc3 From dbaryshkov at gmail.com Mon Sep 2 11:28:52 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 2 Sep 2013 13:28:52 +0400 Subject: [PATCH 5/5] doc: fix building of ps and pdf documentation In-Reply-To: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> References: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1378114132-7587-5-git-send-email-dbaryshkov@gmail.com> * doc/gcrypt.texi, doc/gpl.texi, doc/lgpl.texi: fix texinfo errors. Signed-off-by: Dmitry Eremin-Solenikov --- doc/gcrypt.texi | 2 +- doc/gpl.texi | 5 ----- doc/lgpl.texi | 5 ----- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 4b0b30b..d80964b 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -1956,7 +1956,7 @@ with contexts as most of the other building blocks of Libgcrypt do. @noindent The following information are stored in S-expressions: - at itemize @asis + at itemize @item keys @item plain text data diff --git a/doc/gpl.texi b/doc/gpl.texi index 35b15f2..6eb301e 100644 --- a/doc/gpl.texi +++ b/doc/gpl.texi @@ -287,12 +287,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - at iftex - at heading NO WARRANTY - at end iftex - at ifinfo @center NO WARRANTY - at end ifinfo @item BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY diff --git a/doc/lgpl.texi b/doc/lgpl.texi index a3f83cb..bbd18a0 100644 --- a/doc/lgpl.texi +++ b/doc/lgpl.texi @@ -476,12 +476,7 @@ decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - at iftex - at heading NO WARRANTY - at end iftex - at ifinfo @center NO WARRANTY - at end ifinfo @item BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -- 1.8.4.rc3 From dbaryshkov at gmail.com Mon Sep 2 11:32:57 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 2 Sep 2013 13:32:57 +0400 Subject: [PATCH 4/5] Add GOST R 34.11-2012 implementation (Stribog) In-Reply-To: <1378114132-7587-4-git-send-email-dbaryshkov@gmail.com> References: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> <1378114132-7587-4-git-send-email-dbaryshkov@gmail.com> Message-ID: On Mon, Sep 2, 2013 at 1:28 PM, Dmitry Eremin-Solenikov wrote: > * src/gcrypt.h.in (GCRY_MD_GOSTR3411_12_256, > GCRY_MD_GOSTR3411_12_512): New. > * cipher/stribog.c: New. > * configure.ac (available_digests_64): Add stribog. > * src/cipher.h: Declare Stribog declarations. > * cipher/md.c: Register Stribog digest. > * tests/basic.c (check_digests) Add 4 testcases for Stribog from > standard. > * doc/gcrypt.texi: document new constants. > > Signed-off-by: Dmitry Eremin-Solenikov > --- > cipher/Makefile.am | 1 + > cipher/md.c | 6 + > cipher/stribog.c | 1428 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > configure.ac | 10 +- > doc/gcrypt.texi | 8 + > src/cipher.h | 2 + > src/gcrypt.h.in | 2 + > tests/basic.c | 30 ++ > 8 files changed, 1485 insertions(+), 2 deletions(-) > create mode 100644 cipher/stribog.c Fourth patch is waiting in the moderator queue. It's too big because it a big generated table. From dbaryshkov at gmail.com Mon Sep 2 11:28:51 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 2 Sep 2013 13:28:51 +0400 Subject: [PATCH 4/5] Add GOST R 34.11-2012 implementation (Stribog) In-Reply-To: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> References: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1378114132-7587-4-git-send-email-dbaryshkov@gmail.com> * src/gcrypt.h.in (GCRY_MD_GOSTR3411_12_256, GCRY_MD_GOSTR3411_12_512): New. * cipher/stribog.c: New. * configure.ac (available_digests_64): Add stribog. * src/cipher.h: Declare Stribog declarations. * cipher/md.c: Register Stribog digest. * tests/basic.c (check_digests) Add 4 testcases for Stribog from standard. * doc/gcrypt.texi: document new constants. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/Makefile.am | 1 + cipher/md.c | 6 + cipher/stribog.c | 1428 ++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 10 +- doc/gcrypt.texi | 8 + src/cipher.h | 2 + src/gcrypt.h.in | 2 + tests/basic.c | 30 ++ 8 files changed, 1485 insertions(+), 2 deletions(-) create mode 100644 cipher/stribog.c diff --git a/cipher/Makefile.am b/cipher/Makefile.am index f0aaebe..49d4cee 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -76,6 +76,7 @@ serpent.c serpent-sse2-amd64.S serpent-avx2-amd64.S \ sha1.c \ sha256.c \ sha512.c sha512-armv7-neon.S \ +stribog.c \ tiger.c \ whirlpool.c \ twofish.c twofish-amd64.S \ diff --git a/cipher/md.c b/cipher/md.c index 348fa7a..df8664d 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -60,6 +60,12 @@ static struct digest_table_entry { &_gcry_digest_spec_gost3411_94, &dummy_extra_spec, GCRY_MD_GOSTR3411_94 }, #endif +#ifdef USE_GOST_R_3411_12 + { &_gcry_digest_spec_stribog_256, + &dummy_extra_spec, GCRY_MD_GOSTR3411_12_256 }, + { &_gcry_digest_spec_stribog_512, + &dummy_extra_spec, GCRY_MD_GOSTR3411_12_512 }, +#endif #if USE_MD4 { &_gcry_digest_spec_md4, &dummy_extra_spec, GCRY_MD_MD4 }, diff --git a/cipher/stribog.c b/cipher/stribog.c new file mode 100644 index 0000000..979045e --- /dev/null +++ b/cipher/stribog.c @@ -0,0 +1,1428 @@ +/* stribog.c - GOST R 34.11-2012 (Stribog) hash function + * Copyright (C) 2013 Dmitry Eremin-Solenikov + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +/* Undefine symbol to trade memory for speed */ +#define STRIBOG_TABLES 1 + +#include +#include +#include +#include + +#include "g10lib.h" +#include "bithelp.h" +#include "cipher.h" +#include "hash-common.h" + +typedef struct +{ + union + { + u64 h[8]; + unsigned char result[64]; + }; + u64 N[8]; + u64 Sigma[8]; + byte buf[64]; + int count; +} STRIBOG_CONTEXT; + +static const byte Pi[256] = +{ + 252, 238, 221, 17, 207, 110, 49, 22, 251, 196, 250, 218, 35, 197, 4, 77, 233, 119, 240, + 219, 147, 46, 153, 186, 23, 54, 241, 187, 20, 205, 95, 193, 249, 24, 101, 90, 226, 92, 239, + 33, 129, 28, 60, 66, 139, 1, 142, 79, 5, 132, 2, 174, 227, 106, 143, 160, 6, 11, 237, 152, 127, + 212, 211, 31, 235, 52, 44, 81, 234, 200, 72, 171, 242, 42, 104, 162, 253, 58, 206, 204, 181, + 112, 14, 86, 8, 12, 118, 18, 191, 114, 19, 71, 156, 183, 93, 135, 21, 161, 150, 41, 16, 123, + 154, 199, 243, 145, 120, 111, 157, 158, 178, 177, 50, 117, 25, 61, 255, 53, 138, 126, 109, + 84, 198, 128, 195, 189, 13, 87, 223, 245, 36, 169, 62, 168, 67, 201, 215, 121, 214, 246, 124, + 34, 185, 3, 224, 15, 236, 222, 122, 148, 176, 188, 220, 232, 40, 80, 78, 51, 10, 74, 167, 151, + 96, 115, 30, 0, 98, 68, 26, 184, 56, 130, 100, 159, 38, 65, 173, 69, 70, 146, 39, 94, 85, 47, + 140, 163, 165, 125, 105, 213, 149, 59, 7, 88, 179, 64, 134, 172, 29, 247, 48, 55, 107, 228, + 136, 217, 231, 137, 225, 27, 131, 73, 76, 63, 248, 254, 141, 83, 170, 144, 202, 216, 133, 97, + 32, 113, 103, 164, 45, 43, 9, 91, 203, 155, 37, 208, 190, 229, 108, 82, 89, 166, 116, 210, + 230, 244, 180, 192, 209, 102, 175, 194, 57, 75, 99, 182 +}; + +#ifndef STRIBOG_TABLES +static const u64 A[64] = +{ + U64_C(0x641c314b2b8ee083), U64_C(0xc83862965601dd1b), + U64_C(0x8d70c431ac02a736), U64_C(0x07e095624504536c), + U64_C(0x0edd37c48a08a6d8), U64_C(0x1ca76e95091051ad), + U64_C(0x3853dc371220a247), U64_C(0x70a6a56e2440598e), + U64_C(0xa48b474f9ef5dc18), U64_C(0x550b8e9e21f7a530), + U64_C(0xaa16012142f35760), U64_C(0x492c024284fbaec0), + U64_C(0x9258048415eb419d), U64_C(0x39b008152acb8227), + U64_C(0x727d102a548b194e), U64_C(0xe4fa2054a80b329c), + U64_C(0xf97d86d98a327728), U64_C(0xeffa11af0964ee50), + U64_C(0xc3e9224312c8c1a0), U64_C(0x9bcf4486248d9f5d), + U64_C(0x2b838811480723ba), U64_C(0x561b0d22900e4669), + U64_C(0xac361a443d1c8cd2), U64_C(0x456c34887a3805b9), + U64_C(0x5b068c651810a89e), U64_C(0xb60c05ca30204d21), + U64_C(0x71180a8960409a42), U64_C(0xe230140fc0802984), + U64_C(0xd960281e9d1d5215), U64_C(0xafc0503c273aa42a), + U64_C(0x439da0784e745554), U64_C(0x86275df09ce8aaa8), + U64_C(0x0321658cba93c138), U64_C(0x0642ca05693b9f70), + U64_C(0x0c84890ad27623e0), U64_C(0x18150f14b9ec46dd), + U64_C(0x302a1e286fc58ca7), U64_C(0x60543c50de970553), + U64_C(0xc0a878a0a1330aa6), U64_C(0x9d4df05d5f661451), + U64_C(0xaccc9ca9328a8950), U64_C(0x4585254f64090fa0), + U64_C(0x8a174a9ec8121e5d), U64_C(0x092e94218d243cba), + U64_C(0x125c354207487869), U64_C(0x24b86a840e90f0d2), + U64_C(0x486dd4151c3dfdb9), U64_C(0x90dab52a387ae76f), + U64_C(0x46b60f011a83988e), U64_C(0x8c711e02341b2d01), + U64_C(0x05e23c0468365a02), U64_C(0x0ad97808d06cb404), + U64_C(0x14aff010bdd87508), U64_C(0x2843fd2067adea10), + U64_C(0x5086e740ce47c920), U64_C(0xa011d380818e8f40), + U64_C(0x83478b07b2468764), U64_C(0x1b8e0b0e798c13c8), + U64_C(0x3601161cf205268d), U64_C(0x6c022c38f90a4c07), + U64_C(0xd8045870ef14980e), U64_C(0xad08b0e0c3282d1c), + U64_C(0x47107ddd9b505a38), U64_C(0x8e20faa72ba0b470), +}; +static u64 strido (u64 l) +{ + u64 t = 0; +#if 0 + int j; + for (j = 0; j < 64; j++, l >>= 1) + { + if (l & 1) + t ^= A[j]; + } +#else +#define X(k) if (l & (1LL << k)) t ^= A[k]; + X(000); X(001); X(002); X(003); X(004); X(005); X(006); X(007); + X(010); X(011); X(012); X(013); X(014); X(015); X(016); X(017); + X(020); X(021); X(022); X(023); X(024); X(025); X(026); X(027); + X(030); X(031); X(032); X(033); X(034); X(035); X(036); X(037); + X(040); X(041); X(042); X(043); X(044); X(045); X(046); X(047); + X(050); X(051); X(052); X(053); X(054); X(055); X(056); X(057); + X(060); X(061); X(062); X(063); X(064); X(065); X(066); X(067); + X(070); X(071); X(072); X(073); X(074); X(075); X(076); X(077); +#undef X +#endif + return t; +} +#else +/* Pre-computed results of multiplication of bytes on A */ +static const u64 stribog_table[8][256] = +{ + /* 0 */ + { U64_C(0x0000000000000000), U64_C(0x641c314b2b8ee083), + U64_C(0xc83862965601dd1b), U64_C(0xac2453dd7d8f3d98), + U64_C(0x8d70c431ac02a736), U64_C(0xe96cf57a878c47b5), + U64_C(0x4548a6a7fa037a2d), U64_C(0x215497ecd18d9aae), + U64_C(0x07e095624504536c), U64_C(0x63fca4296e8ab3ef), + U64_C(0xcfd8f7f413058e77), U64_C(0xabc4c6bf388b6ef4), + U64_C(0x8a905153e906f45a), U64_C(0xee8c6018c28814d9), + U64_C(0x42a833c5bf072941), U64_C(0x26b4028e9489c9c2), + U64_C(0x0edd37c48a08a6d8), U64_C(0x6ac1068fa186465b), + U64_C(0xc6e55552dc097bc3), U64_C(0xa2f96419f7879b40), + U64_C(0x83adf3f5260a01ee), U64_C(0xe7b1c2be0d84e16d), + U64_C(0x4b959163700bdcf5), U64_C(0x2f89a0285b853c76), + U64_C(0x093da2a6cf0cf5b4), U64_C(0x6d2193ede4821537), + U64_C(0xc105c030990d28af), U64_C(0xa519f17bb283c82c), + U64_C(0x844d6697630e5282), U64_C(0xe05157dc4880b201), + U64_C(0x4c750401350f8f99), U64_C(0x2869354a1e816f1a), + U64_C(0x1ca76e95091051ad), U64_C(0x78bb5fde229eb12e), + U64_C(0xd49f0c035f118cb6), U64_C(0xb0833d48749f6c35), + U64_C(0x91d7aaa4a512f69b), U64_C(0xf5cb9bef8e9c1618), + U64_C(0x59efc832f3132b80), U64_C(0x3df3f979d89dcb03), + U64_C(0x1b47fbf74c1402c1), U64_C(0x7f5bcabc679ae242), + U64_C(0xd37f99611a15dfda), U64_C(0xb763a82a319b3f59), + U64_C(0x96373fc6e016a5f7), U64_C(0xf22b0e8dcb984574), + U64_C(0x5e0f5d50b61778ec), U64_C(0x3a136c1b9d99986f), + U64_C(0x127a59518318f775), U64_C(0x7666681aa89617f6), + U64_C(0xda423bc7d5192a6e), U64_C(0xbe5e0a8cfe97caed), + U64_C(0x9f0a9d602f1a5043), U64_C(0xfb16ac2b0494b0c0), + U64_C(0x5732fff6791b8d58), U64_C(0x332ecebd52956ddb), + U64_C(0x159acc33c61ca419), U64_C(0x7186fd78ed92449a), + U64_C(0xdda2aea5901d7902), U64_C(0xb9be9feebb939981), + U64_C(0x98ea08026a1e032f), U64_C(0xfcf639494190e3ac), + U64_C(0x50d26a943c1fde34), U64_C(0x34ce5bdf17913eb7), + U64_C(0x3853dc371220a247), U64_C(0x5c4fed7c39ae42c4), + U64_C(0xf06bbea144217f5c), U64_C(0x94778fea6faf9fdf), + U64_C(0xb5231806be220571), U64_C(0xd13f294d95ace5f2), + U64_C(0x7d1b7a90e823d86a), U64_C(0x19074bdbc3ad38e9), + U64_C(0x3fb349555724f12b), U64_C(0x5baf781e7caa11a8), + U64_C(0xf78b2bc301252c30), U64_C(0x93971a882aabccb3), + U64_C(0xb2c38d64fb26561d), U64_C(0xd6dfbc2fd0a8b69e), + U64_C(0x7afbeff2ad278b06), U64_C(0x1ee7deb986a96b85), + U64_C(0x368eebf39828049f), U64_C(0x5292dab8b3a6e41c), + U64_C(0xfeb68965ce29d984), U64_C(0x9aaab82ee5a73907), + U64_C(0xbbfe2fc2342aa3a9), U64_C(0xdfe21e891fa4432a), + U64_C(0x73c64d54622b7eb2), U64_C(0x17da7c1f49a59e31), + U64_C(0x316e7e91dd2c57f3), U64_C(0x55724fdaf6a2b770), + U64_C(0xf9561c078b2d8ae8), U64_C(0x9d4a2d4ca0a36a6b), + U64_C(0xbc1ebaa0712ef0c5), U64_C(0xd8028beb5aa01046), + U64_C(0x7426d836272f2dde), U64_C(0x103ae97d0ca1cd5d), + U64_C(0x24f4b2a21b30f3ea), U64_C(0x40e883e930be1369), + U64_C(0xecccd0344d312ef1), U64_C(0x88d0e17f66bfce72), + U64_C(0xa9847693b73254dc), U64_C(0xcd9847d89cbcb45f), + U64_C(0x61bc1405e13389c7), U64_C(0x05a0254ecabd6944), + U64_C(0x231427c05e34a086), U64_C(0x4708168b75ba4005), + U64_C(0xeb2c455608357d9d), U64_C(0x8f30741d23bb9d1e), + U64_C(0xae64e3f1f23607b0), U64_C(0xca78d2bad9b8e733), + U64_C(0x665c8167a437daab), U64_C(0x0240b02c8fb93a28), + U64_C(0x2a29856691385532), U64_C(0x4e35b42dbab6b5b1), + U64_C(0xe211e7f0c7398829), U64_C(0x860dd6bbecb768aa), + U64_C(0xa75941573d3af204), U64_C(0xc345701c16b41287), + U64_C(0x6f6123c16b3b2f1f), U64_C(0x0b7d128a40b5cf9c), + U64_C(0x2dc91004d43c065e), U64_C(0x49d5214fffb2e6dd), + U64_C(0xe5f17292823ddb45), U64_C(0x81ed43d9a9b33bc6), + U64_C(0xa0b9d435783ea168), U64_C(0xc4a5e57e53b041eb), + U64_C(0x6881b6a32e3f7c73), U64_C(0x0c9d87e805b19cf0), + U64_C(0x70a6a56e2440598e), U64_C(0x14ba94250fceb90d), + U64_C(0xb89ec7f872418495), U64_C(0xdc82f6b359cf6416), + U64_C(0xfdd6615f8842feb8), U64_C(0x99ca5014a3cc1e3b), + U64_C(0x35ee03c9de4323a3), U64_C(0x51f23282f5cdc320), + U64_C(0x7746300c61440ae2), U64_C(0x135a01474acaea61), + U64_C(0xbf7e529a3745d7f9), U64_C(0xdb6263d11ccb377a), + U64_C(0xfa36f43dcd46add4), U64_C(0x9e2ac576e6c84d57), + U64_C(0x320e96ab9b4770cf), U64_C(0x5612a7e0b0c9904c), + U64_C(0x7e7b92aaae48ff56), U64_C(0x1a67a3e185c61fd5), + U64_C(0xb643f03cf849224d), U64_C(0xd25fc177d3c7c2ce), + U64_C(0xf30b569b024a5860), U64_C(0x971767d029c4b8e3), + U64_C(0x3b33340d544b857b), U64_C(0x5f2f05467fc565f8), + U64_C(0x799b07c8eb4cac3a), U64_C(0x1d873683c0c24cb9), + U64_C(0xb1a3655ebd4d7121), U64_C(0xd5bf541596c391a2), + U64_C(0xf4ebc3f9474e0b0c), U64_C(0x90f7f2b26cc0eb8f), + U64_C(0x3cd3a16f114fd617), U64_C(0x58cf90243ac13694), + U64_C(0x6c01cbfb2d500823), U64_C(0x081dfab006dee8a0), + U64_C(0xa439a96d7b51d538), U64_C(0xc025982650df35bb), + U64_C(0xe1710fca8152af15), U64_C(0x856d3e81aadc4f96), + U64_C(0x29496d5cd753720e), U64_C(0x4d555c17fcdd928d), + U64_C(0x6be15e9968545b4f), U64_C(0x0ffd6fd243dabbcc), + U64_C(0xa3d93c0f3e558654), U64_C(0xc7c50d4415db66d7), + U64_C(0xe6919aa8c456fc79), U64_C(0x828dabe3efd81cfa), + U64_C(0x2ea9f83e92572162), U64_C(0x4ab5c975b9d9c1e1), + U64_C(0x62dcfc3fa758aefb), U64_C(0x06c0cd748cd64e78), + U64_C(0xaae49ea9f15973e0), U64_C(0xcef8afe2dad79363), + U64_C(0xefac380e0b5a09cd), U64_C(0x8bb0094520d4e94e), + U64_C(0x27945a985d5bd4d6), U64_C(0x43886bd376d53455), + U64_C(0x653c695de25cfd97), U64_C(0x01205816c9d21d14), + U64_C(0xad040bcbb45d208c), U64_C(0xc9183a809fd3c00f), + U64_C(0xe84cad6c4e5e5aa1), U64_C(0x8c509c2765d0ba22), + U64_C(0x2074cffa185f87ba), U64_C(0x4468feb133d16739), + U64_C(0x48f579593660fbc9), U64_C(0x2ce948121dee1b4a), + U64_C(0x80cd1bcf606126d2), U64_C(0xe4d12a844befc651), + U64_C(0xc585bd689a625cff), U64_C(0xa1998c23b1ecbc7c), + U64_C(0x0dbddffecc6381e4), U64_C(0x69a1eeb5e7ed6167), + U64_C(0x4f15ec3b7364a8a5), U64_C(0x2b09dd7058ea4826), + U64_C(0x872d8ead256575be), U64_C(0xe331bfe60eeb953d), + U64_C(0xc265280adf660f93), U64_C(0xa6791941f4e8ef10), + U64_C(0x0a5d4a9c8967d288), U64_C(0x6e417bd7a2e9320b), + U64_C(0x46284e9dbc685d11), U64_C(0x22347fd697e6bd92), + U64_C(0x8e102c0bea69800a), U64_C(0xea0c1d40c1e76089), + U64_C(0xcb588aac106afa27), U64_C(0xaf44bbe73be41aa4), + U64_C(0x0360e83a466b273c), U64_C(0x677cd9716de5c7bf), + U64_C(0x41c8dbfff96c0e7d), U64_C(0x25d4eab4d2e2eefe), + U64_C(0x89f0b969af6dd366), U64_C(0xedec882284e333e5), + U64_C(0xccb81fce556ea94b), U64_C(0xa8a42e857ee049c8), + U64_C(0x04807d58036f7450), U64_C(0x609c4c1328e194d3), + U64_C(0x545217cc3f70aa64), U64_C(0x304e268714fe4ae7), + U64_C(0x9c6a755a6971777f), U64_C(0xf876441142ff97fc), + U64_C(0xd922d3fd93720d52), U64_C(0xbd3ee2b6b8fcedd1), + U64_C(0x111ab16bc573d049), U64_C(0x75068020eefd30ca), + U64_C(0x53b282ae7a74f908), U64_C(0x37aeb3e551fa198b), + U64_C(0x9b8ae0382c752413), U64_C(0xff96d17307fbc490), + U64_C(0xdec2469fd6765e3e), U64_C(0xbade77d4fdf8bebd), + U64_C(0x16fa240980778325), U64_C(0x72e61542abf963a6), + U64_C(0x5a8f2008b5780cbc), U64_C(0x3e9311439ef6ec3f), + U64_C(0x92b7429ee379d1a7), U64_C(0xf6ab73d5c8f73124), + U64_C(0xd7ffe439197aab8a), U64_C(0xb3e3d57232f44b09), + U64_C(0x1fc786af4f7b7691), U64_C(0x7bdbb7e464f59612), + U64_C(0x5d6fb56af07c5fd0), U64_C(0x39738421dbf2bf53), + U64_C(0x9557d7fca67d82cb), U64_C(0xf14be6b78df36248), + U64_C(0xd01f715b5c7ef8e6), U64_C(0xb403401077f01865), + U64_C(0x182713cd0a7f25fd), U64_C(0x7c3b228621f1c57e) }, + /* 1 */ + { U64_C(0x0000000000000000), U64_C(0xa48b474f9ef5dc18), + U64_C(0x550b8e9e21f7a530), U64_C(0xf180c9d1bf027928), + U64_C(0xaa16012142f35760), U64_C(0x0e9d466edc068b78), + U64_C(0xff1d8fbf6304f250), U64_C(0x5b96c8f0fdf12e48), + U64_C(0x492c024284fbaec0), U64_C(0xeda7450d1a0e72d8), + U64_C(0x1c278cdca50c0bf0), U64_C(0xb8accb933bf9d7e8), + U64_C(0xe33a0363c608f9a0), U64_C(0x47b1442c58fd25b8), + U64_C(0xb6318dfde7ff5c90), U64_C(0x12bacab2790a8088), + U64_C(0x9258048415eb419d), U64_C(0x36d343cb8b1e9d85), + U64_C(0xc7538a1a341ce4ad), U64_C(0x63d8cd55aae938b5), + U64_C(0x384e05a5571816fd), U64_C(0x9cc542eac9edcae5), + U64_C(0x6d458b3b76efb3cd), U64_C(0xc9cecc74e81a6fd5), + U64_C(0xdb7406c69110ef5d), U64_C(0x7fff41890fe53345), + U64_C(0x8e7f8858b0e74a6d), U64_C(0x2af4cf172e129675), + U64_C(0x716207e7d3e3b83d), U64_C(0xd5e940a84d166425), + U64_C(0x24698979f2141d0d), U64_C(0x80e2ce366ce1c115), + U64_C(0x39b008152acb8227), U64_C(0x9d3b4f5ab43e5e3f), + U64_C(0x6cbb868b0b3c2717), U64_C(0xc830c1c495c9fb0f), + U64_C(0x93a609346838d547), U64_C(0x372d4e7bf6cd095f), + U64_C(0xc6ad87aa49cf7077), U64_C(0x6226c0e5d73aac6f), + U64_C(0x709c0a57ae302ce7), U64_C(0xd4174d1830c5f0ff), + U64_C(0x259784c98fc789d7), U64_C(0x811cc386113255cf), + U64_C(0xda8a0b76ecc37b87), U64_C(0x7e014c397236a79f), + U64_C(0x8f8185e8cd34deb7), U64_C(0x2b0ac2a753c102af), + U64_C(0xabe80c913f20c3ba), U64_C(0x0f634bdea1d51fa2), + U64_C(0xfee3820f1ed7668a), U64_C(0x5a68c5408022ba92), + U64_C(0x01fe0db07dd394da), U64_C(0xa5754affe32648c2), + U64_C(0x54f5832e5c2431ea), U64_C(0xf07ec461c2d1edf2), + U64_C(0xe2c40ed3bbdb6d7a), U64_C(0x464f499c252eb162), + U64_C(0xb7cf804d9a2cc84a), U64_C(0x1344c70204d91452), + U64_C(0x48d20ff2f9283a1a), U64_C(0xec5948bd67dde602), + U64_C(0x1dd9816cd8df9f2a), U64_C(0xb952c623462a4332), + U64_C(0x727d102a548b194e), U64_C(0xd6f65765ca7ec556), + U64_C(0x27769eb4757cbc7e), U64_C(0x83fdd9fbeb896066), + U64_C(0xd86b110b16784e2e), U64_C(0x7ce05644888d9236), + U64_C(0x8d609f95378feb1e), U64_C(0x29ebd8daa97a3706), + U64_C(0x3b511268d070b78e), U64_C(0x9fda55274e856b96), + U64_C(0x6e5a9cf6f18712be), U64_C(0xcad1dbb96f72cea6), + U64_C(0x914713499283e0ee), U64_C(0x35cc54060c763cf6), + U64_C(0xc44c9dd7b37445de), U64_C(0x60c7da982d8199c6), + U64_C(0xe02514ae416058d3), U64_C(0x44ae53e1df9584cb), + U64_C(0xb52e9a306097fde3), U64_C(0x11a5dd7ffe6221fb), + U64_C(0x4a33158f03930fb3), U64_C(0xeeb852c09d66d3ab), + U64_C(0x1f389b112264aa83), U64_C(0xbbb3dc5ebc91769b), + U64_C(0xa90916ecc59bf613), U64_C(0x0d8251a35b6e2a0b), + U64_C(0xfc029872e46c5323), U64_C(0x5889df3d7a998f3b), + U64_C(0x031f17cd8768a173), U64_C(0xa7945082199d7d6b), + U64_C(0x56149953a69f0443), U64_C(0xf29fde1c386ad85b), + U64_C(0x4bcd183f7e409b69), U64_C(0xef465f70e0b54771), + U64_C(0x1ec696a15fb73e59), U64_C(0xba4dd1eec142e241), + U64_C(0xe1db191e3cb3cc09), U64_C(0x45505e51a2461011), + U64_C(0xb4d097801d446939), U64_C(0x105bd0cf83b1b521), + U64_C(0x02e11a7dfabb35a9), U64_C(0xa66a5d32644ee9b1), + U64_C(0x57ea94e3db4c9099), U64_C(0xf361d3ac45b94c81), + U64_C(0xa8f71b5cb84862c9), U64_C(0x0c7c5c1326bdbed1), + U64_C(0xfdfc95c299bfc7f9), U64_C(0x5977d28d074a1be1), + U64_C(0xd9951cbb6babdaf4), U64_C(0x7d1e5bf4f55e06ec), + U64_C(0x8c9e92254a5c7fc4), U64_C(0x2815d56ad4a9a3dc), + U64_C(0x73831d9a29588d94), U64_C(0xd7085ad5b7ad518c), + U64_C(0x2688930408af28a4), U64_C(0x8203d44b965af4bc), + U64_C(0x90b91ef9ef507434), U64_C(0x343259b671a5a82c), + U64_C(0xc5b29067cea7d104), U64_C(0x6139d72850520d1c), + U64_C(0x3aaf1fd8ada32354), U64_C(0x9e2458973356ff4c), + U64_C(0x6fa491468c548664), U64_C(0xcb2fd60912a15a7c), + U64_C(0xe4fa2054a80b329c), U64_C(0x4071671b36feee84), + U64_C(0xb1f1aeca89fc97ac), U64_C(0x157ae98517094bb4), + U64_C(0x4eec2175eaf865fc), U64_C(0xea67663a740db9e4), + U64_C(0x1be7afebcb0fc0cc), U64_C(0xbf6ce8a455fa1cd4), + U64_C(0xadd622162cf09c5c), U64_C(0x095d6559b2054044), + U64_C(0xf8ddac880d07396c), U64_C(0x5c56ebc793f2e574), + U64_C(0x07c023376e03cb3c), U64_C(0xa34b6478f0f61724), + U64_C(0x52cbada94ff46e0c), U64_C(0xf640eae6d101b214), + U64_C(0x76a224d0bde07301), U64_C(0xd229639f2315af19), + U64_C(0x23a9aa4e9c17d631), U64_C(0x8722ed0102e20a29), + U64_C(0xdcb425f1ff132461), U64_C(0x783f62be61e6f879), + U64_C(0x89bfab6fdee48151), U64_C(0x2d34ec2040115d49), + U64_C(0x3f8e2692391bddc1), U64_C(0x9b0561dda7ee01d9), + U64_C(0x6a85a80c18ec78f1), U64_C(0xce0eef438619a4e9), + U64_C(0x959827b37be88aa1), U64_C(0x311360fce51d56b9), + U64_C(0xc093a92d5a1f2f91), U64_C(0x6418ee62c4eaf389), + U64_C(0xdd4a284182c0b0bb), U64_C(0x79c16f0e1c356ca3), + U64_C(0x8841a6dfa337158b), U64_C(0x2ccae1903dc2c993), + U64_C(0x775c2960c033e7db), U64_C(0xd3d76e2f5ec63bc3), + U64_C(0x2257a7fee1c442eb), U64_C(0x86dce0b17f319ef3), + U64_C(0x94662a03063b1e7b), U64_C(0x30ed6d4c98cec263), + U64_C(0xc16da49d27ccbb4b), U64_C(0x65e6e3d2b9396753), + U64_C(0x3e702b2244c8491b), U64_C(0x9afb6c6dda3d9503), + U64_C(0x6b7ba5bc653fec2b), U64_C(0xcff0e2f3fbca3033), + U64_C(0x4f122cc5972bf126), U64_C(0xeb996b8a09de2d3e), + U64_C(0x1a19a25bb6dc5416), U64_C(0xbe92e5142829880e), + U64_C(0xe5042de4d5d8a646), U64_C(0x418f6aab4b2d7a5e), + U64_C(0xb00fa37af42f0376), U64_C(0x1484e4356adadf6e), + U64_C(0x063e2e8713d05fe6), U64_C(0xa2b569c88d2583fe), + U64_C(0x5335a0193227fad6), U64_C(0xf7bee756acd226ce), + U64_C(0xac282fa651230886), U64_C(0x08a368e9cfd6d49e), + U64_C(0xf923a13870d4adb6), U64_C(0x5da8e677ee2171ae), + U64_C(0x9687307efc802bd2), U64_C(0x320c77316275f7ca), + U64_C(0xc38cbee0dd778ee2), U64_C(0x6707f9af438252fa), + U64_C(0x3c91315fbe737cb2), U64_C(0x981a76102086a0aa), + U64_C(0x699abfc19f84d982), U64_C(0xcd11f88e0171059a), + U64_C(0xdfab323c787b8512), U64_C(0x7b207573e68e590a), + U64_C(0x8aa0bca2598c2022), U64_C(0x2e2bfbedc779fc3a), + U64_C(0x75bd331d3a88d272), U64_C(0xd1367452a47d0e6a), + U64_C(0x20b6bd831b7f7742), U64_C(0x843dfacc858aab5a), + U64_C(0x04df34fae96b6a4f), U64_C(0xa05473b5779eb657), + U64_C(0x51d4ba64c89ccf7f), U64_C(0xf55ffd2b56691367), + U64_C(0xaec935dbab983d2f), U64_C(0x0a427294356de137), + U64_C(0xfbc2bb458a6f981f), U64_C(0x5f49fc0a149a4407), + U64_C(0x4df336b86d90c48f), U64_C(0xe97871f7f3651897), + U64_C(0x18f8b8264c6761bf), U64_C(0xbc73ff69d292bda7), + U64_C(0xe7e537992f6393ef), U64_C(0x436e70d6b1964ff7), + U64_C(0xb2eeb9070e9436df), U64_C(0x1665fe489061eac7), + U64_C(0xaf37386bd64ba9f5), U64_C(0x0bbc7f2448be75ed), + U64_C(0xfa3cb6f5f7bc0cc5), U64_C(0x5eb7f1ba6949d0dd), + U64_C(0x0521394a94b8fe95), U64_C(0xa1aa7e050a4d228d), + U64_C(0x502ab7d4b54f5ba5), U64_C(0xf4a1f09b2bba87bd), + U64_C(0xe61b3a2952b00735), U64_C(0x42907d66cc45db2d), + U64_C(0xb310b4b77347a205), U64_C(0x179bf3f8edb27e1d), + U64_C(0x4c0d3b0810435055), U64_C(0xe8867c478eb68c4d), + U64_C(0x1906b59631b4f565), U64_C(0xbd8df2d9af41297d), + U64_C(0x3d6f3cefc3a0e868), U64_C(0x99e47ba05d553470), + U64_C(0x6864b271e2574d58), U64_C(0xcceff53e7ca29140), + U64_C(0x97793dce8153bf08), U64_C(0x33f27a811fa66310), + U64_C(0xc272b350a0a41a38), U64_C(0x66f9f41f3e51c620), + U64_C(0x74433ead475b46a8), U64_C(0xd0c879e2d9ae9ab0), + U64_C(0x2148b03366ace398), U64_C(0x85c3f77cf8593f80), + U64_C(0xde553f8c05a811c8), U64_C(0x7ade78c39b5dcdd0), + U64_C(0x8b5eb112245fb4f8), U64_C(0x2fd5f65dbaaa68e0) }, + /* 2 */ + { U64_C(0x0000000000000000), U64_C(0xf97d86d98a327728), + U64_C(0xeffa11af0964ee50), U64_C(0x1687977683569978), + U64_C(0xc3e9224312c8c1a0), U64_C(0x3a94a49a98fab688), + U64_C(0x2c1333ec1bac2ff0), U64_C(0xd56eb535919e58d8), + U64_C(0x9bcf4486248d9f5d), U64_C(0x62b2c25faebfe875), + U64_C(0x743555292de9710d), U64_C(0x8d48d3f0a7db0625), + U64_C(0x582666c536455efd), U64_C(0xa15be01cbc7729d5), + U64_C(0xb7dc776a3f21b0ad), U64_C(0x4ea1f1b3b513c785), + U64_C(0x2b838811480723ba), U64_C(0xd2fe0ec8c2355492), + U64_C(0xc47999be4163cdea), U64_C(0x3d041f67cb51bac2), + U64_C(0xe86aaa525acfe21a), U64_C(0x11172c8bd0fd9532), + U64_C(0x0790bbfd53ab0c4a), U64_C(0xfeed3d24d9997b62), + U64_C(0xb04ccc976c8abce7), U64_C(0x49314a4ee6b8cbcf), + U64_C(0x5fb6dd3865ee52b7), U64_C(0xa6cb5be1efdc259f), + U64_C(0x73a5eed47e427d47), U64_C(0x8ad8680df4700a6f), + U64_C(0x9c5fff7b77269317), U64_C(0x652279a2fd14e43f), + U64_C(0x561b0d22900e4669), U64_C(0xaf668bfb1a3c3141), + U64_C(0xb9e11c8d996aa839), U64_C(0x409c9a541358df11), + U64_C(0x95f22f6182c687c9), U64_C(0x6c8fa9b808f4f0e1), + U64_C(0x7a083ece8ba26999), U64_C(0x8375b81701901eb1), + U64_C(0xcdd449a4b483d934), U64_C(0x34a9cf7d3eb1ae1c), + U64_C(0x222e580bbde73764), U64_C(0xdb53ded237d5404c), + U64_C(0x0e3d6be7a64b1894), U64_C(0xf740ed3e2c796fbc), + U64_C(0xe1c77a48af2ff6c4), U64_C(0x18bafc91251d81ec), + U64_C(0x7d988533d80965d3), U64_C(0x84e503ea523b12fb), + U64_C(0x9262949cd16d8b83), U64_C(0x6b1f12455b5ffcab), + U64_C(0xbe71a770cac1a473), U64_C(0x470c21a940f3d35b), + U64_C(0x518bb6dfc3a54a23), U64_C(0xa8f6300649973d0b), + U64_C(0xe657c1b5fc84fa8e), U64_C(0x1f2a476c76b68da6), + U64_C(0x09add01af5e014de), U64_C(0xf0d056c37fd263f6), + U64_C(0x25bee3f6ee4c3b2e), U64_C(0xdcc3652f647e4c06), + U64_C(0xca44f259e728d57e), U64_C(0x333974806d1aa256), + U64_C(0xac361a443d1c8cd2), U64_C(0x554b9c9db72efbfa), + U64_C(0x43cc0beb34786282), U64_C(0xbab18d32be4a15aa), + U64_C(0x6fdf38072fd44d72), U64_C(0x96a2bedea5e63a5a), + U64_C(0x802529a826b0a322), U64_C(0x7958af71ac82d40a), + U64_C(0x37f95ec21991138f), U64_C(0xce84d81b93a364a7), + U64_C(0xd8034f6d10f5fddf), U64_C(0x217ec9b49ac78af7), + U64_C(0xf4107c810b59d22f), U64_C(0x0d6dfa58816ba507), + U64_C(0x1bea6d2e023d3c7f), U64_C(0xe297ebf7880f4b57), + U64_C(0x87b59255751baf68), U64_C(0x7ec8148cff29d840), + U64_C(0x684f83fa7c7f4138), U64_C(0x91320523f64d3610), + U64_C(0x445cb01667d36ec8), U64_C(0xbd2136cfede119e0), + U64_C(0xaba6a1b96eb78098), U64_C(0x52db2760e485f7b0), + U64_C(0x1c7ad6d351963035), U64_C(0xe507500adba4471d), + U64_C(0xf380c77c58f2de65), U64_C(0x0afd41a5d2c0a94d), + U64_C(0xdf93f490435ef195), U64_C(0x26ee7249c96c86bd), + U64_C(0x3069e53f4a3a1fc5), U64_C(0xc91463e6c00868ed), + U64_C(0xfa2d1766ad12cabb), U64_C(0x035091bf2720bd93), + U64_C(0x15d706c9a47624eb), U64_C(0xecaa80102e4453c3), + U64_C(0x39c43525bfda0b1b), U64_C(0xc0b9b3fc35e87c33), + U64_C(0xd63e248ab6bee54b), U64_C(0x2f43a2533c8c9263), + U64_C(0x61e253e0899f55e6), U64_C(0x989fd53903ad22ce), + U64_C(0x8e18424f80fbbbb6), U64_C(0x7765c4960ac9cc9e), + U64_C(0xa20b71a39b579446), U64_C(0x5b76f77a1165e36e), + U64_C(0x4df1600c92337a16), U64_C(0xb48ce6d518010d3e), + U64_C(0xd1ae9f77e515e901), U64_C(0x28d319ae6f279e29), + U64_C(0x3e548ed8ec710751), U64_C(0xc729080166437079), + U64_C(0x1247bd34f7dd28a1), U64_C(0xeb3a3bed7def5f89), + U64_C(0xfdbdac9bfeb9c6f1), U64_C(0x04c02a42748bb1d9), + U64_C(0x4a61dbf1c198765c), U64_C(0xb31c5d284baa0174), + U64_C(0xa59bca5ec8fc980c), U64_C(0x5ce64c8742ceef24), + U64_C(0x8988f9b2d350b7fc), U64_C(0x70f57f6b5962c0d4), + U64_C(0x6672e81dda3459ac), U64_C(0x9f0f6ec450062e84), + U64_C(0x456c34887a3805b9), U64_C(0xbc11b251f00a7291), + U64_C(0xaa962527735cebe9), U64_C(0x53eba3fef96e9cc1), + U64_C(0x868516cb68f0c419), U64_C(0x7ff89012e2c2b331), + U64_C(0x697f076461942a49), U64_C(0x900281bdeba65d61), + U64_C(0xdea3700e5eb59ae4), U64_C(0x27def6d7d487edcc), + U64_C(0x315961a157d174b4), U64_C(0xc824e778dde3039c), + U64_C(0x1d4a524d4c7d5b44), U64_C(0xe437d494c64f2c6c), + U64_C(0xf2b043e24519b514), U64_C(0x0bcdc53bcf2bc23c), + U64_C(0x6eefbc99323f2603), U64_C(0x97923a40b80d512b), + U64_C(0x8115ad363b5bc853), U64_C(0x78682befb169bf7b), + U64_C(0xad069eda20f7e7a3), U64_C(0x547b1803aac5908b), + U64_C(0x42fc8f75299309f3), U64_C(0xbb8109aca3a17edb), + U64_C(0xf520f81f16b2b95e), U64_C(0x0c5d7ec69c80ce76), + U64_C(0x1adae9b01fd6570e), U64_C(0xe3a76f6995e42026), + U64_C(0x36c9da5c047a78fe), U64_C(0xcfb45c858e480fd6), + U64_C(0xd933cbf30d1e96ae), U64_C(0x204e4d2a872ce186), + U64_C(0x137739aaea3643d0), U64_C(0xea0abf73600434f8), + U64_C(0xfc8d2805e352ad80), U64_C(0x05f0aedc6960daa8), + U64_C(0xd09e1be9f8fe8270), U64_C(0x29e39d3072ccf558), + U64_C(0x3f640a46f19a6c20), U64_C(0xc6198c9f7ba81b08), + U64_C(0x88b87d2ccebbdc8d), U64_C(0x71c5fbf54489aba5), + U64_C(0x67426c83c7df32dd), U64_C(0x9e3fea5a4ded45f5), + U64_C(0x4b515f6fdc731d2d), U64_C(0xb22cd9b656416a05), + U64_C(0xa4ab4ec0d517f37d), U64_C(0x5dd6c8195f258455), + U64_C(0x38f4b1bba231606a), U64_C(0xc189376228031742), + U64_C(0xd70ea014ab558e3a), U64_C(0x2e7326cd2167f912), + U64_C(0xfb1d93f8b0f9a1ca), U64_C(0x026015213acbd6e2), + U64_C(0x14e78257b99d4f9a), U64_C(0xed9a048e33af38b2), + U64_C(0xa33bf53d86bcff37), U64_C(0x5a4673e40c8e881f), + U64_C(0x4cc1e4928fd81167), U64_C(0xb5bc624b05ea664f), + U64_C(0x60d2d77e94743e97), U64_C(0x99af51a71e4649bf), + U64_C(0x8f28c6d19d10d0c7), U64_C(0x765540081722a7ef), + U64_C(0xe95a2ecc4724896b), U64_C(0x1027a815cd16fe43), + U64_C(0x06a03f634e40673b), U64_C(0xffddb9bac4721013), + U64_C(0x2ab30c8f55ec48cb), U64_C(0xd3ce8a56dfde3fe3), + U64_C(0xc5491d205c88a69b), U64_C(0x3c349bf9d6bad1b3), + U64_C(0x72956a4a63a91636), U64_C(0x8be8ec93e99b611e), + U64_C(0x9d6f7be56acdf866), U64_C(0x6412fd3ce0ff8f4e), + U64_C(0xb17c48097161d796), U64_C(0x4801ced0fb53a0be), + U64_C(0x5e8659a6780539c6), U64_C(0xa7fbdf7ff2374eee), + U64_C(0xc2d9a6dd0f23aad1), U64_C(0x3ba420048511ddf9), + U64_C(0x2d23b77206474481), U64_C(0xd45e31ab8c7533a9), + U64_C(0x0130849e1deb6b71), U64_C(0xf84d024797d91c59), + U64_C(0xeeca9531148f8521), U64_C(0x17b713e89ebdf209), + U64_C(0x5916e25b2bae358c), U64_C(0xa06b6482a19c42a4), + U64_C(0xb6ecf3f422cadbdc), U64_C(0x4f91752da8f8acf4), + U64_C(0x9affc0183966f42c), U64_C(0x638246c1b3548304), + U64_C(0x7505d1b730021a7c), U64_C(0x8c78576eba306d54), + U64_C(0xbf4123eed72acf02), U64_C(0x463ca5375d18b82a), + U64_C(0x50bb3241de4e2152), U64_C(0xa9c6b498547c567a), + U64_C(0x7ca801adc5e20ea2), U64_C(0x85d587744fd0798a), + U64_C(0x93521002cc86e0f2), U64_C(0x6a2f96db46b497da), + U64_C(0x248e6768f3a7505f), U64_C(0xddf3e1b179952777), + U64_C(0xcb7476c7fac3be0f), U64_C(0x3209f01e70f1c927), + U64_C(0xe767452be16f91ff), U64_C(0x1e1ac3f26b5de6d7), + U64_C(0x089d5484e80b7faf), U64_C(0xf1e0d25d62390887), + U64_C(0x94c2abff9f2decb8), U64_C(0x6dbf2d26151f9b90), + U64_C(0x7b38ba50964902e8), U64_C(0x82453c891c7b75c0), + U64_C(0x572b89bc8de52d18), U64_C(0xae560f6507d75a30), + U64_C(0xb8d198138481c348), U64_C(0x41ac1eca0eb3b460), + U64_C(0x0f0def79bba073e5), U64_C(0xf67069a0319204cd), + U64_C(0xe0f7fed6b2c49db5), U64_C(0x198a780f38f6ea9d), + U64_C(0xcce4cd3aa968b245), U64_C(0x35994be3235ac56d), + U64_C(0x231edc95a00c5c15), U64_C(0xda635a4c2a3e2b3d) }, + /* 3 */ + { U64_C(0x0000000000000000), U64_C(0x5b068c651810a89e), + U64_C(0xb60c05ca30204d21), U64_C(0xed0a89af2830e5bf), + U64_C(0x71180a8960409a42), U64_C(0x2a1e86ec785032dc), + U64_C(0xc7140f435060d763), U64_C(0x9c12832648707ffd), + U64_C(0xe230140fc0802984), U64_C(0xb936986ad890811a), + U64_C(0x543c11c5f0a064a5), U64_C(0x0f3a9da0e8b0cc3b), + U64_C(0x93281e86a0c0b3c6), U64_C(0xc82e92e3b8d01b58), + U64_C(0x25241b4c90e0fee7), U64_C(0x7e22972988f05679), + U64_C(0xd960281e9d1d5215), U64_C(0x8266a47b850dfa8b), + U64_C(0x6f6c2dd4ad3d1f34), U64_C(0x346aa1b1b52db7aa), + U64_C(0xa8782297fd5dc857), U64_C(0xf37eaef2e54d60c9), + U64_C(0x1e74275dcd7d8576), U64_C(0x4572ab38d56d2de8), + U64_C(0x3b503c115d9d7b91), U64_C(0x6056b074458dd30f), + U64_C(0x8d5c39db6dbd36b0), U64_C(0xd65ab5be75ad9e2e), + U64_C(0x4a4836983ddde1d3), U64_C(0x114ebafd25cd494d), + U64_C(0xfc4433520dfdacf2), U64_C(0xa742bf3715ed046c), + U64_C(0xafc0503c273aa42a), U64_C(0xf4c6dc593f2a0cb4), + U64_C(0x19cc55f6171ae90b), U64_C(0x42cad9930f0a4195), + U64_C(0xded85ab5477a3e68), U64_C(0x85ded6d05f6a96f6), + U64_C(0x68d45f7f775a7349), U64_C(0x33d2d31a6f4adbd7), + U64_C(0x4df04433e7ba8dae), U64_C(0x16f6c856ffaa2530), + U64_C(0xfbfc41f9d79ac08f), U64_C(0xa0facd9ccf8a6811), + U64_C(0x3ce84eba87fa17ec), U64_C(0x67eec2df9feabf72), + U64_C(0x8ae44b70b7da5acd), U64_C(0xd1e2c715afcaf253), + U64_C(0x76a07822ba27f63f), U64_C(0x2da6f447a2375ea1), + U64_C(0xc0ac7de88a07bb1e), U64_C(0x9baaf18d92171380), + U64_C(0x07b872abda676c7d), U64_C(0x5cbefecec277c4e3), + U64_C(0xb1b47761ea47215c), U64_C(0xeab2fb04f25789c2), + U64_C(0x94906c2d7aa7dfbb), U64_C(0xcf96e04862b77725), + U64_C(0x229c69e74a87929a), U64_C(0x799ae58252973a04), + U64_C(0xe58866a41ae745f9), U64_C(0xbe8eeac102f7ed67), + U64_C(0x5384636e2ac708d8), U64_C(0x0882ef0b32d7a046), + U64_C(0x439da0784e745554), U64_C(0x189b2c1d5664fdca), + U64_C(0xf591a5b27e541875), U64_C(0xae9729d76644b0eb), + U64_C(0x3285aaf12e34cf16), U64_C(0x6983269436246788), + U64_C(0x8489af3b1e148237), U64_C(0xdf8f235e06042aa9), + U64_C(0xa1adb4778ef47cd0), U64_C(0xfaab381296e4d44e), + U64_C(0x17a1b1bdbed431f1), U64_C(0x4ca73dd8a6c4996f), + U64_C(0xd0b5befeeeb4e692), U64_C(0x8bb3329bf6a44e0c), + U64_C(0x66b9bb34de94abb3), U64_C(0x3dbf3751c684032d), + U64_C(0x9afd8866d3690741), U64_C(0xc1fb0403cb79afdf), + U64_C(0x2cf18dace3494a60), U64_C(0x77f701c9fb59e2fe), + U64_C(0xebe582efb3299d03), U64_C(0xb0e30e8aab39359d), + U64_C(0x5de987258309d022), U64_C(0x06ef0b409b1978bc), + U64_C(0x78cd9c6913e92ec5), U64_C(0x23cb100c0bf9865b), + U64_C(0xcec199a323c963e4), U64_C(0x95c715c63bd9cb7a), + U64_C(0x09d596e073a9b487), U64_C(0x52d31a856bb91c19), + U64_C(0xbfd9932a4389f9a6), U64_C(0xe4df1f4f5b995138), + U64_C(0xec5df044694ef17e), U64_C(0xb75b7c21715e59e0), + U64_C(0x5a51f58e596ebc5f), U64_C(0x015779eb417e14c1), + U64_C(0x9d45facd090e6b3c), U64_C(0xc64376a8111ec3a2), + U64_C(0x2b49ff07392e261d), U64_C(0x704f7362213e8e83), + U64_C(0x0e6de44ba9ced8fa), U64_C(0x556b682eb1de7064), + U64_C(0xb861e18199ee95db), U64_C(0xe3676de481fe3d45), + U64_C(0x7f75eec2c98e42b8), U64_C(0x247362a7d19eea26), + U64_C(0xc979eb08f9ae0f99), U64_C(0x927f676de1bea707), + U64_C(0x353dd85af453a36b), U64_C(0x6e3b543fec430bf5), + U64_C(0x8331dd90c473ee4a), U64_C(0xd83751f5dc6346d4), + U64_C(0x4425d2d394133929), U64_C(0x1f235eb68c0391b7), + U64_C(0xf229d719a4337408), U64_C(0xa92f5b7cbc23dc96), + U64_C(0xd70dcc5534d38aef), U64_C(0x8c0b40302cc32271), + U64_C(0x6101c99f04f3c7ce), U64_C(0x3a0745fa1ce36f50), + U64_C(0xa615c6dc549310ad), U64_C(0xfd134ab94c83b833), + U64_C(0x1019c31664b35d8c), U64_C(0x4b1f4f737ca3f512), + U64_C(0x86275df09ce8aaa8), U64_C(0xdd21d19584f80236), + U64_C(0x302b583aacc8e789), U64_C(0x6b2dd45fb4d84f17), + U64_C(0xf73f5779fca830ea), U64_C(0xac39db1ce4b89874), + U64_C(0x413352b3cc887dcb), U64_C(0x1a35ded6d498d555), + U64_C(0x641749ff5c68832c), U64_C(0x3f11c59a44782bb2), + U64_C(0xd21b4c356c48ce0d), U64_C(0x891dc05074586693), + U64_C(0x150f43763c28196e), U64_C(0x4e09cf132438b1f0), + U64_C(0xa30346bc0c08544f), U64_C(0xf805cad91418fcd1), + U64_C(0x5f4775ee01f5f8bd), U64_C(0x0441f98b19e55023), + U64_C(0xe94b702431d5b59c), U64_C(0xb24dfc4129c51d02), + U64_C(0x2e5f7f6761b562ff), U64_C(0x7559f30279a5ca61), + U64_C(0x98537aad51952fde), U64_C(0xc355f6c849858740), + U64_C(0xbd7761e1c175d139), U64_C(0xe671ed84d96579a7), + U64_C(0x0b7b642bf1559c18), U64_C(0x507de84ee9453486), + U64_C(0xcc6f6b68a1354b7b), U64_C(0x9769e70db925e3e5), + U64_C(0x7a636ea29115065a), U64_C(0x2165e2c78905aec4), + U64_C(0x29e70dccbbd20e82), U64_C(0x72e181a9a3c2a61c), + U64_C(0x9feb08068bf243a3), U64_C(0xc4ed846393e2eb3d), + U64_C(0x58ff0745db9294c0), U64_C(0x03f98b20c3823c5e), + U64_C(0xeef3028febb2d9e1), U64_C(0xb5f58eeaf3a2717f), + U64_C(0xcbd719c37b522706), U64_C(0x90d195a663428f98), + U64_C(0x7ddb1c094b726a27), U64_C(0x26dd906c5362c2b9), + U64_C(0xbacf134a1b12bd44), U64_C(0xe1c99f2f030215da), + U64_C(0x0cc316802b32f065), U64_C(0x57c59ae5332258fb), + U64_C(0xf08725d226cf5c97), U64_C(0xab81a9b73edff409), + U64_C(0x468b201816ef11b6), U64_C(0x1d8dac7d0effb928), + U64_C(0x819f2f5b468fc6d5), U64_C(0xda99a33e5e9f6e4b), + U64_C(0x37932a9176af8bf4), U64_C(0x6c95a6f46ebf236a), + U64_C(0x12b731dde64f7513), U64_C(0x49b1bdb8fe5fdd8d), + U64_C(0xa4bb3417d66f3832), U64_C(0xffbdb872ce7f90ac), + U64_C(0x63af3b54860fef51), U64_C(0x38a9b7319e1f47cf), + U64_C(0xd5a33e9eb62fa270), U64_C(0x8ea5b2fbae3f0aee), + U64_C(0xc5bafd88d29cfffc), U64_C(0x9ebc71edca8c5762), + U64_C(0x73b6f842e2bcb2dd), U64_C(0x28b07427faac1a43), + U64_C(0xb4a2f701b2dc65be), U64_C(0xefa47b64aacccd20), + U64_C(0x02aef2cb82fc289f), U64_C(0x59a87eae9aec8001), + U64_C(0x278ae987121cd678), U64_C(0x7c8c65e20a0c7ee6), + U64_C(0x9186ec4d223c9b59), U64_C(0xca8060283a2c33c7), + U64_C(0x5692e30e725c4c3a), U64_C(0x0d946f6b6a4ce4a4), + U64_C(0xe09ee6c4427c011b), U64_C(0xbb986aa15a6ca985), + U64_C(0x1cdad5964f81ade9), U64_C(0x47dc59f357910577), + U64_C(0xaad6d05c7fa1e0c8), U64_C(0xf1d05c3967b14856), + U64_C(0x6dc2df1f2fc137ab), U64_C(0x36c4537a37d19f35), + U64_C(0xdbcedad51fe17a8a), U64_C(0x80c856b007f1d214), + U64_C(0xfeeac1998f01846d), U64_C(0xa5ec4dfc97112cf3), + U64_C(0x48e6c453bf21c94c), U64_C(0x13e04836a73161d2), + U64_C(0x8ff2cb10ef411e2f), U64_C(0xd4f44775f751b6b1), + U64_C(0x39fecedadf61530e), U64_C(0x62f842bfc771fb90), + U64_C(0x6a7aadb4f5a65bd6), U64_C(0x317c21d1edb6f348), + U64_C(0xdc76a87ec58616f7), U64_C(0x8770241bdd96be69), + U64_C(0x1b62a73d95e6c194), U64_C(0x40642b588df6690a), + U64_C(0xad6ea2f7a5c68cb5), U64_C(0xf6682e92bdd6242b), + U64_C(0x884ab9bb35267252), U64_C(0xd34c35de2d36dacc), + U64_C(0x3e46bc7105063f73), U64_C(0x654030141d1697ed), + U64_C(0xf952b3325566e810), U64_C(0xa2543f574d76408e), + U64_C(0x4f5eb6f86546a531), U64_C(0x14583a9d7d560daf), + U64_C(0xb31a85aa68bb09c3), U64_C(0xe81c09cf70aba15d), + U64_C(0x05168060589b44e2), U64_C(0x5e100c05408bec7c), + U64_C(0xc2028f2308fb9381), U64_C(0x9904034610eb3b1f), + U64_C(0x740e8ae938dbdea0), U64_C(0x2f08068c20cb763e), + U64_C(0x512a91a5a83b2047), U64_C(0x0a2c1dc0b02b88d9), + U64_C(0xe726946f981b6d66), U64_C(0xbc20180a800bc5f8), + U64_C(0x20329b2cc87bba05), U64_C(0x7b341749d06b129b), + U64_C(0x963e9ee6f85bf724), U64_C(0xcd381283e04b5fba) }, + /* 4 */ + { U64_C(0x0000000000000000), U64_C(0x0321658cba93c138), + U64_C(0x0642ca05693b9f70), U64_C(0x0563af89d3a85e48), + U64_C(0x0c84890ad27623e0), U64_C(0x0fa5ec8668e5e2d8), + U64_C(0x0ac6430fbb4dbc90), U64_C(0x09e7268301de7da8), + U64_C(0x18150f14b9ec46dd), U64_C(0x1b346a98037f87e5), + U64_C(0x1e57c511d0d7d9ad), U64_C(0x1d76a09d6a441895), + U64_C(0x1491861e6b9a653d), U64_C(0x17b0e392d109a405), + U64_C(0x12d34c1b02a1fa4d), U64_C(0x11f22997b8323b75), + U64_C(0x302a1e286fc58ca7), U64_C(0x330b7ba4d5564d9f), + U64_C(0x3668d42d06fe13d7), U64_C(0x3549b1a1bc6dd2ef), + U64_C(0x3cae9722bdb3af47), U64_C(0x3f8ff2ae07206e7f), + U64_C(0x3aec5d27d4883037), U64_C(0x39cd38ab6e1bf10f), + U64_C(0x283f113cd629ca7a), U64_C(0x2b1e74b06cba0b42), + U64_C(0x2e7ddb39bf12550a), U64_C(0x2d5cbeb505819432), + U64_C(0x24bb9836045fe99a), U64_C(0x279afdbabecc28a2), + U64_C(0x22f952336d6476ea), U64_C(0x21d837bfd7f7b7d2), + U64_C(0x60543c50de970553), U64_C(0x637559dc6404c46b), + U64_C(0x6616f655b7ac9a23), U64_C(0x653793d90d3f5b1b), + U64_C(0x6cd0b55a0ce126b3), U64_C(0x6ff1d0d6b672e78b), + U64_C(0x6a927f5f65dab9c3), U64_C(0x69b31ad3df4978fb), + U64_C(0x78413344677b438e), U64_C(0x7b6056c8dde882b6), + U64_C(0x7e03f9410e40dcfe), U64_C(0x7d229ccdb4d31dc6), + U64_C(0x74c5ba4eb50d606e), U64_C(0x77e4dfc20f9ea156), + U64_C(0x7287704bdc36ff1e), U64_C(0x71a615c766a53e26), + U64_C(0x507e2278b15289f4), U64_C(0x535f47f40bc148cc), + U64_C(0x563ce87dd8691684), U64_C(0x551d8df162fad7bc), + U64_C(0x5cfaab726324aa14), U64_C(0x5fdbcefed9b76b2c), + U64_C(0x5ab861770a1f3564), U64_C(0x599904fbb08cf45c), + U64_C(0x486b2d6c08becf29), U64_C(0x4b4a48e0b22d0e11), + U64_C(0x4e29e76961855059), U64_C(0x4d0882e5db169161), + U64_C(0x44efa466dac8ecc9), U64_C(0x47cec1ea605b2df1), + U64_C(0x42ad6e63b3f373b9), U64_C(0x418c0bef0960b281), + U64_C(0xc0a878a0a1330aa6), U64_C(0xc3891d2c1ba0cb9e), + U64_C(0xc6eab2a5c80895d6), U64_C(0xc5cbd729729b54ee), + U64_C(0xcc2cf1aa73452946), U64_C(0xcf0d9426c9d6e87e), + U64_C(0xca6e3baf1a7eb636), U64_C(0xc94f5e23a0ed770e), + U64_C(0xd8bd77b418df4c7b), U64_C(0xdb9c1238a24c8d43), + U64_C(0xdeffbdb171e4d30b), U64_C(0xddded83dcb771233), + U64_C(0xd439febecaa96f9b), U64_C(0xd7189b32703aaea3), + U64_C(0xd27b34bba392f0eb), U64_C(0xd15a5137190131d3), + U64_C(0xf0826688cef68601), U64_C(0xf3a3030474654739), + U64_C(0xf6c0ac8da7cd1971), U64_C(0xf5e1c9011d5ed849), + U64_C(0xfc06ef821c80a5e1), U64_C(0xff278a0ea61364d9), + U64_C(0xfa44258775bb3a91), U64_C(0xf965400bcf28fba9), + U64_C(0xe897699c771ac0dc), U64_C(0xebb60c10cd8901e4), + U64_C(0xeed5a3991e215fac), U64_C(0xedf4c615a4b29e94), + U64_C(0xe413e096a56ce33c), U64_C(0xe732851a1fff2204), + U64_C(0xe2512a93cc577c4c), U64_C(0xe1704f1f76c4bd74), + U64_C(0xa0fc44f07fa40ff5), U64_C(0xa3dd217cc537cecd), + U64_C(0xa6be8ef5169f9085), U64_C(0xa59feb79ac0c51bd), + U64_C(0xac78cdfaadd22c15), U64_C(0xaf59a8761741ed2d), + U64_C(0xaa3a07ffc4e9b365), U64_C(0xa91b62737e7a725d), + U64_C(0xb8e94be4c6484928), U64_C(0xbbc82e687cdb8810), + U64_C(0xbeab81e1af73d658), U64_C(0xbd8ae46d15e01760), + U64_C(0xb46dc2ee143e6ac8), U64_C(0xb74ca762aeadabf0), + U64_C(0xb22f08eb7d05f5b8), U64_C(0xb10e6d67c7963480), + U64_C(0x90d65ad810618352), U64_C(0x93f73f54aaf2426a), + U64_C(0x969490dd795a1c22), U64_C(0x95b5f551c3c9dd1a), + U64_C(0x9c52d3d2c217a0b2), U64_C(0x9f73b65e7884618a), + U64_C(0x9a1019d7ab2c3fc2), U64_C(0x99317c5b11bffefa), + U64_C(0x88c355cca98dc58f), U64_C(0x8be23040131e04b7), + U64_C(0x8e819fc9c0b65aff), U64_C(0x8da0fa457a259bc7), + U64_C(0x8447dcc67bfbe66f), U64_C(0x8766b94ac1682757), + U64_C(0x820516c312c0791f), U64_C(0x8124734fa853b827), + U64_C(0x9d4df05d5f661451), U64_C(0x9e6c95d1e5f5d569), + U64_C(0x9b0f3a58365d8b21), U64_C(0x982e5fd48cce4a19), + U64_C(0x91c979578d1037b1), U64_C(0x92e81cdb3783f689), + U64_C(0x978bb352e42ba8c1), U64_C(0x94aad6de5eb869f9), + U64_C(0x8558ff49e68a528c), U64_C(0x86799ac55c1993b4), + U64_C(0x831a354c8fb1cdfc), U64_C(0x803b50c035220cc4), + U64_C(0x89dc764334fc716c), U64_C(0x8afd13cf8e6fb054), + U64_C(0x8f9ebc465dc7ee1c), U64_C(0x8cbfd9cae7542f24), + U64_C(0xad67ee7530a398f6), U64_C(0xae468bf98a3059ce), + U64_C(0xab25247059980786), U64_C(0xa80441fce30bc6be), + U64_C(0xa1e3677fe2d5bb16), U64_C(0xa2c202f358467a2e), + U64_C(0xa7a1ad7a8bee2466), U64_C(0xa480c8f6317de55e), + U64_C(0xb572e161894fde2b), U64_C(0xb65384ed33dc1f13), + U64_C(0xb3302b64e074415b), U64_C(0xb0114ee85ae78063), + U64_C(0xb9f6686b5b39fdcb), U64_C(0xbad70de7e1aa3cf3), + U64_C(0xbfb4a26e320262bb), U64_C(0xbc95c7e28891a383), + U64_C(0xfd19cc0d81f11102), U64_C(0xfe38a9813b62d03a), + U64_C(0xfb5b0608e8ca8e72), U64_C(0xf87a638452594f4a), + U64_C(0xf19d4507538732e2), U64_C(0xf2bc208be914f3da), + U64_C(0xf7df8f023abcad92), U64_C(0xf4feea8e802f6caa), + U64_C(0xe50cc319381d57df), U64_C(0xe62da695828e96e7), + U64_C(0xe34e091c5126c8af), U64_C(0xe06f6c90ebb50997), + U64_C(0xe9884a13ea6b743f), U64_C(0xeaa92f9f50f8b507), + U64_C(0xefca80168350eb4f), U64_C(0xecebe59a39c32a77), + U64_C(0xcd33d225ee349da5), U64_C(0xce12b7a954a75c9d), + U64_C(0xcb711820870f02d5), U64_C(0xc8507dac3d9cc3ed), + U64_C(0xc1b75b2f3c42be45), U64_C(0xc2963ea386d17f7d), + U64_C(0xc7f5912a55792135), U64_C(0xc4d4f4a6efeae00d), + U64_C(0xd526dd3157d8db78), U64_C(0xd607b8bded4b1a40), + U64_C(0xd36417343ee34408), U64_C(0xd04572b884708530), + U64_C(0xd9a2543b85aef898), U64_C(0xda8331b73f3d39a0), + U64_C(0xdfe09e3eec9567e8), U64_C(0xdcc1fbb25606a6d0), + U64_C(0x5de588fdfe551ef7), U64_C(0x5ec4ed7144c6dfcf), + U64_C(0x5ba742f8976e8187), U64_C(0x588627742dfd40bf), + U64_C(0x516101f72c233d17), U64_C(0x5240647b96b0fc2f), + U64_C(0x5723cbf24518a267), U64_C(0x5402ae7eff8b635f), + U64_C(0x45f087e947b9582a), U64_C(0x46d1e265fd2a9912), + U64_C(0x43b24dec2e82c75a), U64_C(0x4093286094110662), + U64_C(0x49740ee395cf7bca), U64_C(0x4a556b6f2f5cbaf2), + U64_C(0x4f36c4e6fcf4e4ba), U64_C(0x4c17a16a46672582), + U64_C(0x6dcf96d591909250), U64_C(0x6eeef3592b035368), + U64_C(0x6b8d5cd0f8ab0d20), U64_C(0x68ac395c4238cc18), + U64_C(0x614b1fdf43e6b1b0), U64_C(0x626a7a53f9757088), + U64_C(0x6709d5da2add2ec0), U64_C(0x6428b056904eeff8), + U64_C(0x75da99c1287cd48d), U64_C(0x76fbfc4d92ef15b5), + U64_C(0x739853c441474bfd), U64_C(0x70b93648fbd48ac5), + U64_C(0x795e10cbfa0af76d), U64_C(0x7a7f754740993655), + U64_C(0x7f1cdace9331681d), U64_C(0x7c3dbf4229a2a925), + U64_C(0x3db1b4ad20c21ba4), U64_C(0x3e90d1219a51da9c), + U64_C(0x3bf37ea849f984d4), U64_C(0x38d21b24f36a45ec), + U64_C(0x31353da7f2b43844), U64_C(0x3214582b4827f97c), + U64_C(0x3777f7a29b8fa734), U64_C(0x3456922e211c660c), + U64_C(0x25a4bbb9992e5d79), U64_C(0x2685de3523bd9c41), + U64_C(0x23e671bcf015c209), U64_C(0x20c714304a860331), + U64_C(0x292032b34b587e99), U64_C(0x2a01573ff1cbbfa1), + U64_C(0x2f62f8b62263e1e9), U64_C(0x2c439d3a98f020d1), + U64_C(0x0d9baa854f079703), U64_C(0x0ebacf09f594563b), + U64_C(0x0bd96080263c0873), U64_C(0x08f8050c9cafc94b), + U64_C(0x011f238f9d71b4e3), U64_C(0x023e460327e275db), + U64_C(0x075de98af44a2b93), U64_C(0x047c8c064ed9eaab), + U64_C(0x158ea591f6ebd1de), U64_C(0x16afc01d4c7810e6), + U64_C(0x13cc6f949fd04eae), U64_C(0x10ed0a1825438f96), + U64_C(0x190a2c9b249df23e), U64_C(0x1a2b49179e0e3306), + U64_C(0x1f48e69e4da66d4e), U64_C(0x1c698312f735ac76) }, + /* 5 */ + { U64_C(0x0000000000000000), U64_C(0xaccc9ca9328a8950), + U64_C(0x4585254f64090fa0), U64_C(0xe949b9e6568386f0), + U64_C(0x8a174a9ec8121e5d), U64_C(0x26dbd637fa98970d), + U64_C(0xcf926fd1ac1b11fd), U64_C(0x635ef3789e9198ad), + U64_C(0x092e94218d243cba), U64_C(0xa5e20888bfaeb5ea), + U64_C(0x4cabb16ee92d331a), U64_C(0xe0672dc7dba7ba4a), + U64_C(0x8339debf453622e7), U64_C(0x2ff5421677bcabb7), + U64_C(0xc6bcfbf0213f2d47), U64_C(0x6a70675913b5a417), + U64_C(0x125c354207487869), U64_C(0xbe90a9eb35c2f139), + U64_C(0x57d9100d634177c9), U64_C(0xfb158ca451cbfe99), + U64_C(0x984b7fdccf5a6634), U64_C(0x3487e375fdd0ef64), + U64_C(0xddce5a93ab536994), U64_C(0x7102c63a99d9e0c4), + U64_C(0x1b72a1638a6c44d3), U64_C(0xb7be3dcab8e6cd83), + U64_C(0x5ef7842cee654b73), U64_C(0xf23b1885dcefc223), + U64_C(0x9165ebfd427e5a8e), U64_C(0x3da9775470f4d3de), + U64_C(0xd4e0ceb22677552e), U64_C(0x782c521b14fddc7e), + U64_C(0x24b86a840e90f0d2), U64_C(0x8874f62d3c1a7982), + U64_C(0x613d4fcb6a99ff72), U64_C(0xcdf1d36258137622), + U64_C(0xaeaf201ac682ee8f), U64_C(0x0263bcb3f40867df), + U64_C(0xeb2a0555a28be12f), U64_C(0x47e699fc9001687f), + U64_C(0x2d96fea583b4cc68), U64_C(0x815a620cb13e4538), + U64_C(0x6813dbeae7bdc3c8), U64_C(0xc4df4743d5374a98), + U64_C(0xa781b43b4ba6d235), U64_C(0x0b4d2892792c5b65), + U64_C(0xe20491742fafdd95), U64_C(0x4ec80ddd1d2554c5), + U64_C(0x36e45fc609d888bb), U64_C(0x9a28c36f3b5201eb), + U64_C(0x73617a896dd1871b), U64_C(0xdfade6205f5b0e4b), + U64_C(0xbcf31558c1ca96e6), U64_C(0x103f89f1f3401fb6), + U64_C(0xf9763017a5c39946), U64_C(0x55baacbe97491016), + U64_C(0x3fcacbe784fcb401), U64_C(0x9306574eb6763d51), + U64_C(0x7a4feea8e0f5bba1), U64_C(0xd6837201d27f32f1), + U64_C(0xb5dd81794ceeaa5c), U64_C(0x19111dd07e64230c), + U64_C(0xf058a43628e7a5fc), U64_C(0x5c94389f1a6d2cac), + U64_C(0x486dd4151c3dfdb9), U64_C(0xe4a148bc2eb774e9), + U64_C(0x0de8f15a7834f219), U64_C(0xa1246df34abe7b49), + U64_C(0xc27a9e8bd42fe3e4), U64_C(0x6eb60222e6a56ab4), + U64_C(0x87ffbbc4b026ec44), U64_C(0x2b33276d82ac6514), + U64_C(0x414340349119c103), U64_C(0xed8fdc9da3934853), + U64_C(0x04c6657bf510cea3), U64_C(0xa80af9d2c79a47f3), + U64_C(0xcb540aaa590bdf5e), U64_C(0x679896036b81560e), + U64_C(0x8ed12fe53d02d0fe), U64_C(0x221db34c0f8859ae), + U64_C(0x5a31e1571b7585d0), U64_C(0xf6fd7dfe29ff0c80), + U64_C(0x1fb4c4187f7c8a70), U64_C(0xb37858b14df60320), + U64_C(0xd026abc9d3679b8d), U64_C(0x7cea3760e1ed12dd), + U64_C(0x95a38e86b76e942d), U64_C(0x396f122f85e41d7d), + U64_C(0x531f75769651b96a), U64_C(0xffd3e9dfa4db303a), + U64_C(0x169a5039f258b6ca), U64_C(0xba56cc90c0d23f9a), + U64_C(0xd9083fe85e43a737), U64_C(0x75c4a3416cc92e67), + U64_C(0x9c8d1aa73a4aa897), U64_C(0x3041860e08c021c7), + U64_C(0x6cd5be9112ad0d6b), U64_C(0xc01922382027843b), + U64_C(0x29509bde76a402cb), U64_C(0x859c0777442e8b9b), + U64_C(0xe6c2f40fdabf1336), U64_C(0x4a0e68a6e8359a66), + U64_C(0xa347d140beb61c96), U64_C(0x0f8b4de98c3c95c6), + U64_C(0x65fb2ab09f8931d1), U64_C(0xc937b619ad03b881), + U64_C(0x207e0ffffb803e71), U64_C(0x8cb29356c90ab721), + U64_C(0xefec602e579b2f8c), U64_C(0x4320fc876511a6dc), + U64_C(0xaa6945613392202c), U64_C(0x06a5d9c80118a97c), + U64_C(0x7e898bd315e57502), U64_C(0xd245177a276ffc52), + U64_C(0x3b0cae9c71ec7aa2), U64_C(0x97c032354366f3f2), + U64_C(0xf49ec14dddf76b5f), U64_C(0x58525de4ef7de20f), + U64_C(0xb11be402b9fe64ff), U64_C(0x1dd778ab8b74edaf), + U64_C(0x77a71ff298c149b8), U64_C(0xdb6b835baa4bc0e8), + U64_C(0x32223abdfcc84618), U64_C(0x9eeea614ce42cf48), + U64_C(0xfdb0556c50d357e5), U64_C(0x517cc9c56259deb5), + U64_C(0xb835702334da5845), U64_C(0x14f9ec8a0650d115), + U64_C(0x90dab52a387ae76f), U64_C(0x3c1629830af06e3f), + U64_C(0xd55f90655c73e8cf), U64_C(0x79930ccc6ef9619f), + U64_C(0x1acdffb4f068f932), U64_C(0xb601631dc2e27062), + U64_C(0x5f48dafb9461f692), U64_C(0xf3844652a6eb7fc2), + U64_C(0x99f4210bb55edbd5), U64_C(0x3538bda287d45285), + U64_C(0xdc710444d157d475), U64_C(0x70bd98ede3dd5d25), + U64_C(0x13e36b957d4cc588), U64_C(0xbf2ff73c4fc64cd8), + U64_C(0x56664eda1945ca28), U64_C(0xfaaad2732bcf4378), + U64_C(0x828680683f329f06), U64_C(0x2e4a1cc10db81656), + U64_C(0xc703a5275b3b90a6), U64_C(0x6bcf398e69b119f6), + U64_C(0x0891caf6f720815b), U64_C(0xa45d565fc5aa080b), + U64_C(0x4d14efb993298efb), U64_C(0xe1d87310a1a307ab), + U64_C(0x8ba81449b216a3bc), U64_C(0x276488e0809c2aec), + U64_C(0xce2d3106d61fac1c), U64_C(0x62e1adafe495254c), + U64_C(0x01bf5ed77a04bde1), U64_C(0xad73c27e488e34b1), + U64_C(0x443a7b981e0db241), U64_C(0xe8f6e7312c873b11), + U64_C(0xb462dfae36ea17bd), U64_C(0x18ae430704609eed), + U64_C(0xf1e7fae152e3181d), U64_C(0x5d2b66486069914d), + U64_C(0x3e759530fef809e0), U64_C(0x92b90999cc7280b0), + U64_C(0x7bf0b07f9af10640), U64_C(0xd73c2cd6a87b8f10), + U64_C(0xbd4c4b8fbbce2b07), U64_C(0x1180d7268944a257), + U64_C(0xf8c96ec0dfc724a7), U64_C(0x5405f269ed4dadf7), + U64_C(0x375b011173dc355a), U64_C(0x9b979db84156bc0a), + U64_C(0x72de245e17d53afa), U64_C(0xde12b8f7255fb3aa), + U64_C(0xa63eeaec31a26fd4), U64_C(0x0af276450328e684), + U64_C(0xe3bbcfa355ab6074), U64_C(0x4f77530a6721e924), + U64_C(0x2c29a072f9b07189), U64_C(0x80e53cdbcb3af8d9), + U64_C(0x69ac853d9db97e29), U64_C(0xc5601994af33f779), + U64_C(0xaf107ecdbc86536e), U64_C(0x03dce2648e0cda3e), + U64_C(0xea955b82d88f5cce), U64_C(0x4659c72bea05d59e), + U64_C(0x2507345374944d33), U64_C(0x89cba8fa461ec463), + U64_C(0x6082111c109d4293), U64_C(0xcc4e8db52217cbc3), + U64_C(0xd8b7613f24471ad6), U64_C(0x747bfd9616cd9386), + U64_C(0x9d324470404e1576), U64_C(0x31fed8d972c49c26), + U64_C(0x52a02ba1ec55048b), U64_C(0xfe6cb708dedf8ddb), + U64_C(0x17250eee885c0b2b), U64_C(0xbbe99247bad6827b), + U64_C(0xd199f51ea963266c), U64_C(0x7d5569b79be9af3c), + U64_C(0x941cd051cd6a29cc), U64_C(0x38d04cf8ffe0a09c), + U64_C(0x5b8ebf8061713831), U64_C(0xf742232953fbb161), + U64_C(0x1e0b9acf05783791), U64_C(0xb2c7066637f2bec1), + U64_C(0xcaeb547d230f62bf), U64_C(0x6627c8d41185ebef), + U64_C(0x8f6e713247066d1f), U64_C(0x23a2ed9b758ce44f), + U64_C(0x40fc1ee3eb1d7ce2), U64_C(0xec30824ad997f5b2), + U64_C(0x05793bac8f147342), U64_C(0xa9b5a705bd9efa12), + U64_C(0xc3c5c05cae2b5e05), U64_C(0x6f095cf59ca1d755), + U64_C(0x8640e513ca2251a5), U64_C(0x2a8c79baf8a8d8f5), + U64_C(0x49d28ac266394058), U64_C(0xe51e166b54b3c908), + U64_C(0x0c57af8d02304ff8), U64_C(0xa09b332430bac6a8), + U64_C(0xfc0f0bbb2ad7ea04), U64_C(0x50c39712185d6354), + U64_C(0xb98a2ef44edee5a4), U64_C(0x1546b25d7c546cf4), + U64_C(0x76184125e2c5f459), U64_C(0xdad4dd8cd04f7d09), + U64_C(0x339d646a86ccfbf9), U64_C(0x9f51f8c3b44672a9), + U64_C(0xf5219f9aa7f3d6be), U64_C(0x59ed033395795fee), + U64_C(0xb0a4bad5c3fad91e), U64_C(0x1c68267cf170504e), + U64_C(0x7f36d5046fe1c8e3), U64_C(0xd3fa49ad5d6b41b3), + U64_C(0x3ab3f04b0be8c743), U64_C(0x967f6ce239624e13), + U64_C(0xee533ef92d9f926d), U64_C(0x429fa2501f151b3d), + U64_C(0xabd61bb649969dcd), U64_C(0x071a871f7b1c149d), + U64_C(0x64447467e58d8c30), U64_C(0xc888e8ced7070560), + U64_C(0x21c1512881848390), U64_C(0x8d0dcd81b30e0ac0), + U64_C(0xe77daad8a0bbaed7), U64_C(0x4bb1367192312787), + U64_C(0xa2f88f97c4b2a177), U64_C(0x0e34133ef6382827), + U64_C(0x6d6ae04668a9b08a), U64_C(0xc1a67cef5a2339da), + U64_C(0x28efc5090ca0bf2a), U64_C(0x842359a03e2a367a) }, + /* 6 */ + { U64_C(0x0000000000000000), U64_C(0x46b60f011a83988e), + U64_C(0x8c711e02341b2d01), U64_C(0xcac711032e98b58f), + U64_C(0x05e23c0468365a02), U64_C(0x4354330572b5c28c), + U64_C(0x899322065c2d7703), U64_C(0xcf252d0746aeef8d), + U64_C(0x0ad97808d06cb404), U64_C(0x4c6f7709caef2c8a), + U64_C(0x86a8660ae4779905), U64_C(0xc01e690bfef4018b), + U64_C(0x0f3b440cb85aee06), U64_C(0x498d4b0da2d97688), + U64_C(0x834a5a0e8c41c307), U64_C(0xc5fc550f96c25b89), + U64_C(0x14aff010bdd87508), U64_C(0x5219ff11a75bed86), + U64_C(0x98deee1289c35809), U64_C(0xde68e1139340c087), + U64_C(0x114dcc14d5ee2f0a), U64_C(0x57fbc315cf6db784), + U64_C(0x9d3cd216e1f5020b), U64_C(0xdb8add17fb769a85), + U64_C(0x1e7688186db4c10c), U64_C(0x58c0871977375982), + U64_C(0x9207961a59afec0d), U64_C(0xd4b1991b432c7483), + U64_C(0x1b94b41c05829b0e), U64_C(0x5d22bb1d1f010380), + U64_C(0x97e5aa1e3199b60f), U64_C(0xd153a51f2b1a2e81), + U64_C(0x2843fd2067adea10), U64_C(0x6ef5f2217d2e729e), + U64_C(0xa432e32253b6c711), U64_C(0xe284ec2349355f9f), + U64_C(0x2da1c1240f9bb012), U64_C(0x6b17ce251518289c), + U64_C(0xa1d0df263b809d13), U64_C(0xe766d0272103059d), + U64_C(0x229a8528b7c15e14), U64_C(0x642c8a29ad42c69a), + U64_C(0xaeeb9b2a83da7315), U64_C(0xe85d942b9959eb9b), + U64_C(0x2778b92cdff70416), U64_C(0x61ceb62dc5749c98), + U64_C(0xab09a72eebec2917), U64_C(0xedbfa82ff16fb199), + U64_C(0x3cec0d30da759f18), U64_C(0x7a5a0231c0f60796), + U64_C(0xb09d1332ee6eb219), U64_C(0xf62b1c33f4ed2a97), + U64_C(0x390e3134b243c51a), U64_C(0x7fb83e35a8c05d94), + U64_C(0xb57f2f368658e81b), U64_C(0xf3c920379cdb7095), + U64_C(0x363575380a192b1c), U64_C(0x70837a39109ab392), + U64_C(0xba446b3a3e02061d), U64_C(0xfcf2643b24819e93), + U64_C(0x33d7493c622f711e), U64_C(0x7561463d78ace990), + U64_C(0xbfa6573e56345c1f), U64_C(0xf910583f4cb7c491), + U64_C(0x5086e740ce47c920), U64_C(0x1630e841d4c451ae), + U64_C(0xdcf7f942fa5ce421), U64_C(0x9a41f643e0df7caf), + U64_C(0x5564db44a6719322), U64_C(0x13d2d445bcf20bac), + U64_C(0xd915c546926abe23), U64_C(0x9fa3ca4788e926ad), + U64_C(0x5a5f9f481e2b7d24), U64_C(0x1ce9904904a8e5aa), + U64_C(0xd62e814a2a305025), U64_C(0x90988e4b30b3c8ab), + U64_C(0x5fbda34c761d2726), U64_C(0x190bac4d6c9ebfa8), + U64_C(0xd3ccbd4e42060a27), U64_C(0x957ab24f588592a9), + U64_C(0x44291750739fbc28), U64_C(0x029f1851691c24a6), + U64_C(0xc858095247849129), U64_C(0x8eee06535d0709a7), + U64_C(0x41cb2b541ba9e62a), U64_C(0x077d2455012a7ea4), + U64_C(0xcdba35562fb2cb2b), U64_C(0x8b0c3a57353153a5), + U64_C(0x4ef06f58a3f3082c), U64_C(0x08466059b97090a2), + U64_C(0xc281715a97e8252d), U64_C(0x84377e5b8d6bbda3), + U64_C(0x4b12535ccbc5522e), U64_C(0x0da45c5dd146caa0), + U64_C(0xc7634d5effde7f2f), U64_C(0x81d5425fe55de7a1), + U64_C(0x78c51a60a9ea2330), U64_C(0x3e731561b369bbbe), + U64_C(0xf4b404629df10e31), U64_C(0xb2020b63877296bf), + U64_C(0x7d272664c1dc7932), U64_C(0x3b912965db5fe1bc), + U64_C(0xf1563866f5c75433), U64_C(0xb7e03767ef44ccbd), + U64_C(0x721c626879869734), U64_C(0x34aa6d6963050fba), + U64_C(0xfe6d7c6a4d9dba35), U64_C(0xb8db736b571e22bb), + U64_C(0x77fe5e6c11b0cd36), U64_C(0x3148516d0b3355b8), + U64_C(0xfb8f406e25abe037), U64_C(0xbd394f6f3f2878b9), + U64_C(0x6c6aea7014325638), U64_C(0x2adce5710eb1ceb6), + U64_C(0xe01bf47220297b39), U64_C(0xa6adfb733aaae3b7), + U64_C(0x6988d6747c040c3a), U64_C(0x2f3ed975668794b4), + U64_C(0xe5f9c876481f213b), U64_C(0xa34fc777529cb9b5), + U64_C(0x66b39278c45ee23c), U64_C(0x20059d79dedd7ab2), + U64_C(0xeac28c7af045cf3d), U64_C(0xac74837beac657b3), + U64_C(0x6351ae7cac68b83e), U64_C(0x25e7a17db6eb20b0), + U64_C(0xef20b07e9873953f), U64_C(0xa996bf7f82f00db1), + U64_C(0xa011d380818e8f40), U64_C(0xe6a7dc819b0d17ce), + U64_C(0x2c60cd82b595a241), U64_C(0x6ad6c283af163acf), + U64_C(0xa5f3ef84e9b8d542), U64_C(0xe345e085f33b4dcc), + U64_C(0x2982f186dda3f843), U64_C(0x6f34fe87c72060cd), + U64_C(0xaac8ab8851e23b44), U64_C(0xec7ea4894b61a3ca), + U64_C(0x26b9b58a65f91645), U64_C(0x600fba8b7f7a8ecb), + U64_C(0xaf2a978c39d46146), U64_C(0xe99c988d2357f9c8), + U64_C(0x235b898e0dcf4c47), U64_C(0x65ed868f174cd4c9), + U64_C(0xb4be23903c56fa48), U64_C(0xf2082c9126d562c6), + U64_C(0x38cf3d92084dd749), U64_C(0x7e79329312ce4fc7), + U64_C(0xb15c1f945460a04a), U64_C(0xf7ea10954ee338c4), + U64_C(0x3d2d0196607b8d4b), U64_C(0x7b9b0e977af815c5), + U64_C(0xbe675b98ec3a4e4c), U64_C(0xf8d15499f6b9d6c2), + U64_C(0x3216459ad821634d), U64_C(0x74a04a9bc2a2fbc3), + U64_C(0xbb85679c840c144e), U64_C(0xfd33689d9e8f8cc0), + U64_C(0x37f4799eb017394f), U64_C(0x7142769faa94a1c1), + U64_C(0x88522ea0e6236550), U64_C(0xcee421a1fca0fdde), + U64_C(0x042330a2d2384851), U64_C(0x42953fa3c8bbd0df), + U64_C(0x8db012a48e153f52), U64_C(0xcb061da59496a7dc), + U64_C(0x01c10ca6ba0e1253), U64_C(0x477703a7a08d8add), + U64_C(0x828b56a8364fd154), U64_C(0xc43d59a92ccc49da), + U64_C(0x0efa48aa0254fc55), U64_C(0x484c47ab18d764db), + U64_C(0x87696aac5e798b56), U64_C(0xc1df65ad44fa13d8), + U64_C(0x0b1874ae6a62a657), U64_C(0x4dae7baf70e13ed9), + U64_C(0x9cfddeb05bfb1058), U64_C(0xda4bd1b1417888d6), + U64_C(0x108cc0b26fe03d59), U64_C(0x563acfb37563a5d7), + U64_C(0x991fe2b433cd4a5a), U64_C(0xdfa9edb5294ed2d4), + U64_C(0x156efcb607d6675b), U64_C(0x53d8f3b71d55ffd5), + U64_C(0x9624a6b88b97a45c), U64_C(0xd092a9b991143cd2), + U64_C(0x1a55b8babf8c895d), U64_C(0x5ce3b7bba50f11d3), + U64_C(0x93c69abce3a1fe5e), U64_C(0xd57095bdf92266d0), + U64_C(0x1fb784bed7bad35f), U64_C(0x59018bbfcd394bd1), + U64_C(0xf09734c04fc94660), U64_C(0xb6213bc1554adeee), + U64_C(0x7ce62ac27bd26b61), U64_C(0x3a5025c36151f3ef), + U64_C(0xf57508c427ff1c62), U64_C(0xb3c307c53d7c84ec), + U64_C(0x790416c613e43163), U64_C(0x3fb219c70967a9ed), + U64_C(0xfa4e4cc89fa5f264), U64_C(0xbcf843c985266aea), + U64_C(0x763f52caabbedf65), U64_C(0x30895dcbb13d47eb), + U64_C(0xffac70ccf793a866), U64_C(0xb91a7fcded1030e8), + U64_C(0x73dd6ecec3888567), U64_C(0x356b61cfd90b1de9), + U64_C(0xe438c4d0f2113368), U64_C(0xa28ecbd1e892abe6), + U64_C(0x6849dad2c60a1e69), U64_C(0x2effd5d3dc8986e7), + U64_C(0xe1daf8d49a27696a), U64_C(0xa76cf7d580a4f1e4), + U64_C(0x6dabe6d6ae3c446b), U64_C(0x2b1de9d7b4bfdce5), + U64_C(0xeee1bcd8227d876c), U64_C(0xa857b3d938fe1fe2), + U64_C(0x6290a2da1666aa6d), U64_C(0x2426addb0ce532e3), + U64_C(0xeb0380dc4a4bdd6e), U64_C(0xadb58fdd50c845e0), + U64_C(0x67729ede7e50f06f), U64_C(0x21c491df64d368e1), + U64_C(0xd8d4c9e02864ac70), U64_C(0x9e62c6e132e734fe), + U64_C(0x54a5d7e21c7f8171), U64_C(0x1213d8e306fc19ff), + U64_C(0xdd36f5e44052f672), U64_C(0x9b80fae55ad16efc), + U64_C(0x5147ebe67449db73), U64_C(0x17f1e4e76eca43fd), + U64_C(0xd20db1e8f8081874), U64_C(0x94bbbee9e28b80fa), + U64_C(0x5e7cafeacc133575), U64_C(0x18caa0ebd690adfb), + U64_C(0xd7ef8dec903e4276), U64_C(0x915982ed8abddaf8), + U64_C(0x5b9e93eea4256f77), U64_C(0x1d289cefbea6f7f9), + U64_C(0xcc7b39f095bcd978), U64_C(0x8acd36f18f3f41f6), + U64_C(0x400a27f2a1a7f479), U64_C(0x06bc28f3bb246cf7), + U64_C(0xc99905f4fd8a837a), U64_C(0x8f2f0af5e7091bf4), + U64_C(0x45e81bf6c991ae7b), U64_C(0x035e14f7d31236f5), + U64_C(0xc6a241f845d06d7c), U64_C(0x80144ef95f53f5f2), + U64_C(0x4ad35ffa71cb407d), U64_C(0x0c6550fb6b48d8f3), + U64_C(0xc3407dfc2de6377e), U64_C(0x85f672fd3765aff0), + U64_C(0x4f3163fe19fd1a7f), U64_C(0x09876cff037e82f1) }, + /* 7 */ + { U64_C(0x0000000000000000), U64_C(0x83478b07b2468764), + U64_C(0x1b8e0b0e798c13c8), U64_C(0x98c98009cbca94ac), + U64_C(0x3601161cf205268d), U64_C(0xb5469d1b4043a1e9), + U64_C(0x2d8f1d128b893545), U64_C(0xaec8961539cfb221), + U64_C(0x6c022c38f90a4c07), U64_C(0xef45a73f4b4ccb63), + U64_C(0x778c273680865fcf), U64_C(0xf4cbac3132c0d8ab), + U64_C(0x5a033a240b0f6a8a), U64_C(0xd944b123b949edee), + U64_C(0x418d312a72837942), U64_C(0xc2caba2dc0c5fe26), + U64_C(0xd8045870ef14980e), U64_C(0x5b43d3775d521f6a), + U64_C(0xc38a537e96988bc6), U64_C(0x40cdd87924de0ca2), + U64_C(0xee054e6c1d11be83), U64_C(0x6d42c56baf5739e7), + U64_C(0xf58b4562649dad4b), U64_C(0x76ccce65d6db2a2f), + U64_C(0xb4067448161ed409), U64_C(0x3741ff4fa458536d), + U64_C(0xaf887f466f92c7c1), U64_C(0x2ccff441ddd440a5), + U64_C(0x82076254e41bf284), U64_C(0x0140e953565d75e0), + U64_C(0x9989695a9d97e14c), U64_C(0x1acee25d2fd16628), + U64_C(0xad08b0e0c3282d1c), U64_C(0x2e4f3be7716eaa78), + U64_C(0xb686bbeebaa43ed4), U64_C(0x35c130e908e2b9b0), + U64_C(0x9b09a6fc312d0b91), U64_C(0x184e2dfb836b8cf5), + U64_C(0x8087adf248a11859), U64_C(0x03c026f5fae79f3d), + U64_C(0xc10a9cd83a22611b), U64_C(0x424d17df8864e67f), + U64_C(0xda8497d643ae72d3), U64_C(0x59c31cd1f1e8f5b7), + U64_C(0xf70b8ac4c8274796), U64_C(0x744c01c37a61c0f2), + U64_C(0xec8581cab1ab545e), U64_C(0x6fc20acd03edd33a), + U64_C(0x750ce8902c3cb512), U64_C(0xf64b63979e7a3276), + U64_C(0x6e82e39e55b0a6da), U64_C(0xedc56899e7f621be), + U64_C(0x430dfe8cde39939f), U64_C(0xc04a758b6c7f14fb), + U64_C(0x5883f582a7b58057), U64_C(0xdbc47e8515f30733), + U64_C(0x190ec4a8d536f915), U64_C(0x9a494faf67707e71), + U64_C(0x0280cfa6acbaeadd), U64_C(0x81c744a11efc6db9), + U64_C(0x2f0fd2b42733df98), U64_C(0xac4859b3957558fc), + U64_C(0x3481d9ba5ebfcc50), U64_C(0xb7c652bdecf94b34), + U64_C(0x47107ddd9b505a38), U64_C(0xc457f6da2916dd5c), + U64_C(0x5c9e76d3e2dc49f0), U64_C(0xdfd9fdd4509ace94), + U64_C(0x71116bc169557cb5), U64_C(0xf256e0c6db13fbd1), + U64_C(0x6a9f60cf10d96f7d), U64_C(0xe9d8ebc8a29fe819), + U64_C(0x2b1251e5625a163f), U64_C(0xa855dae2d01c915b), + U64_C(0x309c5aeb1bd605f7), U64_C(0xb3dbd1eca9908293), + U64_C(0x1d1347f9905f30b2), U64_C(0x9e54ccfe2219b7d6), + U64_C(0x069d4cf7e9d3237a), U64_C(0x85dac7f05b95a41e), + U64_C(0x9f1425ad7444c236), U64_C(0x1c53aeaac6024552), + U64_C(0x849a2ea30dc8d1fe), U64_C(0x07dda5a4bf8e569a), + U64_C(0xa91533b18641e4bb), U64_C(0x2a52b8b6340763df), + U64_C(0xb29b38bfffcdf773), U64_C(0x31dcb3b84d8b7017), + U64_C(0xf31609958d4e8e31), U64_C(0x705182923f080955), + U64_C(0xe898029bf4c29df9), U64_C(0x6bdf899c46841a9d), + U64_C(0xc5171f897f4ba8bc), U64_C(0x4650948ecd0d2fd8), + U64_C(0xde99148706c7bb74), U64_C(0x5dde9f80b4813c10), + U64_C(0xea18cd3d58787724), U64_C(0x695f463aea3ef040), + U64_C(0xf196c63321f464ec), U64_C(0x72d14d3493b2e388), + U64_C(0xdc19db21aa7d51a9), U64_C(0x5f5e5026183bd6cd), + U64_C(0xc797d02fd3f14261), U64_C(0x44d05b2861b7c505), + U64_C(0x861ae105a1723b23), U64_C(0x055d6a021334bc47), + U64_C(0x9d94ea0bd8fe28eb), U64_C(0x1ed3610c6ab8af8f), + U64_C(0xb01bf71953771dae), U64_C(0x335c7c1ee1319aca), + U64_C(0xab95fc172afb0e66), U64_C(0x28d2771098bd8902), + U64_C(0x321c954db76cef2a), U64_C(0xb15b1e4a052a684e), + U64_C(0x29929e43cee0fce2), U64_C(0xaad515447ca67b86), + U64_C(0x041d83514569c9a7), U64_C(0x875a0856f72f4ec3), + U64_C(0x1f93885f3ce5da6f), U64_C(0x9cd403588ea35d0b), + U64_C(0x5e1eb9754e66a32d), U64_C(0xdd593272fc202449), + U64_C(0x4590b27b37eab0e5), U64_C(0xc6d7397c85ac3781), + U64_C(0x681faf69bc6385a0), U64_C(0xeb58246e0e2502c4), + U64_C(0x7391a467c5ef9668), U64_C(0xf0d62f6077a9110c), + U64_C(0x8e20faa72ba0b470), U64_C(0x0d6771a099e63314), + U64_C(0x95aef1a9522ca7b8), U64_C(0x16e97aaee06a20dc), + U64_C(0xb821ecbbd9a592fd), U64_C(0x3b6667bc6be31599), + U64_C(0xa3afe7b5a0298135), U64_C(0x20e86cb2126f0651), + U64_C(0xe222d69fd2aaf877), U64_C(0x61655d9860ec7f13), + U64_C(0xf9acdd91ab26ebbf), U64_C(0x7aeb569619606cdb), + U64_C(0xd423c08320afdefa), U64_C(0x57644b8492e9599e), + U64_C(0xcfadcb8d5923cd32), U64_C(0x4cea408aeb654a56), + U64_C(0x5624a2d7c4b42c7e), U64_C(0xd56329d076f2ab1a), + U64_C(0x4daaa9d9bd383fb6), U64_C(0xceed22de0f7eb8d2), + U64_C(0x6025b4cb36b10af3), U64_C(0xe3623fcc84f78d97), + U64_C(0x7babbfc54f3d193b), U64_C(0xf8ec34c2fd7b9e5f), + U64_C(0x3a268eef3dbe6079), U64_C(0xb96105e88ff8e71d), + U64_C(0x21a885e1443273b1), U64_C(0xa2ef0ee6f674f4d5), + U64_C(0x0c2798f3cfbb46f4), U64_C(0x8f6013f47dfdc190), + U64_C(0x17a993fdb637553c), U64_C(0x94ee18fa0471d258), + U64_C(0x23284a47e888996c), U64_C(0xa06fc1405ace1e08), + U64_C(0x38a6414991048aa4), U64_C(0xbbe1ca4e23420dc0), + U64_C(0x15295c5b1a8dbfe1), U64_C(0x966ed75ca8cb3885), + U64_C(0x0ea757556301ac29), U64_C(0x8de0dc52d1472b4d), + U64_C(0x4f2a667f1182d56b), U64_C(0xcc6ded78a3c4520f), + U64_C(0x54a46d71680ec6a3), U64_C(0xd7e3e676da4841c7), + U64_C(0x792b7063e387f3e6), U64_C(0xfa6cfb6451c17482), + U64_C(0x62a57b6d9a0be02e), U64_C(0xe1e2f06a284d674a), + U64_C(0xfb2c1237079c0162), U64_C(0x786b9930b5da8606), + U64_C(0xe0a219397e1012aa), U64_C(0x63e5923ecc5695ce), + U64_C(0xcd2d042bf59927ef), U64_C(0x4e6a8f2c47dfa08b), + U64_C(0xd6a30f258c153427), U64_C(0x55e484223e53b343), + U64_C(0x972e3e0ffe964d65), U64_C(0x1469b5084cd0ca01), + U64_C(0x8ca03501871a5ead), U64_C(0x0fe7be06355cd9c9), + U64_C(0xa12f28130c936be8), U64_C(0x2268a314bed5ec8c), + U64_C(0xbaa1231d751f7820), U64_C(0x39e6a81ac759ff44), + U64_C(0xc930877ab0f0ee48), U64_C(0x4a770c7d02b6692c), + U64_C(0xd2be8c74c97cfd80), U64_C(0x51f907737b3a7ae4), + U64_C(0xff31916642f5c8c5), U64_C(0x7c761a61f0b34fa1), + U64_C(0xe4bf9a683b79db0d), U64_C(0x67f8116f893f5c69), + U64_C(0xa532ab4249faa24f), U64_C(0x26752045fbbc252b), + U64_C(0xbebca04c3076b187), U64_C(0x3dfb2b4b823036e3), + U64_C(0x9333bd5ebbff84c2), U64_C(0x1074365909b903a6), + U64_C(0x88bdb650c273970a), U64_C(0x0bfa3d577035106e), + U64_C(0x1134df0a5fe47646), U64_C(0x9273540deda2f122), + U64_C(0x0abad4042668658e), U64_C(0x89fd5f03942ee2ea), + U64_C(0x2735c916ade150cb), U64_C(0xa47242111fa7d7af), + U64_C(0x3cbbc218d46d4303), U64_C(0xbffc491f662bc467), + U64_C(0x7d36f332a6ee3a41), U64_C(0xfe71783514a8bd25), + U64_C(0x66b8f83cdf622989), U64_C(0xe5ff733b6d24aeed), + U64_C(0x4b37e52e54eb1ccc), U64_C(0xc8706e29e6ad9ba8), + U64_C(0x50b9ee202d670f04), U64_C(0xd3fe65279f218860), + U64_C(0x6438379a73d8c354), U64_C(0xe77fbc9dc19e4430), + U64_C(0x7fb63c940a54d09c), U64_C(0xfcf1b793b81257f8), + U64_C(0x5239218681dde5d9), U64_C(0xd17eaa81339b62bd), + U64_C(0x49b72a88f851f611), U64_C(0xcaf0a18f4a177175), + U64_C(0x083a1ba28ad28f53), U64_C(0x8b7d90a538940837), + U64_C(0x13b410acf35e9c9b), U64_C(0x90f39bab41181bff), + U64_C(0x3e3b0dbe78d7a9de), U64_C(0xbd7c86b9ca912eba), + U64_C(0x25b506b0015bba16), U64_C(0xa6f28db7b31d3d72), + U64_C(0xbc3c6fea9ccc5b5a), U64_C(0x3f7be4ed2e8adc3e), + U64_C(0xa7b264e4e5404892), U64_C(0x24f5efe35706cff6), + U64_C(0x8a3d79f66ec97dd7), U64_C(0x097af2f1dc8ffab3), + U64_C(0x91b372f817456e1f), U64_C(0x12f4f9ffa503e97b), + U64_C(0xd03e43d265c6175d), U64_C(0x5379c8d5d7809039), + U64_C(0xcbb048dc1c4a0495), U64_C(0x48f7c3dbae0c83f1), + U64_C(0xe63f55ce97c331d0), U64_C(0x6578dec92585b6b4), + U64_C(0xfdb15ec0ee4f2218), U64_C(0x7ef6d5c75c09a57c) }, +}; +static u64 strido (u64 l) +{ + u64 t = 0; + t^= stribog_table[0][(l >> 0) & 255]; + t^= stribog_table[1][(l >> 8) & 255]; + t^= stribog_table[2][(l >> 16) & 255]; + t^= stribog_table[3][(l >> 24) & 255]; + t^= stribog_table[4][(l >> 32) & 255]; + t^= stribog_table[5][(l >> 40) & 255]; + t^= stribog_table[6][(l >> 48) & 255]; + t^= stribog_table[7][(l >> 56) & 255]; + return t; +} +#endif + +static const u64 C16[13][16] = +{ + { U64_C(0xdd806559f2a64507), U64_C(0x05767436cc744d23), + U64_C(0xa2422a08a460d315), U64_C(0x4b7ce09192676901), + U64_C(0x714eb88d7585c4fc), U64_C(0x2f6a76432e45d016), + U64_C(0xebcb2f81c0657c1f), U64_C(0xb1085bda1ecadae9) }, + { U64_C(0xe679047021b19bb7), U64_C(0x55dda21bd7cbcd56), + U64_C(0x5cb561c2db0aa7ca), U64_C(0x9ab5176b12d69958), + U64_C(0x61d55e0f16b50131), U64_C(0xf3feea720a232b98), + U64_C(0x4fe39d460f70b5d7), U64_C(0x6fa3b58aa99d2f1a) }, + { U64_C(0x991e96f50aba0ab2), U64_C(0xc2b6f443867adb31), + U64_C(0xc1c93a376062db09), U64_C(0xd3e20fe490359eb1), + U64_C(0xf2ea7514b1297b7b), U64_C(0x06f15e5f529c1f8b), + U64_C(0x0a39fc286a3d8435), U64_C(0xf574dcac2bce2fc7) }, + { U64_C(0x220cbebc84e3d12e), U64_C(0x3453eaa193e837f1), + U64_C(0xd8b71333935203be), U64_C(0xa9d72c82ed03d675), + U64_C(0x9d721cad685e353f), U64_C(0x488e857e335c3c7d), + U64_C(0xf948e1a05d71e4dd), U64_C(0xef1fdfb3e81566d2) }, + { U64_C(0x601758fd7c6cfe57), U64_C(0x7a56a27ea9ea63f5), + U64_C(0xdfff00b723271a16), U64_C(0xbfcd1747253af5a3), + U64_C(0x359e35d7800fffbd), U64_C(0x7f151c1f1686104a), + U64_C(0x9a3f410c6ca92363), U64_C(0x4bea6bacad474799) }, + { U64_C(0xfa68407a46647d6e), U64_C(0xbf71c57236904f35), + U64_C(0x0af21f66c2bec6b6), U64_C(0xcffaa6b71c9ab7b4), + U64_C(0x187f9ab49af08ec6), U64_C(0x2d66c4f95142a46c), + U64_C(0x6fa4c33b7a3039c0), U64_C(0xae4faeae1d3ad3d9) }, + { U64_C(0x8886564d3a14d493), U64_C(0x3517454ca23c4af3), + U64_C(0x06476983284a0504), U64_C(0x0992abc52d822c37), + U64_C(0xd3473e33197a93c9), U64_C(0x399ec6c7e6bf87c9), + U64_C(0x51ac86febf240954), U64_C(0xf4c70e16eeaac5ec) }, + { U64_C(0xa47f0dd4bf02e71e), U64_C(0x36acc2355951a8d9), + U64_C(0x69d18d2bd1a5c42f), U64_C(0xf4892bcb929b0690), + U64_C(0x89b4443b4ddbc49a), U64_C(0x4eb7f8719c36de1e), + U64_C(0x03e7aa020c6e4141), U64_C(0x9b1f5b424d93c9a7) }, + { U64_C(0x7261445183235adb), U64_C(0x0e38dc92cb1f2a60), + U64_C(0x7b2b8a9aa6079c54), U64_C(0x800a440bdbb2ceb1), + U64_C(0x3cd955b7e00d0984), U64_C(0x3a7d3a1b25894224), + U64_C(0x944c9ad8ec165fde), U64_C(0x378f5a541631229b) }, + { U64_C(0x74b4c7fb98459ced), U64_C(0x3698fad1153bb6c3), + U64_C(0x7a1e6c303b7652f4), U64_C(0x9fe76702af69334b), + U64_C(0x1fffe18a1b336103), U64_C(0x8941e71cff8a78db), + U64_C(0x382ae548b2e4f3f3), U64_C(0xabbedea680056f52) }, + { U64_C(0x6bcaa4cd81f32d1b), U64_C(0xdea2594ac06fd85d), + U64_C(0xefbacd1d7d476e98), U64_C(0x8a1d71efea48b9ca), + U64_C(0x2001802114846679), U64_C(0xd8fa6bbbebab0761), + U64_C(0x3002c6cd635afe94), U64_C(0x7bcd9ed0efc889fb) }, + { U64_C(0x48bc924af11bd720), U64_C(0xfaf417d5d9b21b99), + U64_C(0xe71da4aa88e12852), U64_C(0x5d80ef9d1891cc86), + U64_C(0xf82012d430219f9b), U64_C(0xcda43c32bcdf1d77), + U64_C(0xd21380b00449b17a), U64_C(0x378ee767f11631ba) }, +}; + + +static void LPSX (u64 *out, u64 *a, const u64 *b) +{ + int i; + u64 temp[8]; + for (i = 0; i < 8; i++) + temp[i] = a[i] ^ b[i]; + for (i = 0; i < 8; i++) + { + u64 l = + ((u64) Pi[ (temp[7] >> (i * 8)) & 0xff] << (7 * 8)) | + ((u64) Pi[ (temp[6] >> (i * 8)) & 0xff] << (6 * 8)) | + ((u64) Pi[ (temp[5] >> (i * 8)) & 0xff] << (5 * 8)) | + ((u64) Pi[ (temp[4] >> (i * 8)) & 0xff] << (4 * 8)) | + ((u64) Pi[ (temp[3] >> (i * 8)) & 0xff] << (3 * 8)) | + ((u64) Pi[ (temp[2] >> (i * 8)) & 0xff] << (2 * 8)) | + ((u64) Pi[ (temp[1] >> (i * 8)) & 0xff] << (1 * 8)) | + ((u64) Pi[ (temp[0] >> (i * 8)) & 0xff] << (0 * 8)) | + 0; + + out[i] = strido(l); + } +} + +static void xor (u64 *out, u64 *in) +{ + int i; + for (i = 0; i < 8; i++) + out[i] ^= in[i]; +} + + +static void g (u64 *h, u64 *m, u64 *N) +{ + u64 K[8]; + u64 T[8]; + int i; + + LPSX (K, h, N); + + for (i = 0; i < 12; i++) + { + LPSX (T, K, i == 0 ? m : T); + LPSX (K, K, C16[i]); + } + xor (T, K); + xor (T, m); + xor (h, T); +} + + +static void +stribog_init_512 (void *context) +{ + STRIBOG_CONTEXT *hd = context; + + memset (hd, 0, sizeof (*hd)); +} + +static void +stribog_init_256 (void *context) +{ + STRIBOG_CONTEXT *hd = context; + stribog_init_512 (context); + memset (hd->h, 1, 64); +} + +static void +transform (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) +{ + u64 M[8]; + u64 l; + int i; + +#ifndef WORDS_BIGENDIAN + memcpy (M, data, 64); +#else + { + byte *p2; + + for (i = 0, p2 = (byte *) M; i < 8; i++, p2 += 8) + { + p2[7] = *data++; + p2[6] = *data++; + p2[5] = *data++; + p2[4] = *data++; + p2[3] = *data++; + p2[2] = *data++; + p2[1] = *data++; + p2[0] = *data++; + } + } +#endif + + g (hd->h, M, hd->N); + l = hd->N[0]; + hd->N[0] += count; + if (hd->N[0] < l) + { /* overflow */ + for (i = 1; i < 8; i++) + { + hd->N[i]++; + if (hd->N[i] != 0) + break; + } + } + + hd->Sigma[0] += M[0]; + for (i = 1; i < 8; i++) + if (hd->Sigma[i-1] < M[i-1]) + hd->Sigma[i] += M[i] + 1; + else + hd->Sigma[i] += M[i]; +} + +static void +stribog_write (void *context, const void *inbuf_arg, size_t inlen) +{ + STRIBOG_CONTEXT *hd = context; + const unsigned char *inbuf = inbuf_arg; + if (hd->count == 64) + { + transform (hd, hd->buf, hd->count * 8); + hd->count = 0; + _gcry_burn_stack (768); + } + if (!inbuf) + return; + if (hd->count) + { + for (; inlen && hd->count < 64; inlen--) + hd->buf[hd->count++] = *inbuf++; + stribog_write (context, NULL, 0); + if (!inlen) + return; + } + while (inlen >= 64) + { + transform (hd, inbuf, 64 * 8); + inlen -= 64; + inbuf += 64; + } + _gcry_burn_stack (768); + for (; inlen && hd->count < 64; inlen--) + hd->buf[hd->count++] = *inbuf++; +} + +/* + The routine finally terminates the computation and returns the + digest. The handle is prepared for a new cycle, but adding bytes + to the handle will the destroy the returned buffer. Returns: 32 + bytes with the message the digest. */ +static void +stribog_final (void *context) +{ + STRIBOG_CONTEXT *hd = context; + u64 Z[8] = {}; + int i; + + stribog_write (context, NULL, 0); /* flush */ ; + /* PAD. It does not count towards message length */ + i = hd->count; + /* After flush we have at least one byte free) */ + hd->buf[i++] = 1; + while (i < 64) + hd->buf[i++] = 0; + transform (hd, hd->buf, hd->count * 8); + + g (hd->h, hd->N, Z); + g (hd->h, hd->Sigma, Z); + _gcry_burn_stack (768); +} + +static byte * +stribog_read_512 (void *context) +{ + STRIBOG_CONTEXT *hd = context; + + return hd->result; +} + +static byte * +stribog_read_256 (void *context) +{ + STRIBOG_CONTEXT *hd = context; + + return hd->result + 32; +} + +gcry_md_spec_t _gcry_digest_spec_stribog_256 = + { + "STRIBOG256", NULL, 0, NULL, 32, + stribog_init_256, stribog_write, stribog_final, stribog_read_256, + sizeof (STRIBOG_CONTEXT) + }; + +gcry_md_spec_t _gcry_digest_spec_stribog_512 = + { + "STRIBOG512", NULL, 0, NULL, 64, + stribog_init_512, stribog_write, stribog_final, stribog_read_512, + sizeof (STRIBOG_CONTEXT) + }; diff --git a/configure.ac b/configure.ac index 0abfa79..6529c3a 100644 --- a/configure.ac +++ b/configure.ac @@ -193,7 +193,7 @@ enabled_pubkey_ciphers="" # Definitions for message digests. available_digests="crc gostr3411-94 md4 md5 rmd160 sha1 sha256" -available_digests_64="sha512 tiger whirlpool" +available_digests_64="sha512 tiger whirlpool stribog" enabled_digests="" # Definitions for kdfs (optional ones) @@ -354,7 +354,7 @@ if test "$ac_cv_sizeof_unsigned_int" != "8" \ && test "$ac_cv_sizeof_unsigned_long_long" != "8" \ && test "$ac_cv_sizeof_uint64_t" != "8"; then AC_MSG_WARN([No 64-bit types. Disabling TIGER/192, SCRYPT, SHA-384, \ - and SHA-512]) + SHA-512 and GOST R 34.11-12]) else available_digests="$available_digests $available_digests_64" available_kdfs="$available_kdfs $available_kdfs_64" @@ -1520,6 +1520,12 @@ if test "$found" = "1" ; then fi fi +LIST_MEMBER(stribog, $enabled_digests) +if test "$found" = "1" ; then + GCRYPT_DIGESTS="$GCRYPT_DIGESTS stribog.lo" + AC_DEFINE(USE_GOST_R_3411_12, 1, [Defined if this module should be included]) +fi + LIST_MEMBER(md4, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo" diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 3d16713..4b0b30b 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -2946,6 +2946,14 @@ bytes. This is the hash algorithm described in GOST R 34.11-94. It yields message digest of 32 bytes. + at item GCRY_MD_GOSTR3411_12_256 +This is the 256-bit version of hash algorithm described in GOST R 34.11-2012 +which yields message digests of 32 bytes. + + at item GCRY_MD_GOSTR3411_12_512 +This is the 512-bit version of hash algorithm described in GOST R 34.11-2012 +which yields message digests of 64 bytes. + @end table @c end table of hash algorithms diff --git a/src/cipher.h b/src/cipher.h index 1787a5e..1dc4d4e 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -209,6 +209,8 @@ extern gcry_md_spec_t _gcry_digest_spec_crc32; extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510; extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; extern gcry_md_spec_t _gcry_digest_spec_gost3411_94; +extern gcry_md_spec_t _gcry_digest_spec_stribog_256; +extern gcry_md_spec_t _gcry_digest_spec_stribog_512; extern gcry_md_spec_t _gcry_digest_spec_md4; extern gcry_md_spec_t _gcry_digest_spec_md5; extern gcry_md_spec_t _gcry_digest_spec_rmd160; diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 88286c6..8632ed1 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1067,6 +1067,8 @@ enum gcry_md_algos GCRY_MD_TIGER1 = 306, /* TIGER fixed. */ GCRY_MD_TIGER2 = 307, /* TIGER2 variant. */ GCRY_MD_GOSTR3411_94 = 308, /* GOST R 34.11-94. */ + GCRY_MD_GOSTR3411_12_256 = 309, /* GOST R 34.11-2012, 256 bit */ + GCRY_MD_GOSTR3411_12_512 = 310, /* GOST R 34.11-2012, 512 bit */ }; /* Flags used with the open function. */ diff --git a/tests/basic.c b/tests/basic.c index fc2e494..c851eb9 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -2550,6 +2550,36 @@ check_digests (void) "\x5C\x00\xCC\xC2\x73\x4C\xDD\x33\x32\xD3\xD4\x74\x95\x76\xE3\xC1" "\xA7\xDB\xAF\x0E\x7E\xA7\x4E\x9F\xA6\x02\x41\x3C\x90\xA1\x29\xFA" }, #endif +#ifdef USE_GOST_R_3411_12 + { GCRY_MD_GOSTR3411_12_512, + "012345678901234567890123456789012345678901234567890123456789012", + "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5\xcc\x3d\x86\xd6\x8d\x28\x54\x62" + "\xb1\x9a\xbc\x24\x75\x22\x2f\x35\xc0\x85\x12\x2b\xe4\xba\x1f\xfa" + "\x00\xad\x30\xf8\x76\x7b\x3a\x82\x38\x4c\x65\x74\xf0\x24\xc3\x11" + "\xe2\xa4\x81\x33\x2b\x08\xef\x7f\x41\x79\x78\x91\xc1\x64\x6f\x48" }, + { GCRY_MD_GOSTR3411_12_256, + "012345678901234567890123456789012345678901234567890123456789012", + "\x9d\x15\x1e\xef\xd8\x59\x0b\x89\xda\xa6\xba\x6c\xb7\x4a\xf9\x27" + "\x5d\xd0\x51\x02\x6b\xb1\x49\xa4\x52\xfd\x84\xe5\xe5\x7b\x55\x00" }, + { GCRY_MD_GOSTR3411_12_512, + "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee" + "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20" + "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20" + "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb" + "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", + "\x1e\x88\xe6\x22\x26\xbf\xca\x6f\x99\x94\xf1\xf2\xd5\x15\x69\xe0" + "\xda\xf8\x47\x5a\x3b\x0f\xe6\x1a\x53\x00\xee\xe4\x6d\x96\x13\x76" + "\x03\x5f\xe8\x35\x49\xad\xa2\xb8\x62\x0f\xcd\x7c\x49\x6c\xe5\xb3" + "\x3f\x0c\xb9\xdd\xdc\x2b\x64\x60\x14\x3b\x03\xda\xba\xc9\xfb\x28" }, + { GCRY_MD_GOSTR3411_12_256, + "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee" + "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20" + "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20" + "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb" + "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", + "\x9d\xd2\xfe\x4e\x90\x40\x9e\x5d\xa8\x7f\x53\x97\x6d\x74\x05\xb0" + "\xc0\xca\xc6\x28\xfc\x66\x9a\x74\x1d\x50\x06\x3c\x55\x7e\x8f\x50" }, +#endif { 0 }, }; int i; -- 1.8.4.rc3 From jussi.kivilinna at iki.fi Tue Sep 3 19:18:29 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 03 Sep 2013 20:18:29 +0300 Subject: [PATCH 2/2] Make _gcry_burn_stack use variable length array In-Reply-To: <20130903171824.13479.98973.stgit@localhost6.localdomain6> References: <20130903171824.13479.98973.stgit@localhost6.localdomain6> Message-ID: <20130903171829.13479.57523.stgit@localhost6.localdomain6> * configure.ac (HAVE_VLA): Add check. * src/misc.c (_gcry_burn_stack) [HAVE_VLA]: Add VLA code. -- Some gcc versions convert _gcry_burn_stack into loop that overwrites the same 64-byte stack buffer instead of burn stack deeper. It's mentioned in GCC bugzilla that _gcry_burn_stack is doing wrong thing here [1] and that this kind of optimization is allowed. So lets fix _gcry_burn_stack by using variable length array when VLAs are supported by compiler. This should ensure proper stack burning to the requested depth and avoid GCC loop optimizations. [1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52285 Signed-off-by: Jussi Kivilinna --- configure.ac | 18 ++++++++++++++++++ src/misc.c | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/configure.ac b/configure.ac index 959327a..993577b 100644 --- a/configure.ac +++ b/configure.ac @@ -764,6 +764,24 @@ case "${host}" in esac AC_SUBST(FALLBACK_SOCKLEN_T) + +# +# Check for VLA support (variable length arrays). +# +AC_CACHE_CHECK(whether the variable length arrays are supported, + [gcry_cv_have_vla], + [gcry_cv_have_vla=no + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [[void f1(char *, int); + char foo(int i) { + char b[(i < 0 ? 0 : i) + 1]; + f1(b, sizeof b); return b[0];}]])], + [gcry_cv_have_vla=yes])]) +if test "$gcry_cv_have_vla" = "yes" ; then + AC_DEFINE(HAVE_VLA,1, [Defined if variable length arrays are supported]) +fi + + # # Check for ELF visibility support. # diff --git a/src/misc.c b/src/misc.c index 2d9c73a..97de322 100644 --- a/src/misc.c +++ b/src/misc.c @@ -290,6 +290,12 @@ _gcry_log_printhex (const char *text, const void *buffer, size_t length) void _gcry_burn_stack (int bytes) { +#ifdef HAVE_VLA + int buflen = (((bytes <= 0) ? 1 : bytes) + 63) & ~63; + char buf[buflen]; + + wipememory (buf, sizeof buf); +#else char buf[64]; wipememory (buf, sizeof buf); @@ -297,6 +303,7 @@ _gcry_burn_stack (int bytes) bytes -= sizeof buf; if (bytes > 0) _gcry_burn_stack (bytes); +#endif } void From jussi.kivilinna at iki.fi Tue Sep 3 19:18:24 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 03 Sep 2013 20:18:24 +0300 Subject: [PATCH 1/2] Move stack burning from block ciphers to cipher modes Message-ID: <20130903171824.13479.98973.stgit@localhost6.localdomain6> * src/gcrypt-module.h (gcry_cipher_encrypt_t) (gcry_cipher_decrypt_t): Return 'unsigned int'. * cipher/cipher.c (dummy_encrypt_block, dummy_decrypt_block): Return zero. (do_ecb_encrypt, do_ecb_decrypt): Get largest stack burn depth from block cipher crypt function and burn stack at end. * cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt) (_gcry_cipher_aeswrap_decrypt): Ditto. * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt) (_gcry_cipher_cbc_decrypt): Ditto. * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt) (_gcry_cipher_cfb_decrypt): Ditto. * cipher/cipher-ctr.c (_gcry_cipher_cbc_encrypt): Ditto. * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt) (_gcry_cipher_ofb_decrypt): Ditto. * cipher/blowfish.c (encrypt_block, decrypt_block): Return burn stack depth. * cipher/camellia-glue.c (camellia_encrypt, camellia_decrypt): Ditto. * cipher/cast5.c (encrypt_block, decrypt_block): Ditto. * cipher/des.c (do_tripledes_encrypt, do_tripledes_decrypt) (do_des_encrypt, do_des_decrypt): Ditto. * cipher/idea.c (idea_encrypt, idea_decrypt): Ditto. * cipher/rijndael.c (rijndael_encrypt, rijndael_decrypt): Ditto. * cipher/seed.c (seed_encrypt, seed_decrypt): Ditto. * cipher/serpent.c (serpent_encrypt, serpent_decrypt): Ditto. * cipher/twofish.c (twofish_encrypt, twofish_decrypt): Ditto. * cipher/rfc2268.c (encrypt_block, decrypt_block): New. (_gcry_cipher_spec_rfc2268_40): Use encrypt_block and decrypt_block. -- Patch moves stack burning from block ciphers and cipher mode loop to end of cipher mode functions. This greatly reduces the overall CPU usage of the problematic _gcry_burn_stack. Internal cipher module API is changed so that encrypt/decrypt functions now return the stack burn depth as unsigned int to cipher mode function. (Note, patch also adds missing burn_stack for RFC2268_40 cipher). _gcry_burn_stack CPU time (looping tests/benchmark cipher blowfish): arch CPU Old New i386 Intel-Haswell 4.1% 0.16% x86_64 Intel-Haswell 3.4% 0.07% armhf Cortex-A8 8.7% 0.14% New vs. old (armhf/Cortex-A8): ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- IDEA 1.05x 1.05x 1.04x 1.04x 1.04x 1.04x 1.07x 1.05x 1.04x 1.04x 3DES 1.04x 1.03x 1.04x 1.03x 1.04x 1.04x 1.04x 1.04x 1.04x 1.04x CAST5 1.19x 1.20x 1.15x 1.00x 1.17x 1.00x 1.15x 1.05x 1.00x 1.00x BLOWFISH 1.21x 1.22x 1.16x 1.00x 1.18x 1.00x 1.16x 1.16x 1.00x 1.00x AES 1.09x 1.09x 1.00x 1.00x 1.00x 1.00x 1.07x 1.07x 1.00x 1.00x AES192 1.11x 1.11x 1.00x 1.00x 1.00x 1.00x 1.08x 1.09x 1.01x 1.00x AES256 1.07x 1.08x 1.01x .99x 1.00x 1.00x 1.07x 1.06x 1.00x 1.00x TWOFISH 1.10x 1.09x 1.09x 1.00x 1.09x 1.00x 1.08x 1.09x 1.00x 1.00x ARCFOUR 1.00x 1.00x DES 1.07x 1.11x 1.06x 1.08x 1.07x 1.07x 1.06x 1.06x 1.06x 1.06x TWOFISH128 1.10x 1.10x 1.09x 1.00x 1.09x 1.00x 1.08x 1.08x 1.00x 1.00x SERPENT128 1.06x 1.07x 1.02x 1.00x 1.06x 1.00x 1.06x 1.05x 1.00x 1.00x SERPENT192 1.07x 1.06x 1.03x 1.00x 1.06x 1.00x 1.06x 1.05x 1.00x 1.00x SERPENT256 1.06x 1.07x 1.02x 1.00x 1.06x 1.00x 1.05x 1.06x 1.00x 1.00x RFC2268_40 0.97x 1.01x 0.99x 0.98x 1.00x 0.97x 0.96x 0.96x 0.97x 0.97x SEED 1.45x 1.54x 1.53x 1.56x 1.50x 1.51x 1.50x 1.50x 1.42x 1.42x CAMELLIA128 1.08x 1.07x 1.06x 1.00x 1.07x 1.00x 1.06x 1.06x 1.00x 1.00x CAMELLIA192 1.08x 1.08x 1.08x 1.00x 1.07x 1.00x 1.07x 1.07x 1.00x 1.00x CAMELLIA256 1.08x 1.09x 1.07x 1.01x 1.08x 1.00x 1.07x 1.07x 1.00x 1.00x SALSA20 .99x 1.00x Raw data: New (armhf/Cortex-A8): Running each test 100 times. ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- IDEA 8620ms 8680ms 9640ms 10010ms 9140ms 8960ms 9630ms 9660ms 9180ms 9180ms 3DES 13990ms 14000ms 14780ms 15300ms 14320ms 14370ms 14780ms 14780ms 14480ms 14480ms CAST5 2980ms 2980ms 3780ms 2300ms 3290ms 2320ms 3770ms 4100ms 2320ms 2320ms BLOWFISH 2740ms 2660ms 3530ms 2060ms 3050ms 2080ms 3530ms 3530ms 2070ms 2070ms AES 2200ms 2330ms 2330ms 2450ms 2270ms 2270ms 2700ms 2690ms 2330ms 2320ms AES192 2550ms 2670ms 2700ms 2910ms 2630ms 2640ms 3060ms 3060ms 2680ms 2690ms AES256 2920ms 3010ms 3040ms 3190ms 3010ms 3000ms 3380ms 3420ms 3050ms 3050ms TWOFISH 2790ms 2840ms 3300ms 2950ms 3010ms 2870ms 3310ms 3280ms 2940ms 2940ms ARCFOUR 2050ms 2050ms DES 5640ms 5630ms 6440ms 6970ms 5960ms 6000ms 6440ms 6440ms 6120ms 6120ms TWOFISH128 2790ms 2840ms 3300ms 2950ms 3010ms 2890ms 3310ms 3290ms 2930ms 2930ms SERPENT128 4530ms 4340ms 5210ms 4470ms 4740ms 4620ms 5020ms 5030ms 4680ms 4680ms SERPENT192 4510ms 4340ms 5190ms 4460ms 4750ms 4620ms 5020ms 5030ms 4680ms 4680ms SERPENT256 4540ms 4330ms 5220ms 4460ms 4730ms 4600ms 5030ms 5020ms 4680ms 4680ms RFC2268_40 10530ms 7790ms 11140ms 9490ms 10650ms 10710ms 11710ms 11690ms 11000ms 11000ms SEED 4530ms 4540ms 5050ms 5380ms 4760ms 4810ms 5060ms 5060ms 4850ms 4860ms CAMELLIA128 2660ms 2630ms 3170ms 2750ms 2880ms 2740ms 3170ms 3170ms 2780ms 2780ms CAMELLIA192 3430ms 3400ms 3930ms 3530ms 3650ms 3500ms 3940ms 3940ms 3570ms 3560ms CAMELLIA256 3430ms 3390ms 3940ms 3500ms 3650ms 3510ms 3930ms 3940ms 3550ms 3550ms SALSA20 1910ms 1900ms Old (armhf/Cortex-A8): Running each test 100 times. ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- IDEA 9030ms 9100ms 10050ms 10410ms 9540ms 9360ms 10350ms 10190ms 9560ms 9570ms 3DES 14580ms 14460ms 15300ms 15720ms 14880ms 14900ms 15350ms 15330ms 15030ms 15020ms CAST5 3560ms 3570ms 4350ms 2300ms 3860ms 2330ms 4340ms 4320ms 2330ms 2320ms BLOWFISH 3320ms 3250ms 4110ms 2060ms 3610ms 2080ms 4100ms 4090ms 2070ms 2070ms AES 2390ms 2530ms 2320ms 2460ms 2280ms 2270ms 2890ms 2880ms 2330ms 2330ms AES192 2830ms 2970ms 2690ms 2900ms 2630ms 2650ms 3320ms 3330ms 2700ms 2690ms AES256 3110ms 3250ms 3060ms 3170ms 3000ms 3000ms 3610ms 3610ms 3050ms 3060ms TWOFISH 3080ms 3100ms 3600ms 2940ms 3290ms 2880ms 3560ms 3570ms 2940ms 2930ms ARCFOUR 2060ms 2050ms DES 6060ms 6230ms 6850ms 7540ms 6380ms 6400ms 6830ms 6840ms 6500ms 6510ms TWOFISH128 3060ms 3110ms 3600ms 2940ms 3290ms 2890ms 3560ms 3560ms 2940ms 2930ms SERPENT128 4820ms 4630ms 5330ms 4460ms 5030ms 4620ms 5300ms 5300ms 4680ms 4680ms SERPENT192 4830ms 4620ms 5320ms 4460ms 5040ms 4620ms 5300ms 5300ms 4680ms 4680ms SERPENT256 4820ms 4640ms 5330ms 4460ms 5030ms 4620ms 5300ms 5300ms 4680ms 4660ms RFC2268_40 10260ms 7850ms 11080ms 9270ms 10620ms 10380ms 11250ms 11230ms 10690ms 10710ms SEED 6580ms 6990ms 7710ms 8370ms 7140ms 7240ms 7600ms 7610ms 6870ms 6900ms CAMELLIA128 2860ms 2820ms 3360ms 2750ms 3080ms 2740ms 3350ms 3360ms 2790ms 2790ms CAMELLIA192 3710ms 3680ms 4240ms 3520ms 3910ms 3510ms 4200ms 4210ms 3560ms 3560ms CAMELLIA256 3700ms 3680ms 4230ms 3520ms 3930ms 3510ms 4200ms 4210ms 3550ms 3560ms SALSA20 1900ms 1900ms Signed-off-by: Jussi Kivilinna --- cipher/blowfish.c | 32 ++++++++++++++++++-------------- cipher/camellia-glue.c | 16 ++++++++-------- cipher/cast5.c | 32 ++++++++++++++++++-------------- cipher/cipher-aeswrap.c | 19 +++++++++++++++++-- cipher/cipher-cbc.c | 27 ++++++++++++++++++++++----- cipher/cipher-cfb.c | 32 ++++++++++++++++++++++++++------ cipher/cipher-ctr.c | 10 ++++++++-- cipher/cipher-ofb.c | 26 ++++++++++++++++++++++---- cipher/cipher.c | 24 ++++++++++++++++++++---- cipher/des.c | 16 ++++++++-------- cipher/idea.c | 8 ++++---- cipher/rfc2268.c | 16 +++++++++++++++- cipher/rijndael.c | 20 ++++++++++++++------ cipher/seed.c | 8 ++++---- cipher/serpent.c | 8 ++++---- cipher/twofish.c | 16 ++++++++-------- src/gcrypt-module.h | 12 ++++++------ 17 files changed, 222 insertions(+), 100 deletions(-) diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 2806433..80e1ec7 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -67,8 +67,8 @@ typedef struct { } BLOWFISH_context; static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen); -static void encrypt_block (void *bc, byte *outbuf, const byte *inbuf); -static void decrypt_block (void *bc, byte *outbuf, const byte *inbuf); +static unsigned int encrypt_block (void *bc, byte *outbuf, const byte *inbuf); +static unsigned int decrypt_block (void *bc, byte *outbuf, const byte *inbuf); /* precomputed S boxes */ @@ -298,18 +298,20 @@ do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf) _gcry_blowfish_amd64_decrypt_block (context, outbuf, inbuf); } -static void encrypt_block (void *context , byte *outbuf, const byte *inbuf) +static unsigned int +encrypt_block (void *context , byte *outbuf, const byte *inbuf) { BLOWFISH_context *c = (BLOWFISH_context *) context; do_encrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (2*8); + return /*burn_stack*/ (2*8); } -static void decrypt_block (void *context, byte *outbuf, const byte *inbuf) +static unsigned int +decrypt_block (void *context, byte *outbuf, const byte *inbuf) { BLOWFISH_context *c = (BLOWFISH_context *) context; do_decrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (2*8); + return /*burn_stack*/ (2*8); } #elif defined(USE_ARMV6_ASM) @@ -352,18 +354,20 @@ do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf) _gcry_blowfish_armv6_decrypt_block (context, outbuf, inbuf); } -static void encrypt_block (void *context , byte *outbuf, const byte *inbuf) +static unsigned int +encrypt_block (void *context , byte *outbuf, const byte *inbuf) { BLOWFISH_context *c = (BLOWFISH_context *) context; do_encrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (10*4); + return /*burn_stack*/ (10*4); } -static void decrypt_block (void *context, byte *outbuf, const byte *inbuf) +static unsigned int +decrypt_block (void *context, byte *outbuf, const byte *inbuf) { BLOWFISH_context *c = (BLOWFISH_context *) context; do_decrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (10*4); + return /*burn_stack*/ (10*4); } #else /*USE_ARMV6_ASM*/ @@ -553,12 +557,12 @@ do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf ) outbuf[7] = d2 & 0xff; } -static void +static unsigned int encrypt_block (void *context, byte *outbuf, const byte *inbuf) { BLOWFISH_context *bc = (BLOWFISH_context *) context; do_encrypt_block (bc, outbuf, inbuf); - _gcry_burn_stack (64); + return /*burn_stack*/ (64); } @@ -580,12 +584,12 @@ do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf) outbuf[7] = d2 & 0xff; } -static void +static unsigned int decrypt_block (void *context, byte *outbuf, const byte *inbuf) { BLOWFISH_context *bc = (BLOWFISH_context *) context; do_decrypt_block (bc, outbuf, inbuf); - _gcry_burn_stack (64); + return /*burn_stack*/ (64); } #endif /*!USE_AMD64_ASM&&!USE_ARMV6_ASM*/ diff --git a/cipher/camellia-glue.c b/cipher/camellia-glue.c index 6e2319d..ad57cf5 100644 --- a/cipher/camellia-glue.c +++ b/cipher/camellia-glue.c @@ -222,27 +222,27 @@ static void Camellia_DecryptBlock(const int keyBitLength, keyBitLength); } -static void +static unsigned int camellia_encrypt(void *c, byte *outbuf, const byte *inbuf) { CAMELLIA_context *ctx = c; Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); #define CAMELLIA_encrypt_stack_burn_size (15*4) - _gcry_burn_stack(CAMELLIA_encrypt_stack_burn_size); + return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size); } -static void +static unsigned int camellia_decrypt(void *c, byte *outbuf, const byte *inbuf) { CAMELLIA_context *ctx=c; Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); #define CAMELLIA_decrypt_stack_burn_size (15*4) - _gcry_burn_stack(CAMELLIA_decrypt_stack_burn_size); + return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size); } #else /*USE_ARMV6_ASM*/ -static void +static unsigned int camellia_encrypt(void *c, byte *outbuf, const byte *inbuf) { CAMELLIA_context *ctx=c; @@ -256,10 +256,10 @@ camellia_encrypt(void *c, byte *outbuf, const byte *inbuf) +2*2*sizeof(void*) /* Function calls. */ \ ) - _gcry_burn_stack(CAMELLIA_encrypt_stack_burn_size); + return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size); } -static void +static unsigned int camellia_decrypt(void *c, byte *outbuf, const byte *inbuf) { CAMELLIA_context *ctx=c; @@ -273,7 +273,7 @@ camellia_decrypt(void *c, byte *outbuf, const byte *inbuf) +2*2*sizeof(void*) /* Function calls. */ \ ) - _gcry_burn_stack(CAMELLIA_decrypt_stack_burn_size); + return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size); } #endif /*!USE_ARMV6_ASM*/ diff --git a/cipher/cast5.c b/cipher/cast5.c index 4377c28..0cd5953 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -71,8 +71,8 @@ typedef struct { } CAST5_context; static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen); -static void encrypt_block (void *c, byte *outbuf, const byte *inbuf); -static void decrypt_block (void *c, byte *outbuf, const byte *inbuf); +static unsigned int encrypt_block (void *c, byte *outbuf, const byte *inbuf); +static unsigned int decrypt_block (void *c, byte *outbuf, const byte *inbuf); @@ -383,18 +383,20 @@ do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf) _gcry_cast5_amd64_decrypt_block (context, outbuf, inbuf); } -static void encrypt_block (void *context , byte *outbuf, const byte *inbuf) +static unsigned int +encrypt_block (void *context , byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_encrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (2*8); + return /*burn_stack*/ (2*8); } -static void decrypt_block (void *context, byte *outbuf, const byte *inbuf) +static unsigned int +decrypt_block (void *context, byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; _gcry_cast5_amd64_decrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (2*8); + return /*burn_stack*/ (2*8); } #elif defined(USE_ARMV6_ASM) @@ -428,18 +430,20 @@ do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf) _gcry_cast5_armv6_decrypt_block (context, outbuf, inbuf); } -static void encrypt_block (void *context , byte *outbuf, const byte *inbuf) +static unsigned int +encrypt_block (void *context , byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_encrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (10*4); + return /*burn_stack*/ (10*4); } -static void decrypt_block (void *context, byte *outbuf, const byte *inbuf) +static unsigned int +decrypt_block (void *context, byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_decrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (10*4); + return /*burn_stack*/ (10*4); } #else /*USE_ARMV6_ASM*/ @@ -519,12 +523,12 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf ) outbuf[7] = l & 0xff; } -static void +static unsigned int encrypt_block (void *context , byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_encrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (20+4*sizeof(void*)); + return /*burn_stack*/ (20+4*sizeof(void*)); } @@ -569,12 +573,12 @@ do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf ) outbuf[7] = l & 0xff; } -static void +static unsigned int decrypt_block (void *context, byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_decrypt_block (c, outbuf, inbuf); - _gcry_burn_stack (20+4*sizeof(void*)); + return /*burn_stack*/ (20+4*sizeof(void*)); } #endif /*!USE_ARMV6_ASM*/ diff --git a/cipher/cipher-aeswrap.c b/cipher/cipher-aeswrap.c index 8e117eb..931dec1 100644 --- a/cipher/cipher-aeswrap.c +++ b/cipher/cipher-aeswrap.c @@ -42,6 +42,7 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, unsigned int n, i; unsigned char *r, *a, *b; unsigned char t[8]; + unsigned int burn, nburn; #if MAX_BLOCKSIZE < 8 #error Invalid block size @@ -64,6 +65,8 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, if (n < 2) return GPG_ERR_INV_ARG; + burn = 0; + r = outbuf; a = outbuf; /* We store A directly in OUTBUF. */ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */ @@ -87,7 +90,8 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, /* B := AES_k( A | R[i] ) */ memcpy (b, a, 8); memcpy (b+8, r+i*8, 8); - c->cipher->encrypt (&c->context.c, b, b); + nburn = c->cipher->encrypt (&c->context.c, b, b); + burn = nburn > burn ? nburn : burn; /* t := t + 1 */ for (x = 7; x >= 0; x--) { @@ -102,6 +106,9 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, } } + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } @@ -117,6 +124,7 @@ _gcry_cipher_aeswrap_decrypt (gcry_cipher_hd_t c, unsigned int n, i; unsigned char *r, *a, *b; unsigned char t[8]; + unsigned int burn, nburn; #if MAX_BLOCKSIZE < 8 #error Invalid block size @@ -140,6 +148,8 @@ _gcry_cipher_aeswrap_decrypt (gcry_cipher_hd_t c, if (n < 3) return GPG_ERR_INV_ARG; + burn = 0; + r = outbuf; a = c->lastiv; /* We use c->LASTIV as buffer for A. */ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */ @@ -163,7 +173,8 @@ _gcry_cipher_aeswrap_decrypt (gcry_cipher_hd_t c, /* B := AES_k^1( (A ^ t)| R[i] ) */ buf_xor(b, a, t, 8); memcpy (b+8, r+(i-1)*8, 8); - c->cipher->decrypt (&c->context.c, b, b); + nburn = c->cipher->decrypt (&c->context.c, b, b); + burn = nburn > burn ? nburn : burn; /* t := t - 1 */ for (x = 7; x >= 0; x--) { @@ -191,5 +202,9 @@ _gcry_cipher_aeswrap_decrypt (gcry_cipher_hd_t c, break; } } + + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return j? GPG_ERR_CHECKSUM : 0; } diff --git a/cipher/cipher-cbc.c b/cipher/cipher-cbc.c index 0d30f63..55a1c74 100644 --- a/cipher/cipher-cbc.c +++ b/cipher/cipher-cbc.c @@ -42,6 +42,7 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c, int i; size_t blocksize = c->cipher->blocksize; unsigned nblocks = inbuflen / blocksize; + unsigned int burn, nburn; if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen)) return GPG_ERR_BUFFER_TOO_SHORT; @@ -51,6 +52,8 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c, && (c->flags & GCRY_CIPHER_CBC_CTS))) return GPG_ERR_INV_LENGTH; + burn = 0; + if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) { if ((inbuflen % blocksize) == 0) @@ -70,7 +73,8 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c, for (n=0; n < nblocks; n++ ) { buf_xor(outbuf, inbuf, c->u_iv.iv, blocksize); - c->cipher->encrypt ( &c->context.c, outbuf, outbuf ); + nburn = c->cipher->encrypt ( &c->context.c, outbuf, outbuf ); + burn = nburn > burn ? nburn : burn; memcpy (c->u_iv.iv, outbuf, blocksize ); inbuf += blocksize; if (!(c->flags & GCRY_CIPHER_CBC_MAC)) @@ -100,10 +104,14 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c, for (; i < blocksize; i++) outbuf[i] = 0 ^ *ivp++; - c->cipher->encrypt (&c->context.c, outbuf, outbuf); + nburn = c->cipher->encrypt (&c->context.c, outbuf, outbuf); + burn = nburn > burn ? nburn : burn; memcpy (c->u_iv.iv, outbuf, blocksize); } + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } @@ -117,6 +125,7 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c, int i; size_t blocksize = c->cipher->blocksize; unsigned int nblocks = inbuflen / blocksize; + unsigned int burn, nburn; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; @@ -126,6 +135,8 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c, && (c->flags & GCRY_CIPHER_CBC_CTS))) return GPG_ERR_INV_LENGTH; + burn = 0; + if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) { nblocks--; @@ -148,7 +159,8 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c, * save the original ciphertext block. We use LASTIV for * this here because it is not used otherwise. */ memcpy (c->lastiv, inbuf, blocksize); - c->cipher->decrypt ( &c->context.c, outbuf, inbuf ); + nburn = c->cipher->decrypt ( &c->context.c, outbuf, inbuf ); + burn = nburn > burn ? nburn : burn; buf_xor(outbuf, outbuf, c->u_iv.iv, blocksize); memcpy(c->u_iv.iv, c->lastiv, blocksize ); inbuf += c->cipher->blocksize; @@ -168,16 +180,21 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c, memcpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */ memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */ - c->cipher->decrypt ( &c->context.c, outbuf, inbuf ); + nburn = c->cipher->decrypt ( &c->context.c, outbuf, inbuf ); + burn = nburn > burn ? nburn : burn; buf_xor(outbuf, outbuf, c->u_iv.iv, restbytes); memcpy(outbuf + blocksize, outbuf, restbytes); for(i=restbytes; i < blocksize; i++) c->u_iv.iv[i] = outbuf[i]; - c->cipher->decrypt (&c->context.c, outbuf, c->u_iv.iv); + nburn = c->cipher->decrypt (&c->context.c, outbuf, c->u_iv.iv); + burn = nburn > burn ? nburn : burn; buf_xor(outbuf, outbuf, c->lastiv, blocksize); /* c->lastiv is now really lastlastiv, does this matter? */ } + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } diff --git a/cipher/cipher-cfb.c b/cipher/cipher-cfb.c index ed84b75..f772280 100644 --- a/cipher/cipher-cfb.c +++ b/cipher/cipher-cfb.c @@ -39,6 +39,7 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, unsigned char *ivp; size_t blocksize = c->cipher->blocksize; size_t blocksize_x_2 = blocksize + blocksize; + unsigned int burn, nburn; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; @@ -53,6 +54,8 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, return 0; } + burn = 0; + if ( c->unused ) { /* XOR the input with the IV and store input into IV */ @@ -80,7 +83,8 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, while ( inbuflen >= blocksize_x_2 ) { /* Encrypt the IV. */ - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; /* XOR the input with the IV and store input into IV. */ buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); outbuf += blocksize; @@ -93,7 +97,8 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, { /* Save the current IV and then encrypt the IV. */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; /* XOR the input with the IV and store input into IV */ buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); outbuf += blocksize; @@ -104,7 +109,8 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, { /* Save the current IV and then encrypt the IV. */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; c->unused = blocksize; /* Apply the XOR. */ c->unused -= inbuflen; @@ -113,6 +119,10 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, inbuf += inbuflen; inbuflen = 0; } + + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } @@ -125,6 +135,7 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, unsigned char *ivp; size_t blocksize = c->cipher->blocksize; size_t blocksize_x_2 = blocksize + blocksize; + unsigned int burn, nburn; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; @@ -139,6 +150,8 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, return 0; } + burn = 0; + if (c->unused) { /* XOR the input with the IV and store input into IV. */ @@ -166,7 +179,8 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, while (inbuflen >= blocksize_x_2 ) { /* Encrypt the IV. */ - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; /* XOR the input with the IV and store input into IV. */ buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); outbuf += blocksize; @@ -179,7 +193,8 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, { /* Save the current IV and then encrypt the IV. */ memcpy ( c->lastiv, c->u_iv.iv, blocksize); - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; /* XOR the input with the IV and store input into IV */ buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); outbuf += blocksize; @@ -191,7 +206,8 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, { /* Save the current IV and then encrypt the IV. */ memcpy ( c->lastiv, c->u_iv.iv, blocksize ); - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; c->unused = blocksize; /* Apply the XOR. */ c->unused -= inbuflen; @@ -200,5 +216,9 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, inbuf += inbuflen; inbuflen = 0; } + + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } diff --git a/cipher/cipher-ctr.c b/cipher/cipher-ctr.c index 6bc6ffc..ff1742c 100644 --- a/cipher/cipher-ctr.c +++ b/cipher/cipher-ctr.c @@ -40,10 +40,13 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, int i; unsigned int blocksize = c->cipher->blocksize; unsigned int nblocks; + unsigned int burn, nburn; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; + burn = 0; + /* First process a left over encrypted counter. */ if (c->unused) { @@ -57,7 +60,6 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, inbuflen -= n; } - /* Use a bulk method if available. */ nblocks = inbuflen / blocksize; if (nblocks && c->bulk.ctr_enc) @@ -75,7 +77,8 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, unsigned char tmp[MAX_BLOCKSIZE]; do { - c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr); + nburn = c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr); + burn = nburn > burn ? nburn : burn; for (i = blocksize; i > 0; i--) { @@ -100,5 +103,8 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, wipememory (tmp, sizeof tmp); } + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } diff --git a/cipher/cipher-ofb.c b/cipher/cipher-ofb.c index e194976..3fb9b0d 100644 --- a/cipher/cipher-ofb.c +++ b/cipher/cipher-ofb.c @@ -38,6 +38,7 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, { unsigned char *ivp; size_t blocksize = c->cipher->blocksize; + unsigned int burn, nburn; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; @@ -52,6 +53,8 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, return 0; } + burn = 0; + if( c->unused ) { inbuflen -= c->unused; @@ -67,7 +70,8 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, { /* Encrypt the IV (and save the current one). */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize); outbuf += blocksize; inbuf += blocksize; @@ -76,7 +80,8 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, if ( inbuflen ) { /* process the remaining bytes */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; c->unused = blocksize; c->unused -= inbuflen; buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen); @@ -84,6 +89,10 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, inbuf += inbuflen; inbuflen = 0; } + + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } @@ -95,6 +104,7 @@ _gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c, { unsigned char *ivp; size_t blocksize = c->cipher->blocksize; + unsigned int burn, nburn; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; @@ -108,6 +118,8 @@ _gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c, return 0; } + burn = 0; + if ( c->unused ) { inbuflen -= c->unused; @@ -123,7 +135,8 @@ _gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c, { /* Encrypt the IV (and save the current one). */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize); outbuf += blocksize; inbuf += blocksize; @@ -133,7 +146,8 @@ _gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c, { /* Process the remaining bytes. */ /* Encrypt the IV (and save the current one). */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); - c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; c->unused = blocksize; c->unused -= inbuflen; buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen); @@ -141,5 +155,9 @@ _gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c, inbuf += inbuflen; inbuflen = 0; } + + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } diff --git a/cipher/cipher.c b/cipher/cipher.c index 08d6165..2337c09 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -150,7 +150,7 @@ dummy_setkey (void *c, const unsigned char *key, unsigned int keylen) return GPG_ERR_NO_ERROR; } -static void +static unsigned int dummy_encrypt_block (void *c, unsigned char *outbuf, const unsigned char *inbuf) { @@ -158,9 +158,10 @@ dummy_encrypt_block (void *c, (void)outbuf; (void)inbuf; BUG(); + return 0; } -static void +static unsigned int dummy_decrypt_block (void *c, unsigned char *outbuf, const unsigned char *inbuf) { @@ -168,6 +169,7 @@ dummy_decrypt_block (void *c, (void)outbuf; (void)inbuf; BUG(); + return 0; } static void @@ -902,6 +904,7 @@ do_ecb_encrypt (gcry_cipher_hd_t c, { unsigned int blocksize = c->cipher->blocksize; unsigned int n, nblocks; + unsigned int burn, nburn; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; @@ -909,13 +912,19 @@ do_ecb_encrypt (gcry_cipher_hd_t c, return GPG_ERR_INV_LENGTH; nblocks = inbuflen / c->cipher->blocksize; + burn = 0; for (n=0; n < nblocks; n++ ) { - c->cipher->encrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf); + nburn = c->cipher->encrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf); + burn = nburn > burn ? nburn : burn; inbuf += blocksize; outbuf += blocksize; } + + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } @@ -926,20 +935,27 @@ do_ecb_decrypt (gcry_cipher_hd_t c, { unsigned int blocksize = c->cipher->blocksize; unsigned int n, nblocks; + unsigned int burn, nburn; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; if ((inbuflen % blocksize)) return GPG_ERR_INV_LENGTH; + nblocks = inbuflen / c->cipher->blocksize; + burn = 0; for (n=0; n < nblocks; n++ ) { - c->cipher->decrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf ); + nburn = c->cipher->decrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf); + burn = nburn > burn ? nburn : burn; inbuf += blocksize; outbuf += blocksize; } + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + return 0; } diff --git a/cipher/des.c b/cipher/des.c index 96b06ae..7db9e5d 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -1054,21 +1054,21 @@ do_tripledes_set_extra_info (void *context, int what, } -static void +static unsigned int do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; tripledes_ecb_encrypt ( ctx, inbuf, outbuf ); - _gcry_burn_stack (32); + return /*burn_stack*/ (32); } -static void +static unsigned int do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; tripledes_ecb_decrypt ( ctx, inbuf, outbuf ); - _gcry_burn_stack (32); + return /*burn_stack*/ (32); } static gcry_err_code_t @@ -1091,22 +1091,22 @@ do_des_setkey (void *context, const byte *key, unsigned keylen) } -static void +static unsigned int do_des_encrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _des_ctx *ctx = (struct _des_ctx *) context; des_ecb_encrypt ( ctx, inbuf, outbuf ); - _gcry_burn_stack (32); + return /*burn_stack*/ (32); } -static void +static unsigned int do_des_decrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _des_ctx *ctx = (struct _des_ctx *) context; des_ecb_decrypt ( ctx, inbuf, outbuf ); - _gcry_burn_stack (32); + return /*burn_stack*/ (32); } diff --git a/cipher/idea.c b/cipher/idea.c index c025c95..6e81e84 100644 --- a/cipher/idea.c +++ b/cipher/idea.c @@ -272,12 +272,12 @@ encrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf ) cipher( outbuf, inbuf, c->ek ); } -static void +static unsigned int idea_encrypt (void *context, byte *out, const byte *in) { IDEA_context *ctx = context; encrypt_block (ctx, out, in); - _gcry_burn_stack (24+3*sizeof (void*)); + return /*burn_stack*/ (24+3*sizeof (void*)); } static void @@ -290,12 +290,12 @@ decrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf ) cipher( outbuf, inbuf, c->dk ); } -static void +static unsigned int idea_decrypt (void *context, byte *out, const byte *in) { IDEA_context *ctx = context; decrypt_block (ctx, out, in); - _gcry_burn_stack (24+3*sizeof (void*)); + return /*burn_stack*/ (24+3*sizeof (void*)); } diff --git a/cipher/rfc2268.c b/cipher/rfc2268.c index 1c9c8d4..130be9b 100644 --- a/cipher/rfc2268.c +++ b/cipher/rfc2268.c @@ -136,6 +136,13 @@ do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf) outbuf[7] = word3 >> 8; } +static unsigned int +encrypt_block (void *context, unsigned char *outbuf, const unsigned char *inbuf) +{ + do_encrypt (context, outbuf, inbuf); + return /*burn_stack*/ (4 * sizeof(void *) + sizeof(void *) + sizeof(u32) * 4); +} + static void do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf) { @@ -188,6 +195,13 @@ do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf) outbuf[7] = word3 >> 8; } +static unsigned int +decrypt_block (void *context, unsigned char *outbuf, const unsigned char *inbuf) +{ + do_decrypt (context, outbuf, inbuf); + return /*burn_stack*/ (4 * sizeof(void *) + sizeof(void *) + sizeof(u32) * 4); +} + static gpg_err_code_t setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2) @@ -340,5 +354,5 @@ static gcry_cipher_oid_spec_t oids_rfc2268_40[] = gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = { "RFC2268_40", NULL, oids_rfc2268_40, RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context), - do_setkey, do_encrypt, do_decrypt + do_setkey, encrypt_block, decrypt_block }; diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 314f106..190d0f9 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1450,10 +1450,11 @@ do_aesni (RIJNDAEL_context *ctx, int decrypt_flag, #endif /*USE_AESNI*/ -static void +static unsigned int rijndael_encrypt (void *context, byte *b, const byte *a) { RIJNDAEL_context *ctx = context; + unsigned int burn_stack; if (0) ; @@ -1461,7 +1462,7 @@ rijndael_encrypt (void *context, byte *b, const byte *a) else if (ctx->use_padlock) { do_padlock (ctx, 0, b, a); - _gcry_burn_stack (48 + 15 /* possible padding for alignment */); + burn_stack = (48 + 15 /* possible padding for alignment */); } #endif /*USE_PADLOCK*/ #ifdef USE_AESNI @@ -1470,13 +1471,16 @@ rijndael_encrypt (void *context, byte *b, const byte *a) aesni_prepare (); do_aesni (ctx, 0, b, a); aesni_cleanup (); + burn_stack = 0; } #endif /*USE_AESNI*/ else { do_encrypt (ctx, b, a); - _gcry_burn_stack (56 + 2*sizeof(int)); + burn_stack = (56 + 2*sizeof(int)); } + + return burn_stack; } @@ -1820,10 +1824,11 @@ do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax) -static void +static unsigned int rijndael_decrypt (void *context, byte *b, const byte *a) { RIJNDAEL_context *ctx = context; + unsigned int burn_stack; if (0) ; @@ -1831,7 +1836,7 @@ rijndael_decrypt (void *context, byte *b, const byte *a) else if (ctx->use_padlock) { do_padlock (ctx, 1, b, a); - _gcry_burn_stack (48 + 2*sizeof(int) /* FIXME */); + burn_stack = (48 + 2*sizeof(int) /* FIXME */); } #endif /*USE_PADLOCK*/ #ifdef USE_AESNI @@ -1840,13 +1845,16 @@ rijndael_decrypt (void *context, byte *b, const byte *a) aesni_prepare (); do_aesni (ctx, 1, b, a); aesni_cleanup (); + burn_stack = 0; } #endif /*USE_AESNI*/ else { do_decrypt (ctx, b, a); - _gcry_burn_stack (56+2*sizeof(int)); + burn_stack = (56+2*sizeof(int)); } + + return burn_stack; } diff --git a/cipher/seed.c b/cipher/seed.c index ae26e67..1600c55 100644 --- a/cipher/seed.c +++ b/cipher/seed.c @@ -371,13 +371,13 @@ do_encrypt (const SEED_context *ctx, byte *outbuf, const byte *inbuf) PUTU32 (outbuf+12, x2); } -static void +static unsigned int seed_encrypt (void *context, byte *outbuf, const byte *inbuf) { SEED_context *ctx = context; do_encrypt (ctx, outbuf, inbuf); - _gcry_burn_stack (4*6); + return /*burn_stack*/ (4*6); } @@ -417,13 +417,13 @@ do_decrypt (SEED_context *ctx, byte *outbuf, const byte *inbuf) PUTU32 (outbuf+12, x2); } -static void +static unsigned int seed_decrypt (void *context, byte *outbuf, const byte *inbuf) { SEED_context *ctx = context; do_decrypt (ctx, outbuf, inbuf); - _gcry_burn_stack (4*6); + return /*burn_stack*/ (4*6); } diff --git a/cipher/serpent.c b/cipher/serpent.c index bf03fe7..30ba4dd 100644 --- a/cipher/serpent.c +++ b/cipher/serpent.c @@ -792,22 +792,22 @@ serpent_decrypt_internal (serpent_context_t *context, memcpy (output, b_next, sizeof (b_next)); } -static void +static unsigned int serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; serpent_encrypt_internal (context, buffer_in, buffer_out); - _gcry_burn_stack (2 * sizeof (serpent_block_t)); + return /*burn_stack*/ (2 * sizeof (serpent_block_t)); } -static void +static unsigned int serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; serpent_decrypt_internal (context, buffer_in, buffer_out); - _gcry_burn_stack (2 * sizeof (serpent_block_t)); + return /*burn_stack*/ (2 * sizeof (serpent_block_t)); } diff --git a/cipher/twofish.c b/cipher/twofish.c index 07a4ebe..70cdb47 100644 --- a/cipher/twofish.c +++ b/cipher/twofish.c @@ -819,12 +819,12 @@ do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in) _gcry_twofish_amd64_encrypt_block(ctx, out, in); } -static void +static unsigned int twofish_encrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; _gcry_twofish_amd64_encrypt_block(ctx, out, in); - _gcry_burn_stack (4*sizeof (void*)); + return /*burn_stack*/ (4*sizeof (void*)); } #else /*!USE_AMD64_ASM*/ @@ -861,12 +861,12 @@ do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in) OUTUNPACK (3, b, 7); } -static void +static unsigned int twofish_encrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; do_twofish_encrypt (ctx, out, in); - _gcry_burn_stack (24+3*sizeof (void*)); + return /*burn_stack*/ (24+3*sizeof (void*)); } #endif /*!USE_AMD64_ASM*/ @@ -882,12 +882,12 @@ do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in) _gcry_twofish_amd64_decrypt_block(ctx, out, in); } -static void +static unsigned int twofish_decrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; _gcry_twofish_amd64_decrypt_block(ctx, out, in); - _gcry_burn_stack (4*sizeof (void*)); + return /*burn_stack*/ (4*sizeof (void*)); } #else /*!USE_AMD64_ASM*/ @@ -924,13 +924,13 @@ do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in) OUTUNPACK (3, d, 3); } -static void +static unsigned int twofish_decrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; do_twofish_decrypt (ctx, out, in); - _gcry_burn_stack (24+3*sizeof (void*)); + return /*burn_stack*/ (24+3*sizeof (void*)); } #endif /*!USE_AMD64_ASM*/ diff --git a/src/gcrypt-module.h b/src/gcrypt-module.h index cd55207..10c9f02 100644 --- a/src/gcrypt-module.h +++ b/src/gcrypt-module.h @@ -52,14 +52,14 @@ typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c, unsigned keylen); /* Type for the cipher_encrypt function. */ -typedef void (*gcry_cipher_encrypt_t) (void *c, - unsigned char *outbuf, - const unsigned char *inbuf); +typedef unsigned int __attribute__ ((warn_unused_result)) (*gcry_cipher_encrypt_t) (void *c, + unsigned char *outbuf, + const unsigned char *inbuf); /* Type for the cipher_decrypt function. */ -typedef void (*gcry_cipher_decrypt_t) (void *c, - unsigned char *outbuf, - const unsigned char *inbuf); +typedef unsigned int __attribute__ ((warn_unused_result)) (*gcry_cipher_decrypt_t) (void *c, + unsigned char *outbuf, + const unsigned char *inbuf); /* Type for the cipher_stencrypt function. */ typedef void (*gcry_cipher_stencrypt_t) (void *c, From wk at gnupg.org Tue Sep 3 20:16:05 2013 From: wk at gnupg.org (Werner Koch) Date: Tue, 03 Sep 2013 20:16:05 +0200 Subject: [PATCH 1/5] Add limited implementation of GOST 28147-89 cipher In-Reply-To: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> (Dmitry Eremin-Solenikov's message of "Mon, 2 Sep 2013 13:28:48 +0400") References: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <871u55n53u.fsf@vigenere.g10code.de> Hi Dmitry, I noticed you patches and will merge them as time permits. I may want to change the assigned ids, though. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Tue Sep 3 21:19:28 2013 From: wk at gnupg.org (Werner Koch) Date: Tue, 03 Sep 2013 21:19:28 +0200 Subject: [PATCH 1/2] Move stack burning from block ciphers to cipher modes In-Reply-To: <20130903171824.13479.98973.stgit@localhost6.localdomain6> (Jussi Kivilinna's message of "Tue, 03 Sep 2013 20:18:24 +0300") References: <20130903171824.13479.98973.stgit@localhost6.localdomain6> Message-ID: <87ppsplnlr.fsf@vigenere.g10code.de> On Tue, 3 Sep 2013 19:18, jussi.kivilinna at iki.fi said: > (Note, patch also adds missing burn_stack for RFC2268_40 cipher). A brute force search would probably be easier than scanning the stack ;-) Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Tue Sep 3 21:17:00 2013 From: wk at gnupg.org (Werner Koch) Date: Tue, 03 Sep 2013 21:17:00 +0200 Subject: [PATCH 2/2] Make _gcry_burn_stack use variable length array In-Reply-To: <20130903171829.13479.57523.stgit@localhost6.localdomain6> (Jussi Kivilinna's message of "Tue, 03 Sep 2013 20:18:29 +0300") References: <20130903171824.13479.98973.stgit@localhost6.localdomain6> <20130903171829.13479.57523.stgit@localhost6.localdomain6> Message-ID: <87txi1lnpv.fsf@vigenere.g10code.de> On Tue, 3 Sep 2013 19:18, jussi.kivilinna at iki.fi said: > 64-byte stack buffer instead of burn stack deeper. It's mentioned in GCC > bugzilla that _gcry_burn_stack is doing wrong thing here [1] and that this > kind of optimization is allowed. >From [1]: This is also a libgcrypt bug, because clearly if it wants to burn some portion of the stack (assuming for security reasons), then 1) if it doesn't prevent tail recursion or tail call to itself, it doesn't do what it is trying to do, in particular it keeps overwriting with zeros the same portion of memory over and over 2) even if it isn't tail recursion/call optimized, on most targets it will still leave gaps on the stack not overwritten So, all in all, quite questionable way of burning cycles in the crypto library.dd Right, this is a about security. It is actual a standard practice which has been around for 20 years or so. I have not seen a reference to the C specs that explains that optimization of tail recursion is allowed. Doubtless this one of those esoteric interpretations of the standard. Turning C into a high level language is a Bad Thing(tm). People who want that should use a high level language. I wonder who long it will take that de-facto safe assumptions, like CHAR_BIT is 8, will be sacrificed for yet another small performance optimization. Do that for C++ but keep hands off the things which worked well for more than 30 years. This was not the first case were stretching the interpretation of the standard opened holes in existing software. Right there is a standard, but there is also a common understanding on how certain things are to be interpreted. The latter is more important than the wording of standard. And yes, there might be gaps on the stack. But for any straight forward C compiler that would not matter at all. We merely try our best to not leave traces of secrets on the stack while being portable. And while we are at it: Why is paged out memory still not encrypted by default? Sorry for the rant. > So lets fix _gcry_burn_stack by using variable length array when VLAs > are supported by compiler. This should ensure proper stack burning to > the requested depth and avoid GCC loop optimizations. Okay, that might work for a while. > +#ifdef HAVE_VLA > + int buflen = (((bytes <= 0) ? 1 : bytes) + 63) & ~63; > + char buf[buflen]; Add volatile ? Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From jussi.kivilinna at iki.fi Tue Sep 3 21:57:25 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 03 Sep 2013 22:57:25 +0300 Subject: [PATCH 2/2] Make _gcry_burn_stack use variable length array In-Reply-To: <87txi1lnpv.fsf@vigenere.g10code.de> References: <20130903171824.13479.98973.stgit@localhost6.localdomain6> <20130903171829.13479.57523.stgit@localhost6.localdomain6> <87txi1lnpv.fsf@vigenere.g10code.de> Message-ID: <52263F25.6000305@iki.fi> On 03.09.2013 22:17, Werner Koch wrote: > On Tue, 3 Sep 2013 19:18, jussi.kivilinna at iki.fi said: > >> 64-byte stack buffer instead of burn stack deeper. It's mentioned in GCC >> bugzilla that _gcry_burn_stack is doing wrong thing here [1] and that this >> kind of optimization is allowed. > > From [1]: > > This is also a libgcrypt bug, because clearly if it wants to burn > some portion of the stack (assuming for security reasons), then > > 1) if it doesn't prevent tail recursion or tail call to itself, it > doesn't do what it is trying to do, in particular it keeps overwriting > with zeros the same portion of memory over and over > > 2) even if it isn't tail recursion/call optimized, on most targets it > will still leave gaps on the stack not overwritten > > So, all in all, quite questionable way of burning cycles in the crypto > library.dd > > Right, this is a about security. It is actual a standard practice which > has been around for 20 years or so. > > I have not seen a reference to the C specs that explains that > optimization of tail recursion is allowed. Doubtless this one of those > esoteric interpretations of the standard. Turning C into a high level > language is a Bad Thing(tm). People who want that should use a high > level language. I wonder who long it will take that de-facto safe > assumptions, like CHAR_BIT is 8, will be sacrificed for yet another small > performance optimization. Do that for C++ but keep hands off the things > which worked well for more than 30 years. This was not the first case > were stretching the interpretation of the standard opened holes in > existing software. Right there is a standard, but there is also a > common understanding on how certain things are to be interpreted. The > latter is more important than the wording of standard. > > And yes, there might be gaps on the stack. But for any straight forward > C compiler that would not matter at all. We merely try our best to not > leave traces of secrets on the stack while being portable. And while we > are at it: Why is paged out memory still not encrypted by default? > > Sorry for the rant. No problem. What annoys me, is that this issue was not communicated here, so that burn stack could have been properly adjusted. > >> So lets fix _gcry_burn_stack by using variable length array when VLAs >> are supported by compiler. This should ensure proper stack burning to >> the requested depth and avoid GCC loop optimizations. > > Okay, that might work for a while. > >> +#ifdef HAVE_VLA >> + int buflen = (((bytes <= 0) ? 1 : bytes) + 63) & ~63; >> + char buf[buflen]; > > Add volatile ? wipememory() casts input pointer to volatile, which should be enough .. but, well, with current compilers you'll never know. I'll throw that volatile in. -Jussi > > > Shalom-Salam, > > Werner > From jussi.kivilinna at iki.fi Wed Sep 4 09:32:51 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Wed, 04 Sep 2013 10:32:51 +0300 Subject: [PATCH] Change _gcry_burn_stack take burn depth as unsigned integer Message-ID: <20130904073251.15489.28621.stgit@localhost6.localdomain6> * src/misc.c (_gcry_burn_stack): Change to handle 'unsigned int' bytes. -- Unsigned integer is better here for code generation because we can now avoid possible branching caused by (bytes <= 0) check. Signed-off-by: Jussi Kivilinna --- src/g10lib.h | 2 +- src/misc.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/g10lib.h b/src/g10lib.h index 31131a5..cc1a1a8 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -235,7 +235,7 @@ int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE; /* Stack burning. */ -void _gcry_burn_stack (int bytes); +void _gcry_burn_stack (unsigned int bytes); /* To avoid that a compiler optimizes certain memset calls away, these diff --git a/src/misc.c b/src/misc.c index 135aeb4..dece1d0 100644 --- a/src/misc.c +++ b/src/misc.c @@ -288,10 +288,11 @@ _gcry_log_printhex (const char *text, const void *buffer, size_t length) void -_gcry_burn_stack (int bytes) +_gcry_burn_stack (unsigned int bytes) { #ifdef HAVE_VLA - int buflen = (((bytes <= 0) ? 1 : bytes) + 63) & ~63; + /* (bytes == 0 ? 1 : bytes) == (!bytes + bytes) */ + unsigned int buflen = ((!bytes + bytes) + 63) & ~63; volatile char buf[buflen]; wipememory (buf, sizeof buf); @@ -300,9 +301,8 @@ _gcry_burn_stack (int bytes) wipememory (buf, sizeof buf); - bytes -= sizeof buf; - if (bytes > 0) - _gcry_burn_stack (bytes); + if (bytes > sizeof buf) + _gcry_burn_stack (bytes - sizeof buf); #endif } From dbaryshkov at gmail.com Thu Sep 5 01:21:33 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 5 Sep 2013 03:21:33 +0400 Subject: mpi: Suppress newer gcc warnings. Message-ID: Hello, I see a typo in a definition of GCC_ATTR_UNUSED macro: +#if __GNUC__ > 2 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 ) +#define GCC_ATTR_UNUSED __attribute__ ((unused)) +#else First line will be true for all gcc starting gcc 3.0, not 3.5. The comparison line should read +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 ) Shall it not? -- With best wishes Dmitry From jussi.kivilinna at iki.fi Thu Sep 5 09:16:46 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 05 Sep 2013 10:16:46 +0300 Subject: mpi: Suppress newer gcc warnings. In-Reply-To: References: Message-ID: <52282FDE.2030403@iki.fi> On 05.09.2013 02:21, Dmitry Eremin-Solenikov wrote:> Hello, > > I see a typo in a definition of GCC_ATTR_UNUSED macro: > > +#if __GNUC__ > 2 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 ) > +#define GCC_ATTR_UNUSED __attribute__ ((unused)) > +#else > > First line will be true for all gcc starting gcc 3.0, not 3.5. > The comparison line should read > > +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 ) > > Shall it not? > Or is just having __GNUC__ > 2 enough? GCC manuals for 3.0.4 and 2.95.3 show support for 'unused' attribute. -Jussi From dbaryshkov at gmail.com Thu Sep 5 11:42:11 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 5 Sep 2013 13:42:11 +0400 Subject: [PATCH v2] Add support for Salsa20/12 - 12 round version of Salsa20 Message-ID: <1378374131-25733-1-git-send-email-dbaryshkov@gmail.com> * src/gcrypt.h.in (GCRY_CIPHER_SALSA20R12): New. * src/salsa20.c (salsa20_core, salsa20_do_encrypt_stream): Add support for reduced round versions. (salsa20r12_encrypt_stream, _gcry_cipher_spec_salsa20r12): Implement Salsa20/12 - a 12 round version of Salsa20 selected by eStream. * src/cipher.h: Declsare Salsa20/12 definition. * cipher/cipher.c: Register Salsa20/12 * tests/basic.c: (check_stream_cipher, check_stream_cipher_large_block): Populate Salsa20/12 tests with test vectors from ecrypt (check_ciphers): Add simple test for Salsa20/12 -- Salsa20/12 is a reduced round version of Salsa20 that is amongst ciphers selected by eSTREAM for Phase 3 of Profile 1 algorithm. Moreover it is one of proposed ciphers for TLS (draft-josefsson-salsa20-tls-02). Signed-off-by: Dmitry Eremin-Solenikov --- [Changes since V1: fixed name of the Salsa20/12 cipher, fixed the name of define with amount of rounds]. NEWS | 3 +- cipher/cipher.c | 2 + cipher/salsa20.c | 49 +++++++++++-- doc/gcrypt.texi | 4 + src/cipher.h | 1 + src/gcrypt.h.in | 3 +- tests/basic.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 273 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 508b943..3e47400 100644 --- a/NEWS +++ b/NEWS @@ -12,7 +12,7 @@ Noteworthy changes in version 1.6.0 (unreleased) * Added support for the IDEA cipher algorithm. - * Added support for the Salsa20 stream cipher. + * Added support for the Salsa20 and reduced Salsa20/12 stream ciphers. * Added a random number generator to directly use the system's RNG. Also added an interface to prefer the use of a specified RNG. @@ -74,6 +74,7 @@ Noteworthy changes in version 1.6.0 (unreleased) GCRYCTL_DISABLE_PRIV_DROP NEW. GCRY_CIPHER_SALSA20 NEW. gcry_sexp_nth_buffer NEW. + GCRY_CIPHER_SALSA20R12 NEW. Noteworthy changes in version 1.5.0 (2011-06-29) diff --git a/cipher/cipher.c b/cipher/cipher.c index 08d6165..7b320c4 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -107,6 +107,8 @@ static struct cipher_table_entry #if USE_SALSA20 { &_gcry_cipher_spec_salsa20, &_gcry_cipher_extraspec_salsa20, GCRY_CIPHER_SALSA20 }, + { &_gcry_cipher_spec_salsa20r12, + &_gcry_cipher_extraspec_salsa20, GCRY_CIPHER_SALSA20R12 }, #endif { NULL } }; diff --git a/cipher/salsa20.c b/cipher/salsa20.c index e26c328..37f2989 100644 --- a/cipher/salsa20.c +++ b/cipher/salsa20.c @@ -49,6 +49,7 @@ /* Number of rounds. The standard uses 20 rounds. In any case the number of rounds must be even. */ #define SALSA20_ROUNDS 20 +#define SALSA20R12_ROUNDS 12 typedef struct @@ -120,13 +121,13 @@ static const char *selftest (void); } while(0) static void -salsa20_core (u32 *dst, const u32 *src) +salsa20_core (u32 *dst, const u32 *src, unsigned rounds) { u32 pad[SALSA20_INPUT_LENGTH]; unsigned int i; memcpy (pad, src, sizeof(pad)); - for (i = 0; i < SALSA20_ROUNDS; i += 2) + for (i = 0; i < rounds; i += 2) { SALSA20_CORE_DEBUG (i); QROUND (pad[0], pad[4], pad[8], pad[12]); @@ -253,7 +254,7 @@ salsa20_setiv (void *context, const byte *iv, unsigned int ivlen) static void salsa20_do_encrypt_stream (SALSA20_context_t *ctx, byte *outbuf, const byte *inbuf, - unsigned int length) + unsigned int length, unsigned rounds) { if (ctx->unused) { @@ -280,7 +281,7 @@ salsa20_do_encrypt_stream (SALSA20_context_t *ctx, /* Create the next pad and bump the block counter. Note that it is the user's duty to change to another nonce not later than after 2^70 processed bytes. */ - salsa20_core (ctx->pad, ctx->input); + salsa20_core (ctx->pad, ctx->input, rounds); if (!++ctx->input[8]) ctx->input[9]++; @@ -306,7 +307,30 @@ salsa20_encrypt_stream (void *context, if (length) { - salsa20_do_encrypt_stream (ctx, outbuf, inbuf, length); + salsa20_do_encrypt_stream (ctx, outbuf, inbuf, length, SALSA20_ROUNDS); + _gcry_burn_stack (/* salsa20_do_encrypt_stream: */ + 2*sizeof (void*) + + 3*sizeof (void*) + sizeof (unsigned int) + /* salsa20_core: */ + + 2*sizeof (void*) + + 2*sizeof (void*) + + 64 + + sizeof (unsigned int) + + sizeof (u32) + ); + } +} + + +static void +salsa20r12_encrypt_stream (void *context, + byte *outbuf, const byte *inbuf, unsigned int length) +{ + SALSA20_context_t *ctx = (SALSA20_context_t *)context; + + if (length) + { + salsa20_do_encrypt_stream (ctx, outbuf, inbuf, length, SALSA20R12_ROUNDS); _gcry_burn_stack (/* salsa20_do_encrypt_stream: */ 2*sizeof (void*) + 3*sizeof (void*) + sizeof (unsigned int) @@ -372,6 +396,21 @@ gcry_cipher_spec_t _gcry_cipher_spec_salsa20 = salsa20_encrypt_stream }; +gcry_cipher_spec_t _gcry_cipher_spec_salsa20r12 = + { + "SALSA20R12", /* name */ + NULL, /* aliases */ + NULL, /* oids */ + 1, /* blocksize in bytes. */ + SALSA20_MAX_KEY_SIZE*8, /* standard key length in bits. */ + sizeof (SALSA20_context_t), + salsa20_setkey, + NULL, + NULL, + salsa20r12_encrypt_stream, + salsa20r12_encrypt_stream + }; + cipher_extra_spec_t _gcry_cipher_extraspec_salsa20 = { NULL, diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 770a245..b49dee3 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -1579,6 +1579,10 @@ The Camellia cipher by NTT. See @cindex Salsa20 This is the Salsa20 stream cipher. + at item GCRY_CIPHER_SALSA20R12 + at cindex Salsa20/12 +This is the Salsa20/12 - reduced round version of Salsa20 stream cipher. + @end table @node Available cipher modes diff --git a/src/cipher.h b/src/cipher.h index bb92758..710061a 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -196,6 +196,7 @@ extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192; extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256; extern gcry_cipher_spec_t _gcry_cipher_spec_idea; extern gcry_cipher_spec_t _gcry_cipher_spec_salsa20; +extern gcry_cipher_spec_t _gcry_cipher_spec_salsa20r12; extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes; extern cipher_extra_spec_t _gcry_cipher_extraspec_aes; diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 06d6663..ce7c154 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -820,7 +820,8 @@ enum gcry_cipher_algos GCRY_CIPHER_CAMELLIA128 = 310, GCRY_CIPHER_CAMELLIA192 = 311, GCRY_CIPHER_CAMELLIA256 = 312, - GCRY_CIPHER_SALSA20 = 313 + GCRY_CIPHER_SALSA20 = 313, + GCRY_CIPHER_SALSA20R12 = 314 }; /* The Rijndael algorithm is basically AES, so provide some macros. */ diff --git a/tests/basic.c b/tests/basic.c index 46e213c..4fbca43 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1241,6 +1241,91 @@ check_stream_cipher (void) "\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71" } } + }, + { + "Salsa20/12 128 bit, test 1", + GCRY_CIPHER_SALSA20R12, 16, 8, + "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00", + { + { 8, + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\xFC\x20\x7D\xBF\xC7\x6C\x5E\x17" + } + } + }, + { + "Salsa20/12 128 bit, test 2", + GCRY_CIPHER_SALSA20R12, 16, 8, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x80\x00\x00\x00\x00\x00\x00\x00", + { + { 8, + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\x08\x28\x39\x9A\x6F\xEF\x20\xDA" + } + } + }, + { + "Salsa20/12 128 bit, test 3", + GCRY_CIPHER_SALSA20R12, 16, 8, + "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD", + "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", + { + { 8, + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\xAD\x9E\x60\xE6\xD2\xA2\x64\xB8" + } + } + }, + { + "Salsa20/12 256 bit, test 1", + GCRY_CIPHER_SALSA20R12, 32, 8, + "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00", + { + { 8, + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\xAF\xE4\x11\xED\x1C\x4E\x07\xE4" + } + } + }, + { + "Salsa20/12 256 bit, test 2", + GCRY_CIPHER_SALSA20R12, 32, 8, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x80\x00\x00\x00\x00\x00\x00\x00", + { + { 8, + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\x17\x2C\x51\x92\xCB\x6E\x64\x5B" + } + } + }, + { + "Salsa20/12 256 bit, ecrypt verified, set 6, vector 0", + GCRY_CIPHER_SALSA20R12, 32, 8, + "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD" + "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D", + "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", + { + { 8, + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82" + }, + { 64, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82\xF2\x00\xC2\x99\x9F\xE4\xBA\x31" + "\xA7\xA1\x8F\x1D\x5C\x97\x16\x19\x1D\x12\x31\x75\xE1\x47\xBD\x4E" + "\x8C\xA6\xED\x16\x6C\xE0\xFC\x8E\x65\xA5\xCA\x60\x84\x20\xFC\x65" + "\x44\xC9\x70\x0A\x0F\x21\x38\xE8\xC1\xA2\x86\xFB\x8C\x1F\xBF\xA0" + } + } } #endif /*USE_SALSA20*/ }; @@ -1543,6 +1628,138 @@ check_stream_cipher_large_block (void) "\xEB\x31\x4E\xD4\x70\xB1\xAF\x6B\x9F\x8D\x69\xDD\x79\xA9\xD7\x50" } } + }, + { + "Salsa20/12 256 bit, ecrypt verified, set 6, vector 0", + GCRY_CIPHER_SALSA20R12, 32, 8, + "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD" + "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D", + "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", + { + { 0, 64, + "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82\xF2\x00\xC2\x99\x9F\xE4\xBA\x31" + "\xA7\xA1\x8F\x1D\x5C\x97\x16\x19\x1D\x12\x31\x75\xE1\x47\xBD\x4E" + "\x8C\xA6\xED\x16\x6C\xE0\xFC\x8E\x65\xA5\xCA\x60\x84\x20\xFC\x65" + "\x44\xC9\x70\x0A\x0F\x21\x38\xE8\xC1\xA2\x86\xFB\x8C\x1F\xBF\xA0" + }, + { 65472, 64, + "\x8F\xBC\x9F\xE8\x69\x1B\xD4\xF0\x82\xB4\x7F\x54\x05\xED\xFB\xC1" + "\x6F\x4D\x5A\x12\xDD\xCB\x2D\x75\x4E\x8A\x99\x98\xD0\xB2\x19\x55" + "\x7D\xFE\x29\x84\xF4\xA1\xD2\xDD\xA7\x6B\x95\x96\x92\x8C\xCE\x05" + "\x56\xF5\x00\x66\xCD\x59\x9E\x44\xEF\x5C\x14\xB2\x26\x68\x3A\xEF" + }, + { 65536, 64, + "\xBC\xBD\x01\xDD\x28\x96\x1C\xC7\xAD\x30\x47\x38\x6C\xBC\xC6\x7C" + "\x10\x8D\x6A\xF1\x11\x67\xE4\x0D\x7A\xE1\xB2\xFC\x45\x18\xA8\x67" + "\xEF\xE4\x02\x65\x1D\x1D\x88\x51\xC4\xFD\x23\x30\xC5\x97\xB3\x6A" + "\x46\xD5\x68\x9E\x00\xFC\x96\xFE\xCF\x9C\xE3\xE2\x21\x1D\x44\xBE" + }, + { 131008, 64, + "\x91\x66\xF3\x1C\xD8\x5B\x5B\xB1\x8F\xC6\x14\xE5\x4E\x4A\xD6\x7F" + "\xB8\x65\x8E\x3B\xF9\xFB\x19\xB7\xA8\x2F\x0F\xE7\xDC\x90\x2D\xF5" + "\x63\xC6\xAC\x4F\x44\x67\x48\xC4\xBC\x3E\x14\x05\xE1\x24\x82\x0D" + "\xC4\x09\x41\x99\x8F\x44\xA8\x10\xE7\x22\x78\x7F\xCD\x47\x78\x4C" + } + } + }, + { + "Salsa20/12 256 bit, ecrypt verified, set 6, vector 1", + GCRY_CIPHER_SALSA20R12, 32, 8, + "\x05\x58\xAB\xFE\x51\xA4\xF7\x4A\x9D\xF0\x43\x96\xE9\x3C\x8F\xE2" + "\x35\x88\xDB\x2E\x81\xD4\x27\x7A\xCD\x20\x73\xC6\x19\x6C\xBF\x12", + "\x16\x7D\xE4\x4B\xB2\x19\x80\xE7", + { + { 0, 64, + "\xC0\x75\x60\xB3\xE7\x76\xB4\x71\xC5\xE2\x93\x14\x26\xCA\xF1\xED" + "\x3A\xE4\xB8\x67\x08\x76\x82\xCA\x9D\xFD\xC2\xBA\xE8\x93\x50\xBD" + "\x84\x82\x1C\xAE\xFF\x85\xAA\xC4\x9D\x74\x35\xA7\xD9\x88\x93\x52" + "\xF5\x27\x9E\x36\x12\x3F\x41\x72\x8A\x14\xEF\x26\x9F\xCB\x94\x4B" + }, + { 65472, 64, + "\xEE\xD1\xBB\x58\xF9\x0C\x89\xE0\x5C\xC6\x8B\x2D\xB6\x05\x58\x49" + "\xB3\xD2\xB1\x87\xB7\xF0\x2F\x9A\x24\xCE\x34\x2A\xF0\xFC\x47\xA3" + "\x74\xBD\x75\x90\xFB\xF4\xFD\x9E\xE5\x9B\x1A\x38\x1E\xBF\xD2\x29" + "\xAD\x2A\x29\x01\xB3\xFB\x61\x08\x12\x90\x0B\x92\x30\xE6\x22\xE9" + }, + { 65536, 64, + "\x70\xF0\x49\x3A\x1B\x62\x53\xCC\x5E\xD3\x45\x0A\x31\xCF\x37\x7D" + "\x83\x4B\xAD\x20\x72\x30\x29\x27\xCC\xD8\x30\x10\x4B\xD3\x05\xFF" + "\x59\xD2\x94\x17\xB2\x32\x88\x4E\xC9\x59\x19\x4D\x60\x47\xC3\xDD" + "\x66\x56\xC4\x7E\x32\x00\x64\xEB\x01\x44\xF7\x34\x1B\xC3\xD6\x97" + }, + { 131008, 64, + "\xD2\xCC\xF7\xC1\xAF\x2A\xB4\x66\xE6\x27\xDB\x44\x08\x40\x96\x9A" + "\xBD\xAB\x68\xD8\x86\xAE\x6A\x38\xA1\x3F\xEE\x17\x50\xCA\x97\xB5" + "\xD3\x31\x5B\x84\x08\x47\x28\x86\x2F\xBC\xC7\xD4\xA9\x7C\x75\xC8" + "\x65\x5F\xF9\xD6\xBB\xC2\x61\x88\x63\x6F\x3E\xDF\xE1\x5C\x7D\x30" + } + } + }, + { + "Salsa20/12 256 bit, ecrypt verified, set 6, vector 2", + GCRY_CIPHER_SALSA20R12, 32, 8, + "\x0A\x5D\xB0\x03\x56\xA9\xFC\x4F\xA2\xF5\x48\x9B\xEE\x41\x94\xE7" + "\x3A\x8D\xE0\x33\x86\xD9\x2C\x7F\xD2\x25\x78\xCB\x1E\x71\xC4\x17", + "\x1F\x86\xED\x54\xBB\x22\x89\xF0", + { + { 0, 64, + "\x51\x22\x52\x91\x01\x90\xD1\x54\xD1\x4D\x0B\x92\x32\xB8\x84\x31" + "\x8C\xCB\x43\x81\x9B\xD5\x42\x19\x32\xC0\x3A\x13\xF0\x7B\x40\x10" + "\x83\xD7\x89\x72\x5A\xA9\xDA\x0B\x41\xCB\x62\x24\x94\x5E\xDC\xB0" + "\xFB\x6F\xD7\xC2\x34\x22\x35\xC9\x70\xF6\x4E\x10\x1C\x25\x68\x64" + }, + { 65472, 64, + "\x97\x96\x74\x55\x84\x0A\x4A\xE5\xC1\xCA\xCE\x49\x15\x19\x13\x8A" + "\xA3\x5E\x5F\x02\x40\x7D\x4A\x1F\xE5\x08\x6D\x35\xF3\x55\x1E\xF4" + "\x77\xD9\x28\x9D\x17\x23\x79\x7C\x1A\x49\xEC\x26\x62\x9A\xFA\xDC" + "\x56\xA0\x38\xA3\x8C\x75\x88\x1B\x62\x17\xFD\x74\x67\x25\x59\x09" + }, + { 65536, 64, + "\x1B\xF8\x2E\x3D\x5C\x54\xDA\xAB\xCF\x84\x15\xF8\xA2\xA1\xA2\x2E" + "\x86\x88\x06\x33\x4F\xF3\x11\x36\x04\x74\x1C\x1D\xF2\xB9\x84\x0F" + "\x87\xDE\xEF\xB0\x07\x23\xA8\xA1\xB2\x4A\x4D\xA1\x7E\xCD\xAD\x00" + "\x01\xF9\x79\xDD\xAE\x2D\xF0\xC5\xE1\xE5\x32\xC4\x8F\x8E\x0D\x34" + }, + { 131008, 64, + "\x06\xD8\x4F\x6A\x71\x34\x84\x20\x32\x9F\xCD\x0C\x41\x75\x9A\xD1" + "\x8F\x99\x57\xA3\x8F\x22\x89\x3B\xA5\x58\xC5\x05\x11\x97\x28\x5C" + "\x6B\xE2\xFD\x6C\x96\xA5\xC6\x62\xAF\xD3\x11\x78\xE7\x0F\x96\x0A" + "\xAB\x3F\x47\x96\x23\xA4\x44\xB6\x81\x91\xE4\xC5\x28\x46\x93\x88" + } + } + }, + { + "Salsa20/12 256 bit, ecrypt verified, set 6, vector 3", + GCRY_CIPHER_SALSA20R12, 32, 8, + "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC" + "\x3F\x92\xE5\x38\x8B\xDE\x31\x84\xD7\x2A\x7D\xD0\x23\x76\xC9\x1C", + "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9", + { + { 0, 64, + "\x99\xDB\x33\xAD\x11\xCE\x0C\xCB\x3B\xFD\xBF\x8D\x0C\x18\x16\x04" + "\x52\xD0\x14\xCD\xE9\x89\xB4\xC4\x11\xA5\x59\xFF\x7C\x20\xA1\x69" + "\xE6\xDC\x99\x09\xD8\x16\xBE\xCE\xDC\x40\x63\xCE\x07\xCE\xA8\x28" + "\xF4\x4B\xF9\xB6\xC9\xA0\xA0\xB2\x00\xE1\xB5\x2A\xF4\x18\x59\xC5" + }, + { 65472, 64, + "\x2F\xF2\x02\x64\xEE\xAF\x47\xAB\x7D\x57\xC3\x62\x24\x53\x54\x51" + "\x73\x5A\xC8\x36\xD3\x2D\xD2\x8A\xE6\x36\x45\xCE\x95\x2F\x7F\xDB" + "\xE6\x68\x9C\x69\x59\x77\xB1\xC7\x6E\x60\xDD\x5B\x27\xAC\xA4\x76" + "\xD2\x62\x0F\xDC\x93\x13\xE8\x48\x9B\xA5\x6A\x70\xC9\xF4\xC3\xA8" + }, + { 65536, 64, + "\xEB\x30\xCD\xA7\x27\xC0\xF8\xB7\xE4\x5D\x5E\xF3\x0D\xB7\xCB\xE0" + "\x21\xF2\x29\x1E\x5F\x56\x93\x8D\x56\xF6\x87\xB7\x37\xC3\xB4\x27" + "\x54\x5C\x56\xA6\xD3\xA0\xBF\x2B\x2F\x47\xB4\x84\x93\xFA\xE4\x5E" + "\xD5\x0C\x2E\x9B\xBE\x49\xFD\x92\xD6\x7C\x76\x49\x05\x5F\x06\xFD" + }, + { 131008, 64, + "\x0E\xBF\x6C\xC3\xCB\xCB\xE7\x4E\x6E\xE8\x07\x47\x1B\x49\x2A\x67" + "\x39\xA5\x2F\x57\x11\x31\xA2\x50\xBC\xDF\xA0\x76\xA2\x65\x90\xD7" + "\xED\xE6\x75\x1C\x03\x26\xA0\x2C\xB1\x1C\x58\x77\x35\x52\x80\x4F" + "\xD8\x68\x67\x15\x35\x5C\x5A\x5C\xC5\x91\x96\x3A\x75\xE9\x94\xB4" + } + } } #endif /*USE_SALSA20*/ }; @@ -2170,6 +2387,7 @@ check_ciphers (void) #endif #if USE_SALSA20 GCRY_CIPHER_SALSA20, + GCRY_CIPHER_SALSA20R12, #endif 0 }; -- 1.8.4.rc3 From gniibe at fsij.org Fri Sep 6 10:41:37 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 06 Sep 2013 17:41:37 +0900 Subject: possible mpi-pow improvement Message-ID: <1378456897.3188.14.camel@cfw2.gniibe.org> For the Yarom/Falkner flush+reload cache side-channel attack, we changed the code so that it always calls the multiplication routine. But this results some performance regression. It is sad thing. Thus, I am trying to recover performance. Attached is the patch I am testing. It needs more clean up, but it works for me with 'make check'. About performance: ====================== original ===================== $ ./tests/benchmark rsa Algorithm generate 100*sign 100*verify ------------------------------------------------ RSA 1024 bit 340ms 860ms 30ms RSA 2048 bit 870ms 5510ms 110ms RSA 3072 bit 6440ms 16930ms 210ms RSA 4096 bit 17470ms 37270ms 360ms Current fix: Call MUL always, regardless of E's bit. ====================== Always call MUL =============== $ ./tests/benchmark rsa Algorithm generate 100*sign 100*verify ------------------------------------------------ RSA 1024 bit 210ms 1180ms 30ms RSA 2048 bit 2040ms 7450ms 110ms RSA 3072 bit 21720ms 21960ms 210ms RSA 4096 bit 25290ms 49680ms 360ms My possible change: ====================== k-ary, MUL instead of SQR ===== Algorithm generate 100*sign 100*verify ------------------------------------------------ RSA 1024 bit 280ms 710ms 30ms RSA 2048 bit 960ms 4410ms 110ms RSA 3072 bit 17680ms 12990ms 220ms RSA 4096 bit 12280ms 29550ms 360ms Any comments are appreciated. diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 85d6fd8..4e75008 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -34,8 +34,36 @@ #include "longlong.h" +static void +mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p, + mpi_ptr_t rp, mpi_size_t rsize, + mpi_ptr_t sp, mpi_size_t ssize, + mpi_ptr_t mp, mpi_size_t msize, + struct karatsuba_ctx *karactx_p) +{ + if( ssize < KARATSUBA_THRESHOLD ) + _gcry_mpih_mul ( xp, rp, rsize, sp, ssize ); + else + _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, sp, ssize, karactx_p); + + if (rsize + ssize > msize) + { + _gcry_mpih_divrem (xp + msize, 0, xp, rsize + ssize, mp, msize); + *xsize_p = msize; + } + else + *xsize_p = rsize + ssize; +} + +#define SIZE_G ((1 << (5 - 1)) - 1) + /**************** * RES = BASE ^ EXPO mod MOD + * + * Reference: + * Handbook of Applied Cryptography + * Algorithm 14.83: Modified left-to-right k-ary exponentiation + * */ void gcry_mpi_powm (gcry_mpi_t res, @@ -60,15 +88,28 @@ gcry_mpi_powm (gcry_mpi_t res, unsigned int bp_nlimbs = 0; unsigned int ep_nlimbs = 0; unsigned int xp_nlimbs = 0; - mpi_ptr_t tspace = NULL; - mpi_size_t tsize = 0; - + mpi_ptr_t g[SIZE_G]; + mpi_size_t gsize[SIZE_G]; + mpi_size_t W; + mpi_ptr_t g_k; + mpi_size_t g_k_size; esize = expo->nlimbs; msize = mod->nlimbs; size = 2 * msize; msign = mod->sign; + if (esize * BITS_PER_MPI_LIMB >= 512) + W = 5; + else if (esize * BITS_PER_MPI_LIMB >= 256) + W = 4; + else if (esize * BITS_PER_MPI_LIMB >= 128) + W = 3; + else if (esize * BITS_PER_MPI_LIMB >= 64) + W = 2; + else + W = 1; + esec = mpi_is_secure(expo); msec = mpi_is_secure(mod); bsec = mpi_is_secure(base); @@ -167,18 +208,17 @@ gcry_mpi_powm (gcry_mpi_t res, mpi_resize (res, size); rp = res->d; } - MPN_COPY ( rp, bp, bsize ); - rsize = bsize; - rsign = bsign; /* Main processing. */ { - mpi_size_t i; + mpi_size_t i, j; mpi_ptr_t xp; + mpi_size_t xsize; int c; mpi_limb_t e; mpi_limb_t carry_limb; struct karatsuba_ctx karactx; + mpi_ptr_t tp; xp_nlimbs = msec? (2 * (msize + 1)):0; xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec ); @@ -186,11 +226,34 @@ gcry_mpi_powm (gcry_mpi_t res, memset( &karactx, 0, sizeof karactx ); negative_result = (ep[0] & 1) && base->sign; + /* Precompute G[] */ + if (W > 1) /* X^2 */ + mul_mod (xp, &xsize, bp, bsize, bp, bsize, mp, msize, &karactx); + for (i = 1; i < (1 << (W - 1)); i++) + { /* Gk, k = 2*i + 1 */ + if (i == 1) + { + g_k = bp; + g_k_size = bsize; + } + else + { + g_k = g[i-2]; + g_k_size = gsize[i-2]; + } + + if (xsize >= g_k_size) + mul_mod (rp, &rsize, xp, xsize, g_k, g_k_size, + mp, msize, &karactx); + else + mul_mod (rp, &rsize, g_k, g_k_size, xp, xsize, + mp, msize, &karactx); + g[i-1] = mpi_alloc_limb_space (rsize, esec); + gsize[i-1] = rsize; + MPN_COPY (g[i-1], rp, rsize); + } + i = esize - 1; - e = ep[i]; - count_leading_zeros (c, e); - e = (e << c) << 1; /* Shift the expo bits to the left, lose msb. */ - c = BITS_PER_MPI_LIMB - 1 - c; /* Main loop. @@ -200,78 +263,137 @@ gcry_mpi_powm (gcry_mpi_t res, _gcry_mpih_divmod. With 50% probability the result after this loop will be in the area originally pointed by RP (==RES->d), and with 50% probability in the area originally pointed to by XP. */ + rsign = bsign; + if (W == 1) + { + rsize = bsize; + } + else + { + rsize = msize; + MPN_ZERO (rp, rsize); + } + MPN_COPY ( rp, bp, bsize ); + + e = ep[i]; + count_leading_zeros (c, e); + e = (e << c) << 1; + c = BITS_PER_MPI_LIMB - 1 - c; + + j = 0; + for (;;) + if (e == 0) + { + j += c; + i--; + if ( i < 0 ) + { + c = 0; + break; + } + + e = ep[i]; + c = BITS_PER_MPI_LIMB; + } + else + { + int c0; + mpi_limb_t e0; + + count_leading_zeros (c0, e); + e = (e << c0); + c -= c0; + j += c0; + + if (c >= W) + { + e0 = (e >> (BITS_PER_MPI_LIMB - W)); + e = (e << W); + c -= W; + } + else + { + i--; + if ( i < 0 ) + { + e = (e >> (BITS_PER_MPI_LIMB - c)); + break; + } + + c0 = c; + e0 = (e >> (BITS_PER_MPI_LIMB - W)) + | (ep[i] >> (BITS_PER_MPI_LIMB - W + c0)); + e = (ep[i] << (W - c0)); + c = BITS_PER_MPI_LIMB - W + c0; + } + + count_trailing_zeros (c0, e0); + e0 = (e0 >> c0) >> 1; + + for (j += W - c0; j; j--) + { + mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx); + tp = rp; rp = xp; xp = tp; + rsize = xsize; + } + + if (e0 == 0) + { + g_k = bp; + g_k_size = bsize; + } + else + { + g_k = g[e0 - 1]; + g_k_size = gsize[e0 -1]; + } + + mul_mod (xp, &xsize, rp, rsize, g_k, g_k_size, mp, msize, &karactx); + tp = rp; rp = xp; xp = tp; + rsize = xsize; + + j = c0; + } + + if (c != 0) { - while (c) - { - mpi_ptr_t tp; - mpi_size_t xsize; - - /*mpih_mul_n(xp, rp, rp, rsize);*/ - if ( rsize < KARATSUBA_THRESHOLD ) - _gcry_mpih_sqr_n_basecase( xp, rp, rsize ); - else - { - if ( !tspace ) - { - tsize = 2 * rsize; - tspace = mpi_alloc_limb_space( tsize, 0 ); - } - else if ( tsize < (2*rsize) ) - { - _gcry_mpi_free_limb_space (tspace, 0); - tsize = 2 * rsize; - tspace = mpi_alloc_limb_space (tsize, 0 ); - } - _gcry_mpih_sqr_n (xp, rp, rsize, tspace); - } - - xsize = 2 * rsize; - if ( xsize > msize ) - { - _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); - xsize = msize; - } - - tp = rp; rp = xp; xp = tp; - rsize = xsize; - - /* To mitigate the Yarom/Falkner flush+reload cache - * side-channel attack on the RSA secret exponent, we do - * the multiplication regardless of the value of the - * high-bit of E. But to avoid this performance penalty - * we do it only if the exponent has been stored in secure - * memory and we can thus assume it is a secret exponent. */ - if (esec || (mpi_limb_signed_t)e < 0) - { - /*mpih_mul( xp, rp, rsize, bp, bsize );*/ - if( bsize < KARATSUBA_THRESHOLD ) - _gcry_mpih_mul ( xp, rp, rsize, bp, bsize ); - else - _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, bp, bsize, - &karactx); - - xsize = rsize + bsize; - if ( xsize > msize ) - { - _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); - xsize = msize; - } - } - if ( (mpi_limb_signed_t)e < 0 ) - { - tp = rp; rp = xp; xp = tp; - rsize = xsize; - } - e <<= 1; - c--; - } + j += c; + count_trailing_zeros (c, e); + e = (e >> c); + j -= c; + } - i--; - if ( i < 0 ) - break; - e = ep[i]; - c = BITS_PER_MPI_LIMB; + while (j--) + { + mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx); + tp = rp; rp = xp; xp = tp; + rsize = xsize; + } + + if (e != 0) + { + if ((e>>1) == 0) + { + g_k = bp; + g_k_size = bsize; + } + else + { + g_k = g[(e>>1) - 1]; + g_k_size = gsize[(e>>1) -1]; + } + + mul_mod (xp, &xsize, rp, rsize, g_k, g_k_size, mp, msize, &karactx); + tp = rp; rp = xp; xp = tp; + rsize = xsize; + + for (; c; c--) + { + mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx); + tp = rp; rp = xp; xp = tp; + rsize = xsize; + } } /* We shifted MOD, the modulo reduction argument, left @@ -308,6 +430,8 @@ gcry_mpi_powm (gcry_mpi_t res, MPN_NORMALIZE (rp, rsize); _gcry_mpih_release_karatsuba_ctx (&karactx ); + for (i = 0; i < (1 << (W - 1)) - 1; i++) + _gcry_mpi_free_limb_space( g[i], esec ? gsize[i] : 0 ); } /* Fixup for negative results. */ @@ -333,6 +457,4 @@ gcry_mpi_powm (gcry_mpi_t res, _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs ); if (xp_marker) _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs ); - if (tspace) - _gcry_mpi_free_limb_space( tspace, 0 ); } -- From jussi.kivilinna at iki.fi Fri Sep 6 22:57:01 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Fri, 06 Sep 2013 23:57:01 +0300 Subject: [PATCH] scrypt: fix for big-endian systems Message-ID: <20130906205701.3981.13181.stgit@localhost6.localdomain6> * cipher/scrypt.c (_salsa20_core): Fix endianess issues. -- On big-endian systems 'tests/t-kdf' was failing scrypt tests. Patch fixes the issue. Signed-off-by: Jussi Kivilinna --- cipher/scrypt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cipher/scrypt.c b/cipher/scrypt.c index 06196d6..9e29288 100644 --- a/cipher/scrypt.c +++ b/cipher/scrypt.c @@ -107,7 +107,9 @@ _salsa20_core(u32 *dst, const u32 *src, unsigned rounds) assert ( (rounds & 1) == 0); - memcpy (x, src, sizeof(x)); + for (i = 0; i < SALSA20_INPUT_LENGTH; i++) + x[i] = LE_SWAP32(src[i]); + for (i = 0; i < rounds;i += 2) { QROUND(x[0], x[4], x[8], x[12]); @@ -123,8 +125,8 @@ _salsa20_core(u32 *dst, const u32 *src, unsigned rounds) for (i = 0; i < SALSA20_INPUT_LENGTH; i++) { - u32 t = x[i] + src[i]; - dst[i] = LE_SWAP32 (t); + u32 t = x[i] + LE_SWAP32(src[i]); + dst[i] = LE_SWAP32(t); } } From wk at gnupg.org Sat Sep 7 10:16:48 2013 From: wk at gnupg.org (Werner Koch) Date: Sat, 07 Sep 2013 10:16:48 +0200 Subject: mpi: Suppress newer gcc warnings. In-Reply-To: <52282FDE.2030403@iki.fi> (Jussi Kivilinna's message of "Thu, 05 Sep 2013 10:16:46 +0300") References: <52282FDE.2030403@iki.fi> Message-ID: <87li39hwr3.fsf@vigenere.g10code.de> On Thu, 5 Sep 2013 09:16, jussi.kivilinna at iki.fi said: > Or is just having __GNUC__ > 2 enough? GCC manuals for 3.0.4 and 2.95.3 show support for 'unused' attribute. I am not sure about this. It is easier to require a later version of gcc than to test it with all that old versions. Sure the code is buggy and we should also check whether I did the same c+p error elsewhere. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Sat Sep 7 10:24:49 2013 From: wk at gnupg.org (Werner Koch) Date: Sat, 07 Sep 2013 10:24:49 +0200 Subject: [PATCH v2] Add support for Salsa20/12 - 12 round version of Salsa20 In-Reply-To: <1378374131-25733-1-git-send-email-dbaryshkov@gmail.com> (Dmitry Eremin-Solenikov's message of "Thu, 5 Sep 2013 13:42:11 +0400") References: <1378374131-25733-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <87bo45hwdq.fsf@vigenere.g10code.de> Thanks. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Tue Sep 10 09:43:19 2013 From: wk at gnupg.org (Werner Koch) Date: Tue, 10 Sep 2013 09:43:19 +0200 Subject: Got stuck with Ed25519 Message-ID: <874n9t9l60.fsf@vigenere.g10code.de> Hi, I am trying to implement the ED25519 signature scheme (as a step to Curve25519 world domination ;-). The plan is to have a generic implementation for Twisted Edwards curves and then later optimize it. Thus the PD code by DJB et al. is not yet usable. However, I get stuck with the implementation and would appreciate some help. I have attached a patch against current master (90fdf25) which implements the math. However, something is badly wrong. Output of the test program is: $ ./t-mpi-point --verbose t-mpi-point: checking point setting functions t-mpi-point: checking context functions t-mpi-point: checking standard curves t-mpi-point: checking sample public key t-mpi-point: checking basic math functions for EC t-mpi-point: checking basic math functions for EC (variant) t-mpi-point: checking basic Twisted Edwards math t-mpi-point: twistededwards_math: failed assertion: nG == (0,1) nG.x: 229171B146DF6E0B7BF69DBB70641CE5893DE9E7D1B5A16F4B9C5B86AD3BBBE4 nG.y: 40D64B6B3C2B4AA965E6ECC890722DE29C1A03B37255822E18515A214AAB6FBB nG.z: 33046B465045AC705194688838033890488E7AD521DCEB534D9D171C4D329D08 .x: 2746918A09C779B2258698FD5F07F82890CB8209A09660CA31FE9D5E86F74AA7 .y: 2E29127DF0E0833A0D60EA1E75C5E233217858D573F17348D5319A7F57BD1BA3 The expected output is .x=0,.y=1. I really don't understand what's going on wrong here. If I would use if (x) gcry_mpi_div (x, NULL, point->x, point->z, -1); if (y) gcry_mpi_div (y, NULL, point->y, point->z, -1); in mpi/ec.c:_gcry_mpi_ec_get_affine this works but that is of course wrong, because modular arithmetic is needed. It works only in this special case. The addition on Twisted Edwards curve does not need any special treatment for the neutral element, thus in theory the code should be correct. If someone could point me to another generic implementation for Edwards curves this might also be helpful. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: edwards.diff Type: text/x-diff Size: 18597 bytes Desc: not available URL: From gniibe at fsij.org Wed Sep 11 02:30:43 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Wed, 11 Sep 2013 09:30:43 +0900 Subject: Got stuck with Ed25519 In-Reply-To: <874n9t9l60.fsf@vigenere.g10code.de> References: <874n9t9l60.fsf@vigenere.g10code.de> Message-ID: <1378859443.31633.0.camel@latx1.gniibe.org> On 2013-09-10 at 09:43 +0200, Werner Koch wrote: > The expected output is .x=0,.y=1. I really don't understand what's > going on wrong here. Here is the change over your patch. It works fine for me. (1) Z1 should be p1->z. I think that it's a kind of typo. (2) Comment fix Z_3 should be Z_2. (3) X3 might be same place where X2 refers. Need to use TMP, at first. (4) NBITS should not be number of bits of SCALAR minus 1, but number of bits itself. diff --git a/mpi/ec.c b/mpi/ec.c index d0f25c4..1d6a6a7 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1081,7 +1081,7 @@ add_points_twistededwards (mpi_point_t result, { #define X1 (p1->x) #define Y1 (p1->y) -#define Z1 (p2->z) +#define Z1 (p1->z) #define X2 (p2->x) #define Y2 (p2->y) #define Z2 (p2->z) @@ -1097,7 +1097,7 @@ add_points_twistededwards (mpi_point_t result, #define G (ctx->t.scratch[6]) #define tmp (ctx->t.scratch[7]) - /* Compute: (X_3 : Y_3 : Z_3) = (X_1 : Y_1 : Z_1) + (X_2 : Y_2 : Z_3) */ + /* Compute: (X_3 : Y_3 : Z_3) = (X_1 : Y_1 : Z_1) + (X_2 : Y_2 : Z_2) */ /* A = Z1 ? Z2 */ ec_mulm (A, Z1, Z2, ctx); @@ -1122,8 +1122,8 @@ add_points_twistededwards (mpi_point_t result, ec_addm (G, B, E, ctx); /* X_3 = A ? F ? ((X_1 + Y_1) ? (X_2 + Y_2) - C - D) */ - ec_addm (X3, X1, Y1, ctx); - ec_addm (tmp, X2, Y2, ctx); + ec_addm (tmp, X1, Y1, ctx); + ec_addm (X3, X2, Y2, ctx); ec_mulm (X3, X3, tmp, ctx); ec_subm (X3, X3, C, ctx); ec_subm (X3, X3, D, ctx); @@ -1230,7 +1230,7 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, unsigned int nbits; int j; - nbits = mpi_get_nbits (scalar) - 1; + nbits = mpi_get_nbits (scalar); mpi_set_ui (result->x, 0); mpi_set_ui (result->y, 1); mpi_set_ui (result->z, 1); -- From gniibe at fsij.org Wed Sep 11 02:44:10 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Wed, 11 Sep 2013 09:44:10 +0900 Subject: Got stuck with Ed25519 In-Reply-To: <1378859443.31633.0.camel@latx1.gniibe.org> References: <874n9t9l60.fsf@vigenere.g10code.de> <1378859443.31633.0.camel@latx1.gniibe.org> Message-ID: <1378860250.31633.1.camel@latx1.gniibe.org> On 2013-09-11 at 09:30 +0900, NIIBE Yutaka wrote: > Here is the change over your patch. It works fine for me. Besides, it seems for me that mpi-pow.c has a bug when it is called with negative base and expo is even (result is positive). I don't test it though. diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 85d6fd8..ff7a462 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -169,7 +169,7 @@ gcry_mpi_powm (gcry_mpi_t res, } MPN_COPY ( rp, bp, bsize ); rsize = bsize; - rsign = bsign; + rsign = 0; /* Main processing. */ { Anther thing I am not sure is about the definition of Ed25519. I only read a paper of twisted-20080313.pdf, by DJB et al. I'm a newbie in this area, but I thought that it's something like: I'm sure that it's me who is wrong. Please let me know a reference. diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index aa32794..e8d5c87 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -96,10 +96,10 @@ static const ecc_domain_parms_t domain_parms[] = "Ed25519", 256, 0, MPI_EC_TWISTEDEDWARDS, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "-0x01", - "-0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4", + "0x1db42", + "0x1db41", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", - "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", + "0x5707795FBCC143CC45B2B85332E917972AE291B229B8D23DBAE60B8D00032832", "0x6666666666666666666666666666666666666666666666666666666666666658" }, { -- From wk at gnupg.org Wed Sep 11 09:28:12 2013 From: wk at gnupg.org (Werner Koch) Date: Wed, 11 Sep 2013 09:28:12 +0200 Subject: Got stuck with Ed25519 In-Reply-To: <1378859443.31633.0.camel@latx1.gniibe.org> (NIIBE Yutaka's message of "Wed, 11 Sep 2013 09:30:43 +0900") References: <874n9t9l60.fsf@vigenere.g10code.de> <1378859443.31633.0.camel@latx1.gniibe.org> Message-ID: <87vc276cmr.fsf@vigenere.g10code.de> On Wed, 11 Sep 2013 02:30, gniibe at fsij.org said: > Here is the change over your patch. It works fine for me. Many thanks. I should have asked earlier. Pretty obvious bugs but we all know that it is sometimes virtually impossible to detect one own bugs. > (1) Z1 should be p1->z. I think that it's a kind of typo. And I checked that a dozen times :-(. > (3) X3 might be same place where X2 refers. Need to use TMP, at first. Good point. > (4) NBITS should not be number of bits of SCALAR minus 1, but > number of bits itself. That was actually a leftover from another test. Works now. Now for the rest of the code. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Wed Sep 11 09:35:01 2013 From: wk at gnupg.org (Werner Koch) Date: Wed, 11 Sep 2013 09:35:01 +0200 Subject: Got stuck with Ed25519 In-Reply-To: <1378860250.31633.1.camel@latx1.gniibe.org> (NIIBE Yutaka's message of "Wed, 11 Sep 2013 09:44:10 +0900") References: <874n9t9l60.fsf@vigenere.g10code.de> <1378859443.31633.0.camel@latx1.gniibe.org> <1378860250.31633.1.camel@latx1.gniibe.org> Message-ID: <87r4cv6cbe.fsf@vigenere.g10code.de> On Wed, 11 Sep 2013 02:44, gniibe at fsij.org said: > Besides, it seems for me that mpi-pow.c has a bug when it is called > with negative base and expo is even (result is positive). I don't > test it though. I first thought the same but actually the sign is implementation defined. http://en.wikipedia.org/wiki/Modulo_operation has a table describing this. We should not change that because that would be an ABI change. Instead I cleared the sign in ec_powm. > - "-0x01", > - "-0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4", > + "0x1db42", > + "0x1db41", Right, you could get that impression from the paper. However, another paper describes tricks to improve the performance and there it is better that A is -1 despite that you will have a long D. The whole EC stuff is pretty interesting but requires a lot of reading. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From gniibe at fsij.org Thu Sep 12 03:17:00 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 12 Sep 2013 10:17:00 +0900 Subject: Got stuck with Ed25519 In-Reply-To: <87r4cv6cbe.fsf@vigenere.g10code.de> References: <874n9t9l60.fsf@vigenere.g10code.de> <1378859443.31633.0.camel@latx1.gniibe.org> <1378860250.31633.1.camel@latx1.gniibe.org> <87r4cv6cbe.fsf@vigenere.g10code.de> Message-ID: <1378948620.3176.3.camel@cfw2.gniibe.org> On 2013-09-11 at 09:35 +0200, Werner Koch wrote: > On Wed, 11 Sep 2013 02:44, gniibe at fsij.org said: > > > Besides, it seems for me that mpi-pow.c has a bug when it is called > > with negative base and expo is even (result is positive). I don't > > test it though. > > I first thought the same but actually the sign is implementation > defined. http://en.wikipedia.org/wiki/Modulo_operation has a table > describing this. We should not change that because that would be an ABI > change. Instead I cleared the sign in ec_powm. Thanks for the reference for modulo operation. That's useful for me. However, it is BASE (not MOD), which we are talking about, now. Well, I wrote a test case to share the issue. Here is a possible patch. In the test case, it calculates (-17)^6 mod 19. Result should be 7. Mathematically, it's also correct for powm to return -12 in this case, but it checks against positive 7. In the current implementation it returns -7, which is wrong. diff --git a/tests/mpitests.c b/tests/mpitests.c index e1c51d1..ae206d7 100644 --- a/tests/mpitests.c +++ b/tests/mpitests.c @@ -379,6 +379,25 @@ test_powm (void) if (gcry_mpi_cmp (res, base)) die ("test_powm failed at %d\n", __LINE__); + /* Check for a case: base is negative and expo is even. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_neg (base, base); + gcry_mpi_set_ui (exp, e_int * 2); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (res, base, exp, mod); + /* Result should be positive and it's 7 = (-17)^6 mod 19. */ + if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7)) + { + if (verbose) + { + fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res)); + fprintf (stderr, "mpi: "); + gcry_mpi_dump (res); + putc ('\n', stderr); + } + die ("test_powm failed for negative base at %d\n", __LINE__); + } + gcry_mpi_release (base); gcry_mpi_release (exp); gcry_mpi_release (mod); diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 85d6fd8..4955fa5 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -169,7 +169,7 @@ gcry_mpi_powm (gcry_mpi_t res, } MPN_COPY ( rp, bp, bsize ); rsize = bsize; - rsign = bsign; + rsign = 0; /* Main processing. */ { @@ -184,7 +184,7 @@ gcry_mpi_powm (gcry_mpi_t res, xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec ); memset( &karactx, 0, sizeof karactx ); - negative_result = (ep[0] & 1) && base->sign; + negative_result = (ep[0] & 1) && bsign; i = esize - 1; e = ep[i]; -- From wachs at net.in.tum.de Thu Sep 12 09:24:08 2013 From: wachs at net.in.tum.de (Matthias Wachs) Date: Thu, 12 Sep 2013 09:24:08 +0200 Subject: compiling guix with libgcrypt from git Message-ID: <1378970648.16315.69.camel@fulcrum.net.in.tum.de> Hi libgcrypt developers, I am trying to compile the guix package manager with libgcrypt from git. With 1.5.3 it's compiling, but not with the git version. Guix developers told me that I should talk to you, as gcry_md_algo_t is not deprecated. It fails to compile with: g++ -DHAVE_CONFIG_H -I. -I./nix -I./nix -I./nix/libutil -I./nix -g -O2 -MT nix/libutil/libutil_a-hash.o -MD -MP -MF nix/libutil/.deps/libutil_a-hash.Tpo -c -o nix/libutil/libutil_a-hash.o `test -f 'nix/libutil/hash.cc' || echo './'`nix/libutil/hash.cc In file included from nix/libutil/md5.h:19:0, from nix/libutil/hash.cc:11: ./nix/libutil/gcrypt-hash.hh:33:60: error: ?gcry_md_algo_t? has not been > declared ./nix/libutil/gcrypt-hash.hh:37:9: error: ?gcry_md_algo_t? has not been declared make[2]: *** [nix/libutil/libutil_a-hash.o] Error 1 In idea about that? TIA ... and please don't shoot the messenger ... -Matthias -- Dipl.-Inf. Matthias Wachs Free Secure Network Systems Group Technische Universitaet Muenchen Chair for Network Architectures and Services Institute for Informatics / I8 Tel: +49 89 289 18037 Boltzmannstr. 3 / Room 03.05.042 Fax: +49 89 289 18033 D-85748 Garching b. Muenchen, Germany Email: wachs at net.in.tum.de -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 490 bytes Desc: This is a digitally signed message part URL: From gniibe at fsij.org Thu Sep 12 10:07:14 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 12 Sep 2013 17:07:14 +0900 Subject: compiling guix with libgcrypt from git In-Reply-To: <1378970648.16315.69.camel@fulcrum.net.in.tum.de> References: <1378970648.16315.69.camel@fulcrum.net.in.tum.de> Message-ID: <1378973234.3176.12.camel@cfw2.gniibe.org> On 2013-09-12 at 09:24 +0200, Matthias Wachs wrote: > Guix developers told me that I should talk to you, as gcry_md_algo_t is > not deprecated. I think that it was internal of libgcrypt, not external interface. The type was removed when AC interface was removed in 2011-09-15. The commit diff is: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff;h=fc9eec3626fcb9a3d4043d779462c4fc39cd51ae Documentation says: -- Function: gcry_error_t gcry_md_open (gcry_md_hd_t *HD, int ALGO, unsigned int FLAGS) Create a message digest object for algorithm ALGO. FLAGS may be given as an bitwise OR of constants described below. ALGO may be given as `0' if the algorithms to use are later set using `gcry_md_enable'. HD is guaranteed to either receive a valid handle or NULL. Here, ALGO's type is integer. It is not gcry_md_algo_t. -- From ludo at gnu.org Thu Sep 12 14:12:25 2013 From: ludo at gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) Date: Thu, 12 Sep 2013 14:12:25 +0200 Subject: compiling guix with libgcrypt from git In-Reply-To: <1378973234.3176.12.camel@cfw2.gniibe.org> (NIIBE Yutaka's message of "Thu, 12 Sep 2013 17:07:14 +0900") References: <1378970648.16315.69.camel@fulcrum.net.in.tum.de> <1378973234.3176.12.camel@cfw2.gniibe.org> Message-ID: <87fvtap7bq.fsf@gnu.org> NIIBE Yutaka skribis: > On 2013-09-12 at 09:24 +0200, Matthias Wachs wrote: >> Guix developers told me that I should talk to you, as gcry_md_algo_t is >> not deprecated. > > I think that it was internal of libgcrypt, not external interface. > > The type was removed when AC interface was removed in 2011-09-15. > The commit diff is: > > http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff;h=fc9eec3626fcb9a3d4043d779462c4fc39cd51ae > > Documentation says: > > -- Function: gcry_error_t gcry_md_open (gcry_md_hd_t *HD, int ALGO, > unsigned int FLAGS) > Create a message digest object for algorithm ALGO. FLAGS may be > given as an bitwise OR of constants described below. ALGO may be > given as `0' if the algorithms to use are later set using > `gcry_md_enable'. HD is guaranteed to either receive a valid > handle or NULL. > > Here, ALGO's type is integer. It is not gcry_md_algo_t. Indeed, my bad. This is now fixed: http://git.sv.gnu.org/cgit/guix.git/commit/?id=ea1673808584f3c40cc76cc2ea570676309ba5bc Thanks! Ludo?. From wk at gnupg.org Wed Sep 18 14:58:12 2013 From: wk at gnupg.org (Werner Koch) Date: Wed, 18 Sep 2013 14:58:12 +0200 Subject: [PATCH 1/5] Add limited implementation of GOST 28147-89 cipher In-Reply-To: <871u55n53u.fsf@vigenere.g10code.de> (Werner Koch's message of "Tue, 03 Sep 2013 20:16:05 +0200") References: <1378114132-7587-1-git-send-email-dbaryshkov@gmail.com> <871u55n53u.fsf@vigenere.g10code.de> Message-ID: <87a9jawal7.fsf@vigenere.g10code.de> Hi, I just pushed your 5 patches. I also did an additional pacth to rename the algorithm identifiers to shorter names etc. Thanks, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From jussi.kivilinna at iki.fi Wed Sep 18 16:26:34 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Wed, 18 Sep 2013 17:26:34 +0300 Subject: [PATCH] Fix encryption/decryption return type for GOST28147 Message-ID: <20130918142634.7650.45794.stgit@localhost6.localdomain6> * cipher/gost.h (_gcry_gost_enc_one): Change return type to 'unsigned int'. * cipher/gost28147.c (max): New macro. (gost_encrypt_block, gost_decrypt_block): Return burn stack depth. (_gcry_gost_enc_one): Return burn stack depth from gost_encrypt_block. -- Return type for block cipher functions was lately changed from 'void' to 'unsigned int' to pass burn stack depth to cipher mode code. Patch fixes gost28147 to return stack burn value. Signed-off-by: Jussi Kivilinna --- cipher/gost.h | 2 +- cipher/gost28147.c | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/cipher/gost.h b/cipher/gost.h index e1cf033..42021aa 100644 --- a/cipher/gost.h +++ b/cipher/gost.h @@ -27,7 +27,7 @@ typedef struct { } GOST28147_context; /* This is a simple interface that will be used by GOST R 34.11-94 */ -extern void _gcry_gost_enc_one (GOST28147_context *c, const byte *key, +extern unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, byte *out, byte *in); #endif diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 5d6d1e7..862e7d6 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -35,6 +35,9 @@ #include "cipher.h" +#define max(a, b) (((a) > (b)) ? (a) : (b)) + + /* This is an s-box from RFC4357, named GostR3411-94-TestParamSet * For now it is the only s-box supported, as libgcrypt lacks mechanism * for passing parameters to cipher in a usefull way. */ @@ -107,7 +110,7 @@ gost_val (GOST28147_context *ctx, u32 cm1, int subkey) return (cm1 << 11) | (cm1 >> 21); } -static void +static unsigned int gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) { GOST28147_context *ctx = c; @@ -153,16 +156,22 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; + + return /* burn_stack */ 4*sizeof(void*) /* func call */ + + 3*sizeof(void*) /* stack */ + + max( 4*sizeof(void*) /* gost_val call */, + 3*sizeof(void*) /* gost_set_subst call */ + + 2*sizeof(void*) /* gost_set subst stack*/ ); } -void _gcry_gost_enc_one (GOST28147_context *c, const byte *key, +unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, byte *out, byte *in) { gost_setkey (c, key, 32); - gost_encrypt_block (c, out, in); + return gost_encrypt_block (c, out, in); } -static void +static unsigned int gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) { GOST28147_context *ctx = c; @@ -208,6 +217,12 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; + + return /* burn_stack */ 4*sizeof(void*) /* func call */ + + 3*sizeof(void*) /* stack */ + + max( 4*sizeof(void*) /* gost_val call */, + 3*sizeof(void*) /* gost_set_subst call */ + + 2*sizeof(void*) /* gost_set subst stack*/ ); } gcry_cipher_spec_t _gcry_cipher_spec_gost28147 = From dbaryshkov at gmail.com Wed Sep 18 17:18:41 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Wed, 18 Sep 2013 19:18:41 +0400 Subject: [PATCH] Fix encryption/decryption return type for GOST28147 In-Reply-To: <20130918142634.7650.45794.stgit@localhost6.localdomain6> References: <20130918142634.7650.45794.stgit@localhost6.localdomain6> Message-ID: On Wed, Sep 18, 2013 at 6:26 PM, Jussi Kivilinna wrote: > * cipher/gost.h (_gcry_gost_enc_one): Change return type to > 'unsigned int'. > * cipher/gost28147.c (max): New macro. > (gost_encrypt_block, gost_decrypt_block): Return burn stack depth. > (_gcry_gost_enc_one): Return burn stack depth from gost_encrypt_block. > -- > > Return type for block cipher functions was lately changed from 'void' to > 'unsigned int' to pass burn stack depth to cipher mode code. Patch fixes > gost28147 to return stack burn value. > > Signed-off-by: Jussi Kivilinna > --- > cipher/gost.h | 2 +- > cipher/gost28147.c | 23 +++++++++++++++++++---- > 2 files changed, 20 insertions(+), 5 deletions(-) > > diff --git a/cipher/gost.h b/cipher/gost.h > index e1cf033..42021aa 100644 > --- a/cipher/gost.h > +++ b/cipher/gost.h > @@ -27,7 +27,7 @@ typedef struct { > } GOST28147_context; > > /* This is a simple interface that will be used by GOST R 34.11-94 */ > -extern void _gcry_gost_enc_one (GOST28147_context *c, const byte *key, > +extern unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, > byte *out, byte *in); > > #endif > diff --git a/cipher/gost28147.c b/cipher/gost28147.c > index 5d6d1e7..862e7d6 100644 > --- a/cipher/gost28147.c > +++ b/cipher/gost28147.c > @@ -35,6 +35,9 @@ > #include "cipher.h" > > > +#define max(a, b) (((a) > (b)) ? (a) : (b)) > + > + > /* This is an s-box from RFC4357, named GostR3411-94-TestParamSet > * For now it is the only s-box supported, as libgcrypt lacks mechanism > * for passing parameters to cipher in a usefull way. */ > @@ -107,7 +110,7 @@ gost_val (GOST28147_context *ctx, u32 cm1, int subkey) > return (cm1 << 11) | (cm1 >> 21); > } > > -static void > +static unsigned int > gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) > { > GOST28147_context *ctx = c; > @@ -153,16 +156,22 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) > outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; > outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; > outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; > + > + return /* burn_stack */ 4*sizeof(void*) /* func call */ + > + 3*sizeof(void*) /* stack */ + > + max( 4*sizeof(void*) /* gost_val call */, > + 3*sizeof(void*) /* gost_set_subst call */ + > + 2*sizeof(void*) /* gost_set subst stack*/ ); I think you can be pretty much sure here that 4 is less than 3 + 2, can't you? And also it looks like you have forgot those n1 and n2 variables... I would suggest to just select 384 or 512 and don't get into details of stack. What do you think? -- With best wishes Dmitry From jussi.kivilinna at iki.fi Wed Sep 18 17:29:42 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Wed, 18 Sep 2013 18:29:42 +0300 Subject: [PATCH] Fix encryption/decryption return type for GOST28147 In-Reply-To: References: <20130918142634.7650.45794.stgit@localhost6.localdomain6> Message-ID: <5239C6E6.80500@iki.fi> I should have checked email before pushing this patch to repo.. On 18.09.2013 18:18, Dmitry Eremin-Solenikov wrote: >> + >> + return /* burn_stack */ 4*sizeof(void*) /* func call */ + >> + 3*sizeof(void*) /* stack */ + >> + max( 4*sizeof(void*) /* gost_val call */, >> + 3*sizeof(void*) /* gost_set_subst call */ + >> + 2*sizeof(void*) /* gost_set subst stack*/ ); > > I think you can be pretty much sure here that 4 is less than 3 + 2, can't you? It shows where values come from. > And also it looks like you have forgot those n1 and n2 variables... "3*sizeof(void*) /* stack */" has ctx, n1 and n2. Sure, I could have had just 'sizeof(void*) + sizeof(int)*2'. > I would suggest to just select 384 or 512 and don't get into details of stack. > What do you think? I'd have stack burn values opened up instead of magic numbers to avoid making mistakes. The above gives 96 bytes with 64-bit pointers and 48 with 32-bit. -Jussi From dbaryshkov at gmail.com Mon Sep 16 04:55:13 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 16 Sep 2013 06:55:13 +0400 Subject: [PATCH] Fix Stribog digest on bigendian platforms Message-ID: <1379300113-22064-1-git-send-email-dbaryshkov@gmail.com> * cipher/stribog.c (stribog_final): swap bytes in the result of digest calculations. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/stribog.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cipher/stribog.c b/cipher/stribog.c index 979045e..ec7ffe9 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -1394,6 +1394,21 @@ stribog_final (void *context) g (hd->h, hd->N, Z); g (hd->h, hd->Sigma, Z); + +#ifdef WORDS_BIGENDIAN + for (i = 0; i < 8; i++) + { + u64 T = hd->h[i]; + T = ((T & U64_C(0x00ff00ff00ff00ff)) << 8) | + ((T & U64_C(0xff00ff00ff00ff00)) >> 8); + T = ((T & U64_C(0x0000ffff0000ffff)) << 16) | + ((T & U64_C(0xffff0000ffff0000)) >> 16); + T = ((T & U64_C(0x00000000ffffffff)) << 32) | + ((T & U64_C(0xffffffff00000000)) >> 32); + hd->h[i] = T; + } +#endif + _gcry_burn_stack (768); } -- 1.8.4.rc3 From jussi.kivilinna at iki.fi Thu Sep 19 12:09:57 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 13:09:57 +0300 Subject: [PATCH 1/2] Make SHA-512 use the new _gcry_md_block_write helper Message-ID: <20130919100957.9331.21972.stgit@localhost6.localdomain6> * cipher/hash-common.c (_gcry_md_block_write): Check that hd->buf is large enough. * cipher/hash-common.h (MD_BLOCK_MAX_BLOCKSIZE, MD_NBLOCKS_TYPE): New macros. (gcry_md_block_ctx_t): Use above macros for 'nblocks' and 'buf'. * cipher/sha512.c (SHA512_STATE): New struct. (SHA512_CONTEXT): Add 'bctx' and 'state'. (sha512_init, sha384_init): Initialize 'bctx'. (__transform, _gcry_sha512_transform_armv7_neon): Use SHA512_STATE for 'hd'. (transform): For now, do not return burn stack. (sha512_write): Remove. (sha512_final): Use _gcry_md_block_write and bctx. (_gcry_digest_spec_sha512, _gcry_digest_spec_sha384): Use _gcry_md_block_write. -- Patch changes 'nblocks' counter to 64-bits when SHA-512 is enabled. This does not cause problems with other algorithms; they are already casting 'nblocks' to u32 variable in their finalization functions. Also move 'buf' member to head of 'gcry_md_block_ctx_t' to ensure proper alignment; this is because some algorithms cast buffer pointer to (u64*) in final endian conversion. Signed-off-by: Jussi Kivilinna --- cipher/hash-common.c | 5 + cipher/hash-common.h | 17 ++++- cipher/sha512.c | 179 ++++++++++++++++++++++---------------------------- 3 files changed, 97 insertions(+), 104 deletions(-) diff --git a/cipher/hash-common.c b/cipher/hash-common.c index a823a66..1a6e8e9 100644 --- a/cipher/hash-common.c +++ b/cipher/hash-common.c @@ -102,7 +102,10 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen) const unsigned char *inbuf = inbuf_arg; gcry_md_block_ctx_t *hd = context; - if ( hd->buf == NULL || hd->bwrite == NULL) + if (sizeof(hd->buf) < hd->blocksize) + BUG(); + + if (hd->buf == NULL || hd->bwrite == NULL) return; if (hd->count == hd->blocksize) /* Flush the buffer. */ diff --git a/cipher/hash-common.h b/cipher/hash-common.h index 1d1d4ec..4dd5441 100644 --- a/cipher/hash-common.h +++ b/cipher/hash-common.h @@ -20,6 +20,8 @@ #ifndef GCRY_HASH_COMMON_H #define GCRY_HASH_COMMON_H +#include "types.h" + const char * _gcry_hash_selftest_check_one /**/ (int algo, @@ -29,11 +31,20 @@ const char * _gcry_hash_selftest_check_one /* Type for the md_write helper function. */ typedef void (*_gcry_md_block_write_t) (void *c, const unsigned char *buf); +#if defined(HAVE_U64_TYPEDEF) && defined(USE_SHA512) +/* SHA-512 needs u64 and larger buffer. */ +# define MD_BLOCK_MAX_BLOCKSIZE 128 +# define MD_NBLOCKS_TYPE u64 +#else +# define MD_BLOCK_MAX_BLOCKSIZE 64 +# define MD_NBLOCKS_TYPE u32 +#endif + typedef struct gcry_md_block_ctx { - u32 nblocks; - int count; - byte buf[64]; + byte buf[MD_BLOCK_MAX_BLOCKSIZE]; + MD_NBLOCKS_TYPE nblocks; + int count; size_t blocksize; _gcry_md_block_write_t bwrite; size_t stack_burn; diff --git a/cipher/sha512.c b/cipher/sha512.c index fee3e71..ed63ae6 100644 --- a/cipher/sha512.c +++ b/cipher/sha512.c @@ -67,18 +67,25 @@ typedef struct { u64 h0, h1, h2, h3, h4, h5, h6, h7; - u64 nblocks; - byte buf[128]; - int count; +} SHA512_STATE; + +typedef struct +{ + gcry_md_block_ctx_t bctx; + SHA512_STATE state; #ifdef USE_ARM_NEON_ASM int use_neon; #endif } SHA512_CONTEXT; static void +transform (void *context, const unsigned char *data); + +static void sha512_init (void *context) { - SHA512_CONTEXT *hd = context; + SHA512_CONTEXT *ctx = context; + SHA512_STATE *hd = &ctx->state; hd->h0 = U64_C(0x6a09e667f3bcc908); hd->h1 = U64_C(0xbb67ae8584caa73b); @@ -89,17 +96,22 @@ sha512_init (void *context) hd->h6 = U64_C(0x1f83d9abfb41bd6b); hd->h7 = U64_C(0x5be0cd19137e2179); - hd->nblocks = 0; - hd->count = 0; + ctx->bctx.nblocks = 0; + ctx->bctx.count = 0; + ctx->bctx.blocksize = 128; + ctx->bctx.bwrite = transform; + ctx->bctx.stack_burn = 256; + #ifdef USE_ARM_NEON_ASM - hd->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; + ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; #endif } static void sha384_init (void *context) { - SHA512_CONTEXT *hd = context; + SHA512_CONTEXT *ctx = context; + SHA512_STATE *hd = &ctx->state; hd->h0 = U64_C(0xcbbb9d5dc1059ed8); hd->h1 = U64_C(0x629a292a367cd507); @@ -110,10 +122,14 @@ sha384_init (void *context) hd->h6 = U64_C(0xdb0c2e0d64f98fa7); hd->h7 = U64_C(0x47b5481dbefa4fa4); - hd->nblocks = 0; - hd->count = 0; + ctx->bctx.nblocks = 0; + ctx->bctx.count = 0; + ctx->bctx.blocksize = 128; + ctx->bctx.bwrite = transform; + ctx->bctx.stack_burn = 256; + #ifdef USE_ARM_NEON_ASM - hd->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; + ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; #endif } @@ -196,7 +212,7 @@ static const u64 k[] = * Transform the message W which consists of 16 64-bit-words */ static void -__transform (SHA512_CONTEXT *hd, const unsigned char *data) +__transform (SHA512_STATE *hd, const unsigned char *data) { u64 a, b, c, d, e, f, g, h; u64 w[16]; @@ -477,71 +493,33 @@ __transform (SHA512_CONTEXT *hd, const unsigned char *data) #ifdef USE_ARM_NEON_ASM -void _gcry_sha512_transform_armv7_neon (SHA512_CONTEXT *hd, +void _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd, const unsigned char *data, const u64 k[]); #endif -static unsigned int -transform (SHA512_CONTEXT *hd, const unsigned char *data) +static void +transform (void *context, const unsigned char *data) { + SHA512_CONTEXT *ctx = context; + #ifdef USE_ARM_NEON_ASM if (hd->use_neon) { - _gcry_sha512_transform_armv7_neon(hd, data, k); + _gcry_sha512_transform_armv7_neon(&ctx->state, data, k); + /* TODO: return burn stack to md_block_write */ /* return stack burn depth */ - return (sizeof(void *) * 3); + return /*(sizeof(void *) * 3)*/; } #endif - __transform (hd, data); + __transform (&ctx->state, data); + /* TODO: return burn stack to md_block_write */ /* return stack burn depth */ - return 256; -} - - -/* Update the message digest with the contents - * of INBUF with length INLEN. - */ -static void -sha512_write (void *context, const void *inbuf_arg, size_t inlen) -{ - const unsigned char *inbuf = inbuf_arg; - SHA512_CONTEXT *hd = context; - unsigned int stack_burn_depth = 0; - - if (hd->count == 128) - { /* flush the buffer */ - stack_burn_depth = transform (hd, hd->buf); - _gcry_burn_stack (stack_burn_depth); - hd->count = 0; - hd->nblocks++; - } - if (!inbuf) - return; - if (hd->count) - { - for (; inlen && hd->count < 128; inlen--) - hd->buf[hd->count++] = *inbuf++; - sha512_write (context, NULL, 0); - if (!inlen) - return; - } - - while (inlen >= 128) - { - stack_burn_depth = transform (hd, inbuf); - hd->count = 0; - hd->nblocks++; - inlen -= 128; - inbuf += 128; - } - _gcry_burn_stack (stack_burn_depth); - for (; inlen && hd->count < 128; inlen--) - hd->buf[hd->count++] = *inbuf++; + return /*256*/; } @@ -561,15 +539,15 @@ sha512_final (void *context) u64 t, msb, lsb; byte *p; - sha512_write (context, NULL, 0); /* flush */ ; + _gcry_md_block_write (context, NULL, 0); /* flush */ ; - t = hd->nblocks; + t = hd->bctx.nblocks; /* multiply by 128 to make a byte count */ lsb = t << 7; msb = t >> 57; /* add the count */ t = lsb; - if ((lsb += hd->count) < t) + if ((lsb += hd->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -577,49 +555,50 @@ sha512_final (void *context) msb <<= 3; msb |= t >> 61; - if (hd->count < 112) + if (hd->bctx.count < 112) { /* enough room */ - hd->buf[hd->count++] = 0x80; /* pad */ - while (hd->count < 112) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ + while (hd->bctx.count < 112) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else { /* need one extra block */ - hd->buf[hd->count++] = 0x80; /* pad character */ - while (hd->count < 128) - hd->buf[hd->count++] = 0; - sha512_write (context, NULL, 0); /* flush */ ; - memset (hd->buf, 0, 112); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ + while (hd->bctx.count < 128) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write (context, NULL, 0); /* flush */ ; + memset (hd->bctx.buf, 0, 112); /* fill next block with zeroes */ } /* append the 128 bit count */ - hd->buf[112] = msb >> 56; - hd->buf[113] = msb >> 48; - hd->buf[114] = msb >> 40; - hd->buf[115] = msb >> 32; - hd->buf[116] = msb >> 24; - hd->buf[117] = msb >> 16; - hd->buf[118] = msb >> 8; - hd->buf[119] = msb; - - hd->buf[120] = lsb >> 56; - hd->buf[121] = lsb >> 48; - hd->buf[122] = lsb >> 40; - hd->buf[123] = lsb >> 32; - hd->buf[124] = lsb >> 24; - hd->buf[125] = lsb >> 16; - hd->buf[126] = lsb >> 8; - hd->buf[127] = lsb; - stack_burn_depth = transform (hd, hd->buf); + hd->bctx.buf[112] = msb >> 56; + hd->bctx.buf[113] = msb >> 48; + hd->bctx.buf[114] = msb >> 40; + hd->bctx.buf[115] = msb >> 32; + hd->bctx.buf[116] = msb >> 24; + hd->bctx.buf[117] = msb >> 16; + hd->bctx.buf[118] = msb >> 8; + hd->bctx.buf[119] = msb; + + hd->bctx.buf[120] = lsb >> 56; + hd->bctx.buf[121] = lsb >> 48; + hd->bctx.buf[122] = lsb >> 40; + hd->bctx.buf[123] = lsb >> 32; + hd->bctx.buf[124] = lsb >> 24; + hd->bctx.buf[125] = lsb >> 16; + hd->bctx.buf[126] = lsb >> 8; + hd->bctx.buf[127] = lsb; + transform (hd, hd->bctx.buf); + stack_burn_depth = hd->bctx.stack_burn; _gcry_burn_stack (stack_burn_depth); - p = hd->buf; + p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN -#define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0) +#define X(a) do { *(u64*)p = hd->state.h##a ; p += 8; } while (0) #else /* little endian */ -#define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48; \ - *p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32; \ - *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ - *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while (0) +#define X(a) do { *p++ = hd->state.h##a >> 56; *p++ = hd->state.h##a >> 48; \ + *p++ = hd->state.h##a >> 40; *p++ = hd->state.h##a >> 32; \ + *p++ = hd->state.h##a >> 24; *p++ = hd->state.h##a >> 16; \ + *p++ = hd->state.h##a >> 8; *p++ = hd->state.h##a; } while(0) #endif X (0); X (1); @@ -638,7 +617,7 @@ static byte * sha512_read (void *context) { SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context; - return hd->buf; + return hd->bctx.buf; } @@ -797,7 +776,7 @@ static gcry_md_oid_spec_t oid_spec_sha512[] = gcry_md_spec_t _gcry_digest_spec_sha512 = { "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64, - sha512_init, sha512_write, sha512_final, sha512_read, + sha512_init, _gcry_md_block_write, sha512_final, sha512_read, sizeof (SHA512_CONTEXT), }; md_extra_spec_t _gcry_digest_extraspec_sha512 = @@ -825,7 +804,7 @@ static gcry_md_oid_spec_t oid_spec_sha384[] = gcry_md_spec_t _gcry_digest_spec_sha384 = { "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48, - sha384_init, sha512_write, sha512_final, sha512_read, + sha384_init, _gcry_md_block_write, sha512_final, sha512_read, sizeof (SHA512_CONTEXT), }; md_extra_spec_t _gcry_digest_extraspec_sha384 = From jussi.kivilinna at iki.fi Thu Sep 19 12:10:02 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 13:10:02 +0300 Subject: [PATCH 2/2] Make STRIBOG use the new _gcry_md_block_write helper In-Reply-To: <20130919100957.9331.21972.stgit@localhost6.localdomain6> References: <20130919100957.9331.21972.stgit@localhost6.localdomain6> Message-ID: <20130919101002.9331.60606.stgit@localhost6.localdomain6> * cipher/stribog.c (STRIBOG_STRUCT): Add 'bctx' and remove 'buf' and 'count'. (stribog_init_512): Initialize 'bctx'. (transform64): New function. (stribog_write): Remove. (stribog_final): Use _gcry_md_block_write and bctx. (_gcry_digest_spec_stribog_256, _gcry_digest_spec_stribog_512): Use _gcry_md_block_write. -- Signed-off-by: Jussi Kivilinna --- cipher/stribog.c | 55 +++++++++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/cipher/stribog.c b/cipher/stribog.c index ec7ffe9..961270c 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -32,6 +32,7 @@ typedef struct { + gcry_md_block_ctx_t bctx; union { u64 h[8]; @@ -39,8 +40,6 @@ typedef struct }; u64 N[8]; u64 Sigma[8]; - byte buf[64]; - int count; } STRIBOG_CONTEXT; static const byte Pi[256] = @@ -1276,11 +1275,19 @@ static void g (u64 *h, u64 *m, u64 *N) static void +transform64 (void *context, const void *inbuf_arg); + + +static void stribog_init_512 (void *context) { STRIBOG_CONTEXT *hd = context; memset (hd, 0, sizeof (*hd)); + + hd->bctx.blocksize = 64; + hd->bctx.bwrite = transform64; + hd->bctx.stack_burn = 768; } static void @@ -1340,35 +1347,11 @@ transform (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) } static void -stribog_write (void *context, const void *inbuf_arg, size_t inlen) +transform64 (void *context, const void *inbuf_arg) { STRIBOG_CONTEXT *hd = context; - const unsigned char *inbuf = inbuf_arg; - if (hd->count == 64) - { - transform (hd, hd->buf, hd->count * 8); - hd->count = 0; - _gcry_burn_stack (768); - } - if (!inbuf) - return; - if (hd->count) - { - for (; inlen && hd->count < 64; inlen--) - hd->buf[hd->count++] = *inbuf++; - stribog_write (context, NULL, 0); - if (!inlen) - return; - } - while (inlen >= 64) - { - transform (hd, inbuf, 64 * 8); - inlen -= 64; - inbuf += 64; - } - _gcry_burn_stack (768); - for (; inlen && hd->count < 64; inlen--) - hd->buf[hd->count++] = *inbuf++; + + transform (hd, inbuf_arg, 64 * 8); } /* @@ -1383,14 +1366,14 @@ stribog_final (void *context) u64 Z[8] = {}; int i; - stribog_write (context, NULL, 0); /* flush */ ; + _gcry_md_block_write (context, NULL, 0); /* flush */ ; /* PAD. It does not count towards message length */ - i = hd->count; + i = hd->bctx.count; /* After flush we have at least one byte free) */ - hd->buf[i++] = 1; + hd->bctx.buf[i++] = 1; while (i < 64) - hd->buf[i++] = 0; - transform (hd, hd->buf, hd->count * 8); + hd->bctx.buf[i++] = 0; + transform (hd, hd->bctx.buf, hd->bctx.count * 8); g (hd->h, hd->N, Z); g (hd->h, hd->Sigma, Z); @@ -1431,13 +1414,13 @@ stribog_read_256 (void *context) gcry_md_spec_t _gcry_digest_spec_stribog_256 = { "STRIBOG256", NULL, 0, NULL, 32, - stribog_init_256, stribog_write, stribog_final, stribog_read_256, + stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read_256, sizeof (STRIBOG_CONTEXT) }; gcry_md_spec_t _gcry_digest_spec_stribog_512 = { "STRIBOG512", NULL, 0, NULL, 64, - stribog_init_512, stribog_write, stribog_final, stribog_read_512, + stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read_512, sizeof (STRIBOG_CONTEXT) }; From jussi.kivilinna at iki.fi Thu Sep 19 13:47:59 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 14:47:59 +0300 Subject: [PATCH 2/3] gostr3411_94: set better burn stack depth estimate In-Reply-To: <20130919114754.11088.23703.stgit@localhost6.localdomain6> References: <20130919114754.11088.23703.stgit@localhost6.localdomain6> Message-ID: <20130919114759.11088.17112.stgit@localhost6.localdomain6> * cipher/gost28147.c (_gcry_gost_enc_one): Account function stack to burn stack depth. * cipher/gostr3411-94.c (max): New macro. (do_hash_step, transform): Return stack burn depth. -- Signed-off-by: Jussi Kivilinna --- cipher/gost28147.c | 2 +- cipher/gostr3411-94.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 862e7d6..c669148 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -168,7 +168,7 @@ unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, byte *out, byte *in) { gost_setkey (c, key, 32); - return gost_encrypt_block (c, out, in); + return gost_encrypt_block (c, out, in) + 5 * sizeof(void *); } static unsigned int diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index bfd52bd..368fc01 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -30,6 +30,8 @@ #include "gost.h" +#define max(a, b) (((a) > (b)) ? (a) : (b)) + typedef struct { gcry_md_block_ctx_t bctx; GOST28147_context hd; @@ -148,11 +150,12 @@ do_add (unsigned char *s, unsigned char *a) } } -static void +static unsigned int do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) { unsigned char u[32], v[32], s[32]; unsigned char k[32]; + unsigned int burn; int i; memcpy (u, h, 32); @@ -161,7 +164,7 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) for (i = 0; i < 4; i++) { do_p (k, u, v); - _gcry_gost_enc_one (hd, k, s + i*8, h + i*8); + burn = _gcry_gost_enc_one (hd, k, s + i*8, h + i*8); do_a (u); if (i == 1) @@ -198,6 +201,12 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) memcpy (h, s+20, 12); memcpy (h+12, s, 20); + + return /* burn_stack */ 4 * sizeof(void*) /* func call (ret addr + args) */ + + 4 * 32 + 2 * sizeof(int) /* stack */ + + max(burn /* _gcry_gost_enc_one */, + sizeof(void*) * 2 /* do_a2 call */ + + 16 + sizeof(int) /* do_a2 stack */ ); } @@ -206,13 +215,13 @@ transform (void *ctx, const unsigned char *data) { GOSTR3411_CONTEXT *hd = ctx; byte m[32]; + unsigned int burn; memcpy (m, data, 32); - do_hash_step (&hd->hd, hd->h, m); + burn = do_hash_step (&hd->hd, hd->h, m); do_add (hd->sigma, m); -/* FIXME: Fix this arbitrary value for the stack_burn size. -wk */ - return /* stack_burn */ 200; + return /* burn_stack */ burn + 3 * sizeof(void*) + 32 + 2 * sizeof(void*); } /* From jussi.kivilinna at iki.fi Thu Sep 19 13:47:54 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 14:47:54 +0300 Subject: [PATCH 1/3] Use hash transform function return type for passing burn stack depth Message-ID: <20130919114754.11088.23703.stgit@localhost6.localdomain6> * cipher/gostr4311-94.c (transform): Return stack burn depth. * cipher/hash-common.c (_gcry_md_block_write): Use stack burn depth returned by 'hd->bwrite'. * cipher/hash-common.h (_gcry_md_block_write_t): Change return type to 'unsigned int'. (gry_md_block_ctx_t): Remove 'stack_burn'. * cipher/md4.c (transform): Return stack burn depth. (md4_final): Use stack burn depth from transform. * cipher/md5.c (transform): Return stack burn depth. (md5_final): Use stack burn depth from transform. * cipher/rmd160.c (transform): Return stack burn depth. (rmd160_final): Use stack burn depth from transform. * cipher/sha1.c (transform): Return stack burn depth. (sha1_final): Use stack burn depth from transform. * cipher/sha256.c (transform): Return stack burn depth. (sha256_final): Use stack burn depth from transform. * cipher/sha512.c (__transform, transform): Return stack burn depth. (sha512_final): Use stack burn depth from transform. * cipher/stribog.c (transform64): Return stack burn depth. * cipher/tiger.c (transform): Return stack burn depth. (tiger_final): Use stack burn depth from transform. -- Transform function might want different depth of stack burn depending on detected CPU features (like in SHA-512 on ARM with NEON). So return stack burn depth from transform functions as a request or a hint to calling function. Signed-off-by: Jussi Kivilinna --- cipher/gostr3411-94.c | 9 +++++---- cipher/hash-common.c | 10 ++++++---- cipher/hash-common.h | 4 ++-- cipher/md4.c | 12 +++++++----- cipher/md5.c | 12 +++++++----- cipher/rmd160.c | 13 ++++++++----- cipher/sha1.c | 16 +++++++++------- cipher/sha256.c | 14 ++++++++------ cipher/sha512.c | 27 +++++++++++---------------- cipher/stribog.c | 7 ++++--- cipher/tiger.c | 13 ++++++++----- 11 files changed, 75 insertions(+), 62 deletions(-) diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index 93bf597..bfd52bd 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -38,7 +38,7 @@ typedef struct { u32 len; } GOSTR3411_CONTEXT; -static void +static unsigned int transform (void *c, const unsigned char *data); static void @@ -53,8 +53,6 @@ gost3411_init (void *context) hd->bctx.nblocks = 0; hd->bctx.count = 0; hd->bctx.blocksize = 32; - /* FIXME: Fix this arbitrary value for the stack_burn size. -wk */ - hd->bctx.stack_burn = 200; hd->bctx.bwrite = transform; } @@ -203,7 +201,7 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) } -static void +static unsigned int transform (void *ctx, const unsigned char *data) { GOSTR3411_CONTEXT *hd = ctx; @@ -212,6 +210,9 @@ transform (void *ctx, const unsigned char *data) memcpy (m, data, 32); do_hash_step (&hd->hd, hd->h, m); do_add (hd->sigma, m); + +/* FIXME: Fix this arbitrary value for the stack_burn size. -wk */ + return /* stack_burn */ 200; } /* diff --git a/cipher/hash-common.c b/cipher/hash-common.c index 1a6e8e9..bec699f 100644 --- a/cipher/hash-common.c +++ b/cipher/hash-common.c @@ -101,6 +101,7 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen) { const unsigned char *inbuf = inbuf_arg; gcry_md_block_ctx_t *hd = context; + unsigned int stack_burn = 0; if (sizeof(hd->buf) < hd->blocksize) BUG(); @@ -110,8 +111,8 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen) if (hd->count == hd->blocksize) /* Flush the buffer. */ { - hd->bwrite (hd, hd->buf); - _gcry_burn_stack (hd->stack_burn); + stack_burn = hd->bwrite (hd, hd->buf); + _gcry_burn_stack (stack_burn); hd->count = 0; hd->nblocks++; } @@ -129,13 +130,14 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen) while (inlen >= hd->blocksize) { - hd->bwrite (hd, inbuf); + stack_burn = hd->bwrite (hd, inbuf); hd->count = 0; hd->nblocks++; inlen -= hd->blocksize; inbuf += hd->blocksize; } - _gcry_burn_stack (hd->stack_burn); for (; inlen && hd->count < hd->blocksize; inlen--) hd->buf[hd->count++] = *inbuf++; + + _gcry_burn_stack (stack_burn); } diff --git a/cipher/hash-common.h b/cipher/hash-common.h index 4dd5441..3caf0a7 100644 --- a/cipher/hash-common.h +++ b/cipher/hash-common.h @@ -29,7 +29,8 @@ const char * _gcry_hash_selftest_check_one const void *expect, size_t expectlen); /* Type for the md_write helper function. */ -typedef void (*_gcry_md_block_write_t) (void *c, const unsigned char *buf); +typedef unsigned int (*_gcry_md_block_write_t) (void *c, + const unsigned char *buf); #if defined(HAVE_U64_TYPEDEF) && defined(USE_SHA512) /* SHA-512 needs u64 and larger buffer. */ @@ -47,7 +48,6 @@ typedef struct gcry_md_block_ctx int count; size_t blocksize; _gcry_md_block_write_t bwrite; - size_t stack_burn; } gcry_md_block_ctx_t; diff --git a/cipher/md4.c b/cipher/md4.c index 9e75fbc..2de530c 100644 --- a/cipher/md4.c +++ b/cipher/md4.c @@ -64,7 +64,7 @@ typedef struct { u32 A,B,C,D; /* chaining variables */ } MD4_CONTEXT; -static void +static unsigned int transform ( void *c, const unsigned char *data ); static void @@ -80,7 +80,6 @@ md4_init( void *context ) ctx->bctx.nblocks = 0; ctx->bctx.count = 0; ctx->bctx.blocksize = 64; - ctx->bctx.stack_burn = 80+6*sizeof(void*); ctx->bctx.bwrite = transform; } @@ -92,7 +91,7 @@ md4_init( void *context ) /**************** * transform 64 bytes */ -static void +static unsigned int transform ( void *c, const unsigned char *data ) { MD4_CONTEXT *ctx = c; @@ -188,6 +187,8 @@ transform ( void *c, const unsigned char *data ) ctx->B += B; ctx->C += C; ctx->D += D; + + return /*burn_stack*/ 80+6*sizeof(void*); } @@ -204,6 +205,7 @@ md4_final( void *context ) MD4_CONTEXT *hd = context; u32 t, msb, lsb; byte *p; + unsigned int burn; _gcry_md_block_write(hd, NULL, 0); /* flush */; @@ -244,8 +246,8 @@ md4_final( void *context ) hd->bctx.buf[61] = msb >> 8; hd->bctx.buf[62] = msb >> 16; hd->bctx.buf[63] = msb >> 24; - transform( hd, hd->bctx.buf ); - _gcry_burn_stack (80+6*sizeof(void*)); + burn = transform( hd, hd->bctx.buf ); + _gcry_burn_stack (burn); p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN diff --git a/cipher/md5.c b/cipher/md5.c index 9857f2c..88745a8 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -48,7 +48,7 @@ typedef struct { u32 A,B,C,D; /* chaining variables */ } MD5_CONTEXT; -static void +static unsigned int transform ( void *ctx, const unsigned char *data ); static void @@ -64,7 +64,6 @@ md5_init( void *context ) ctx->bctx.nblocks = 0; ctx->bctx.count = 0; ctx->bctx.blocksize = 64; - ctx->bctx.stack_burn = 80+6*sizeof(void*); ctx->bctx.bwrite = transform; } @@ -82,7 +81,7 @@ md5_init( void *context ) /**************** * transform n*64 bytes */ -static void +static unsigned int transform ( void *c, const unsigned char *data ) { MD5_CONTEXT *ctx = c; @@ -213,6 +212,8 @@ transform ( void *c, const unsigned char *data ) ctx->B += B; ctx->C += C; ctx->D += D; + + return /*burn_stack*/ 80+6*sizeof(void*); } @@ -229,6 +230,7 @@ md5_final( void *context) MD5_CONTEXT *hd = context; u32 t, msb, lsb; byte *p; + unsigned int burn; _gcry_md_block_write(hd, NULL, 0); /* flush */; @@ -269,8 +271,8 @@ md5_final( void *context) hd->bctx.buf[61] = msb >> 8; hd->bctx.buf[62] = msb >> 16; hd->bctx.buf[63] = msb >> 24; - transform( hd, hd->bctx.buf ); - _gcry_burn_stack (80+6*sizeof(void*)); + burn = transform( hd, hd->bctx.buf ); + _gcry_burn_stack (burn); p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN diff --git a/cipher/rmd160.c b/cipher/rmd160.c index 5bb32a6..7f143df 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -139,7 +139,7 @@ * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528 */ -static void +static unsigned int transform ( void *ctx, const unsigned char *data ); void @@ -152,10 +152,10 @@ _gcry_rmd160_init (void *context) hd->h2 = 0x98BADCFE; hd->h3 = 0x10325476; hd->h4 = 0xC3D2E1F0; + hd->bctx.nblocks = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; - hd->bctx.stack_burn = 108+5*sizeof(void*); hd->bctx.bwrite = transform; } @@ -164,7 +164,7 @@ _gcry_rmd160_init (void *context) /**************** * Transform the message X which consists of 16 32-bit-words */ -static void +static unsigned int transform ( void *ctx, const unsigned char *data ) { RMD160_CONTEXT *hd = ctx; @@ -400,6 +400,8 @@ transform ( void *ctx, const unsigned char *data ) hd->h3 = hd->h4 + b + aa; hd->h4 = hd->h0 + c + bb; hd->h0 = t; + + return /*burn_stack*/ 108+5*sizeof(void*); } @@ -434,6 +436,7 @@ rmd160_final( void *context ) RMD160_CONTEXT *hd = context; u32 t, msb, lsb; byte *p; + unsigned int burn; _gcry_md_block_write(hd, NULL, 0); /* flush */; @@ -474,8 +477,8 @@ rmd160_final( void *context ) hd->bctx.buf[61] = msb >> 8; hd->bctx.buf[62] = msb >> 16; hd->bctx.buf[63] = msb >> 24; - transform( hd, hd->bctx.buf ); - _gcry_burn_stack (108+5*sizeof(void*)); + burn = transform( hd, hd->bctx.buf ); + _gcry_burn_stack (burn); p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN diff --git a/cipher/sha1.c b/cipher/sha1.c index 9e4e9c6..382bce8 100644 --- a/cipher/sha1.c +++ b/cipher/sha1.c @@ -57,10 +57,10 @@ typedef struct u32 h0,h1,h2,h3,h4; } SHA1_CONTEXT; - -static void +static unsigned int transform (void *c, const unsigned char *data); + static void sha1_init (void *context) { @@ -71,10 +71,10 @@ sha1_init (void *context) hd->h2 = 0x98badcfe; hd->h3 = 0x10325476; hd->h4 = 0xc3d2e1f0; + hd->bctx.nblocks = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; - hd->bctx.stack_burn = 88+4*sizeof(void*); hd->bctx.bwrite = transform; } @@ -104,7 +104,7 @@ sha1_init (void *context) /* * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA. */ -static void +static unsigned int transform (void *ctx, const unsigned char *data) { SHA1_CONTEXT *hd = ctx; @@ -224,6 +224,8 @@ transform (void *ctx, const unsigned char *data) hd->h2 += c; hd->h3 += d; hd->h4 += e; + + return /* burn_stack */ 88+4*sizeof(void*); } @@ -238,9 +240,9 @@ static void sha1_final(void *context) { SHA1_CONTEXT *hd = context; - u32 t, msb, lsb; unsigned char *p; + unsigned int burn; _gcry_md_block_write (hd, NULL, 0); /* flush */; @@ -281,8 +283,8 @@ sha1_final(void *context) hd->bctx.buf[61] = lsb >> 16; hd->bctx.buf[62] = lsb >> 8; hd->bctx.buf[63] = lsb ; - transform( hd, hd->bctx.buf ); - _gcry_burn_stack (88+4*sizeof(void*)); + burn = transform( hd, hd->bctx.buf ); + _gcry_burn_stack (burn); p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN diff --git a/cipher/sha256.c b/cipher/sha256.c index 1785699..cf23f2f 100644 --- a/cipher/sha256.c +++ b/cipher/sha256.c @@ -50,9 +50,10 @@ typedef struct { u32 h0,h1,h2,h3,h4,h5,h6,h7; } SHA256_CONTEXT; -static void +static unsigned int transform (void *c, const unsigned char *data); + static void sha256_init (void *context) { @@ -70,7 +71,6 @@ sha256_init (void *context) hd->bctx.nblocks = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; - hd->bctx.stack_burn = 74*4+32; hd->bctx.bwrite = transform; } @@ -92,7 +92,6 @@ sha224_init (void *context) hd->bctx.nblocks = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; - hd->bctx.stack_burn = 74*4+32; hd->bctx.bwrite = transform; } @@ -145,7 +144,7 @@ Sum1 (u32 x) } -static void +static unsigned int transform (void *ctx, const unsigned char *data) { SHA256_CONTEXT *hd = ctx; @@ -261,6 +260,8 @@ transform (void *ctx, const unsigned char *data) hd->h5 += f; hd->h6 += g; hd->h7 += h; + + return /*burn_stack*/ 74*4+32; } #undef S0 #undef S1 @@ -278,6 +279,7 @@ sha256_final(void *context) SHA256_CONTEXT *hd = context; u32 t, msb, lsb; byte *p; + unsigned int burn; _gcry_md_block_write (hd, NULL, 0); /* flush */; @@ -318,8 +320,8 @@ sha256_final(void *context) hd->bctx.buf[61] = lsb >> 16; hd->bctx.buf[62] = lsb >> 8; hd->bctx.buf[63] = lsb; - transform (hd, hd->bctx.buf); - _gcry_burn_stack (74*4+32); + burn = transform (hd, hd->bctx.buf); + _gcry_burn_stack (burn); p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN diff --git a/cipher/sha512.c b/cipher/sha512.c index ed63ae6..26cbe14 100644 --- a/cipher/sha512.c +++ b/cipher/sha512.c @@ -63,7 +63,6 @@ # endif #endif - typedef struct { u64 h0, h1, h2, h3, h4, h5, h6, h7; @@ -78,7 +77,7 @@ typedef struct #endif } SHA512_CONTEXT; -static void +static unsigned int transform (void *context, const unsigned char *data); static void @@ -100,7 +99,6 @@ sha512_init (void *context) ctx->bctx.count = 0; ctx->bctx.blocksize = 128; ctx->bctx.bwrite = transform; - ctx->bctx.stack_burn = 256; #ifdef USE_ARM_NEON_ASM ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; @@ -126,7 +124,6 @@ sha384_init (void *context) ctx->bctx.count = 0; ctx->bctx.blocksize = 128; ctx->bctx.bwrite = transform; - ctx->bctx.stack_burn = 256; #ifdef USE_ARM_NEON_ASM ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; @@ -211,7 +208,7 @@ static const u64 k[] = /**************** * Transform the message W which consists of 16 64-bit-words */ -static void +static unsigned int __transform (SHA512_STATE *hd, const unsigned char *data) { u64 a, b, c, d, e, f, g, h; @@ -489,6 +486,9 @@ __transform (SHA512_STATE *hd, const unsigned char *data) hd->h5 += f; hd->h6 += g; hd->h7 += h; + + return /* burn_stack */ (8 + 16) * sizeof(u64) + sizeof(u32) + + 3 * sizeof(void*); } @@ -499,7 +499,7 @@ void _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd, #endif -static void +static unsigned int transform (void *context, const unsigned char *data) { SHA512_CONTEXT *ctx = context; @@ -509,17 +509,13 @@ transform (void *context, const unsigned char *data) { _gcry_sha512_transform_armv7_neon(&ctx->state, data, k); - /* TODO: return burn stack to md_block_write */ - /* return stack burn depth */ - return /*(sizeof(void *) * 3)*/; + /* _gcry_sha512_transform_armv7_neon does not store sensitive data + * to stack. */ + return /* no burn_stack */ 0; } #endif - __transform (&ctx->state, data); - - /* TODO: return burn stack to md_block_write */ - /* return stack burn depth */ - return /*256*/; + return __transform (&ctx->state, data) + 3 * sizeof(void*); } @@ -587,8 +583,7 @@ sha512_final (void *context) hd->bctx.buf[125] = lsb >> 16; hd->bctx.buf[126] = lsb >> 8; hd->bctx.buf[127] = lsb; - transform (hd, hd->bctx.buf); - stack_burn_depth = hd->bctx.stack_burn; + stack_burn_depth = transform (hd, hd->bctx.buf); _gcry_burn_stack (stack_burn_depth); p = hd->bctx.buf; diff --git a/cipher/stribog.c b/cipher/stribog.c index 234a17e..1f79882 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -1274,7 +1274,7 @@ static void g (u64 *h, u64 *m, u64 *N) } -static void +static unsigned int transform64 (void *context, const unsigned char *inbuf_arg); @@ -1287,7 +1287,6 @@ stribog_init_512 (void *context) hd->bctx.blocksize = 64; hd->bctx.bwrite = transform64; - hd->bctx.stack_burn = 768; } static void @@ -1346,12 +1345,14 @@ transform (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) hd->Sigma[i] += M[i]; } -static void +static unsigned int transform64 (void *context, const unsigned char *inbuf_arg) { STRIBOG_CONTEXT *hd = context; transform (hd, inbuf_arg, 64 * 8); + + return /* burn_stack */ 768; } /* diff --git a/cipher/tiger.c b/cipher/tiger.c index 49d3919..8f5959b 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -587,7 +587,7 @@ static u64 sbox4[256] = { U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */ }; -static void +static unsigned int transform ( void *ctx, const unsigned char *data ); static void @@ -598,10 +598,10 @@ do_init (void *context, int variant) hd->a = 0x0123456789abcdefLL; hd->b = 0xfedcba9876543210LL; hd->c = 0xf096a5b4c3b2e187LL; + hd->bctx.nblocks = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; - hd->bctx.stack_burn = 21*8+11*sizeof(void*); hd->bctx.bwrite = transform; hd->variant = variant; } @@ -691,7 +691,7 @@ key_schedule( u64 *x ) /**************** * Transform the message DATA which consists of 512 bytes (8 words) */ -static void +static unsigned int transform ( void *ctx, const unsigned char *data ) { TIGER_CONTEXT *hd = ctx; @@ -735,6 +735,8 @@ transform ( void *ctx, const unsigned char *data ) hd->a = a; hd->b = b; hd->c = c; + + return /*burn_stack*/ 21*8+11*sizeof(void*); } @@ -747,6 +749,7 @@ tiger_final( void *context ) TIGER_CONTEXT *hd = context; u32 t, msb, lsb; byte *p; + unsigned int burn; byte pad = hd->variant == 2? 0x80 : 0x01; _gcry_md_block_write(hd, NULL, 0); /* flush */; @@ -788,8 +791,8 @@ tiger_final( void *context ) hd->bctx.buf[61] = msb >> 8; hd->bctx.buf[62] = msb >> 16; hd->bctx.buf[63] = msb >> 24; - transform( hd, hd->bctx.buf ); - _gcry_burn_stack (21*8+11*sizeof(void*)); + burn = transform( hd, hd->bctx.buf ); + _gcry_burn_stack (burn); p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN From jussi.kivilinna at iki.fi Thu Sep 19 13:48:04 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 14:48:04 +0300 Subject: [PATCH 3/3] Optimize and cleanup 32-bit and 64-bit endianess transforms In-Reply-To: <20130919114754.11088.23703.stgit@localhost6.localdomain6> References: <20130919114754.11088.23703.stgit@localhost6.localdomain6> Message-ID: <20130919114804.11088.76191.stgit@localhost6.localdomain6> * cipher/bithelp.h (bswap32, bswap64, le_bswap32, be_bswap32) (le_bswap64, be_bswap64): New. * cipher/bufhelp.h (buf_get_be32, buf_get_le32, buf_put_le32) (buf_put_be32, buf_get_be64, buf_get_le64, buf_put_be64) (buf_put_le64): New. * cipher/blowfish.c (do_encrypt_block, do_decrypt_block): Use new endian conversion helpers. (do_bf_setkey): Turn endian specific code to generic. * cipher/camellia.c (GETU32, PUTU32): Use new endian conversion helpers. * cipher/cast5.c (rol): Remove, use rol from bithelp. (F1, F2, F3): Fix to use rol from bithelp. (do_encrypt_block, do_decrypt_block, do_cast_setkey): Use new endian conversion helpers. * cipher/des.c (READ_64BIT_DATA, WRITE_64BIT_DATA): Ditto. * cipher/md4.c (transform, md4_final): Ditto. * cipher/md5.c (transform, md5_final): Ditto. * cipher/rmd160.c (transform, rmd160_final): Ditto. * cipher/salsa20.c (LE_SWAP32, LE_READ_UINT32): Ditto. * cipher/scrypt.c (READ_UINT64, LE_READ_UINT64, LE_SWAP32): Ditto. * cipher/seed.c (GETU32, PUTU32): Ditto. * cipher/serpent.c (byte_swap_32): Remove. (serpent_key_prepare, serpent_encrypt_internal) (serpent_decrypt_internal): Use new endian conversion helpers. * cipher/sha1.c (transform, sha1_final): Ditto. * cipher/sha256.c (transform, sha256_final): Ditto. * cipher/sha512.c (__transform, sha512_final): Ditto. * cipher/stribog.c (transform, stribog_final): Ditto. * cipher/tiger.c (transform, tiger_final): Ditto. * cipher/twofish.c (INPACK, OUTUNPACK): Ditto. * cipher/whirlpool.c (buffer_to_block, block_to_buffer): Ditto. * configure.ac (gcry_cv_have_builtin_bswap32): Check for compiler provided __builtin_bswap32. (gcry_cv_have_builtin_bswap64): Check for compiler provided __builtin_bswap64. -- Patch add helper functions that provide conversions to/from integers and buffers of different endianess. Benefits are code cleanup and optimization for architectures that have byte-swaping instructions and/or can do fast unaligned memory accesses. Signed-off-by: Jussi Kivilinna --- cipher/bithelp.h | 40 +++++++++++++++ cipher/blowfish.c | 43 ++++------------ cipher/bufhelp.h | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cipher/camellia.c | 14 +---- cipher/cast5.c | 57 ++++++--------------- cipher/des.c | 11 ++-- cipher/md4.c | 37 +++---------- cipher/md5.c | 38 +++----------- cipher/rmd160.c | 45 +++------------- cipher/salsa20.c | 14 +---- cipher/scrypt.c | 34 ++---------- cipher/seed.c | 9 +-- cipher/serpent.c | 57 +++++++-------------- cipher/sha1.c | 70 ++++++++----------------- cipher/sha256.c | 37 ++----------- cipher/sha512.c | 51 ++----------------- cipher/stribog.c | 35 +------------ cipher/tiger.c | 48 ++++------------- cipher/twofish.c | 7 +-- cipher/whirlpool.c | 23 +------- configure.ac | 30 +++++++++++ 21 files changed, 352 insertions(+), 491 deletions(-) diff --git a/cipher/bithelp.h b/cipher/bithelp.h index 785701e..734dcbb 100644 --- a/cipher/bithelp.h +++ b/cipher/bithelp.h @@ -20,6 +20,8 @@ #ifndef G10_BITHELP_H #define G10_BITHELP_H +#include "types.h" + /**************** * Rotate the 32 bit unsigned integer X by N bits left/right @@ -52,5 +54,43 @@ ror(u32 x, int n) #define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) ) #endif +/* Byte swap for 32-bit and 64-bit integers. If available, use compiler + provided helpers. */ +#ifdef HAVE_BUILTIN_BSWAP32 +# define bswap32 __builtin_bswap32 +#else +static inline u32 bswap32(u32 x) +{ + return ((rol(x, 8) & 0x00ff00ffL) | (ror(x, 8) & 0xff00ff00L)); +} +#endif + +#ifdef HAVE_U64_TYPEDEF +# ifdef HAVE_BUILTIN_BSWAP64 +# define bswap64 __builtin_bswap64 +# else +static inline u64 bswap64(u64 x) +{ + return ((u64)bswap32(x) << 32) | (bswap32(x >> 32)); +} +# endif +#endif + +/* Endian dependent byte swap operations. */ +#ifdef WORDS_BIGENDIAN +# define le_bswap32(x) bswap32(x) +# define be_bswap32(x) ((u32)(x)) +# ifdef HAVE_U64_TYPEDEF +# define le_bswap64(x) bswap64(x) +# define be_bswap64(x) ((u64)(x)) +# endif +#else +# define le_bswap32(x) ((u32)(x)) +# define be_bswap32(x) bswap32(x) +# ifdef HAVE_U64_TYPEDEF +# define le_bswap64(x) ((u64)(x)) +# define be_bswap64(x) bswap64(x) +# endif +#endif #endif /*G10_BITHELP_H*/ diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 80e1ec7..61042ed 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -544,17 +544,11 @@ do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf ) { u32 d1, d2; - d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + d1 = buf_get_be32(inbuf); + d2 = buf_get_be32(inbuf + 4); do_encrypt( bc, &d1, &d2 ); - outbuf[0] = (d1 >> 24) & 0xff; - outbuf[1] = (d1 >> 16) & 0xff; - outbuf[2] = (d1 >> 8) & 0xff; - outbuf[3] = d1 & 0xff; - outbuf[4] = (d2 >> 24) & 0xff; - outbuf[5] = (d2 >> 16) & 0xff; - outbuf[6] = (d2 >> 8) & 0xff; - outbuf[7] = d2 & 0xff; + buf_put_be32(outbuf, d1); + buf_put_be32(outbuf + 4, d2); } static unsigned int @@ -571,17 +565,11 @@ do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf) { u32 d1, d2; - d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + d1 = buf_get_be32(inbuf); + d2 = buf_get_be32(inbuf + 4); decrypt( bc, &d1, &d2 ); - outbuf[0] = (d1 >> 24) & 0xff; - outbuf[1] = (d1 >> 16) & 0xff; - outbuf[2] = (d1 >> 8) & 0xff; - outbuf[3] = d1 & 0xff; - outbuf[4] = (d2 >> 24) & 0xff; - outbuf[5] = (d2 >> 16) & 0xff; - outbuf[6] = (d2 >> 8) & 0xff; - outbuf[7] = d2 & 0xff; + buf_put_be32(outbuf, d1); + buf_put_be32(outbuf + 4, d2); } static unsigned int @@ -903,17 +891,10 @@ do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen) for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) { -#ifdef WORDS_BIGENDIAN - ((byte*)&data)[0] = key[j]; - ((byte*)&data)[1] = key[(j+1)%keylen]; - ((byte*)&data)[2] = key[(j+2)%keylen]; - ((byte*)&data)[3] = key[(j+3)%keylen]; -#else - ((byte*)&data)[3] = key[j]; - ((byte*)&data)[2] = key[(j+1)%keylen]; - ((byte*)&data)[1] = key[(j+2)%keylen]; - ((byte*)&data)[0] = key[(j+3)%keylen]; -#endif + data = ((u32)key[j] << 24) | + ((u32)key[(j+1)%keylen] << 16) | + ((u32)key[(j+2)%keylen] << 8) | + ((u32)key[(j+3)%keylen]); c->p[i] ^= data; j = (j+4) % keylen; } diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h index d829cf1..c637dac 100644 --- a/cipher/bufhelp.h +++ b/cipher/bufhelp.h @@ -20,6 +20,8 @@ #ifndef G10_BUFHELP_H #define G10_BUFHELP_H +#include + #ifdef HAVE_STDINT_H # include /* uintptr_t */ #elif defined(HAVE_INTTYPES_H) @@ -28,6 +30,8 @@ /* In this case, uintptr_t is provided by config.h. */ #endif +#include "bithelp.h" + #if defined(__i386__) || defined(__x86_64__) || \ (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) @@ -179,4 +183,143 @@ do_bytes: } } + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + +/* Functions for loading and storing unaligned u32 values of different + endianness. */ +static inline u32 buf_get_be32(const void *_buf) +{ + const byte *in = _buf; + return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \ + ((u32)in[2] << 8) | (u32)in[3]; +} + +static inline u32 buf_get_le32(const void *_buf) +{ + const byte *in = _buf; + return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \ + ((u32)in[1] << 8) | (u32)in[0]; +} + +static inline void buf_put_be32(void *_buf, u32 val) +{ + byte *out = _buf; + out[0] = val >> 24; + out[1] = val >> 16; + out[2] = val >> 8; + out[3] = val; +} + +static inline void buf_put_le32(void *_buf, u32 val) +{ + byte *out = _buf; + out[3] = val >> 24; + out[2] = val >> 16; + out[1] = val >> 8; + out[0] = val; +} + +#ifdef HAVE_U64_TYPEDEF +/* Functions for loading and storing unaligned u64 values of different + endianness. */ +static inline u64 buf_get_be64(const void *_buf) +{ + const byte *in = _buf; + return ((u64)in[0] << 56) | ((u64)in[1] << 48) | \ + ((u64)in[2] << 40) | ((u64)in[3] << 32) | \ + ((u64)in[4] << 24) | ((u64)in[5] << 16) | \ + ((u64)in[6] << 8) | (u64)in[7]; +} + +static inline u64 buf_get_le64(const void *_buf) +{ + const byte *in = _buf; + return ((u64)in[7] << 56) | ((u64)in[6] << 48) | \ + ((u64)in[5] << 40) | ((u64)in[4] << 32) | \ + ((u64)in[3] << 24) | ((u64)in[2] << 16) | \ + ((u64)in[1] << 8) | (u64)in[0]; +} + +static inline void buf_put_be64(void *_buf, u64 val) +{ + byte *out = _buf; + out[0] = val >> 56; + out[1] = val >> 48; + out[2] = val >> 40; + out[3] = val >> 32; + out[4] = val >> 24; + out[5] = val >> 16; + out[6] = val >> 8; + out[7] = val; +} + +static inline void buf_put_le64(void *_buf, u64 val) +{ + byte *out = _buf; + out[7] = val >> 56; + out[6] = val >> 48; + out[5] = val >> 40; + out[4] = val >> 32; + out[3] = val >> 24; + out[2] = val >> 16; + out[1] = val >> 8; + out[0] = val; +} +#endif /*HAVE_U64_TYPEDEF*/ + +#else /*BUFHELP_FAST_UNALIGNED_ACCESS*/ + +/* Functions for loading and storing unaligned u32 values of different + endianness. */ +static inline u32 buf_get_be32(const void *_buf) +{ + return be_bswap32(*(const u32 *)_buf); +} + +static inline u32 buf_get_le32(const void *_buf) +{ + return le_bswap32(*(const u32 *)_buf); +} + +static inline void buf_put_be32(void *_buf, u32 val) +{ + u32 *out = _buf; + *out = be_bswap32(val); +} + +static inline void buf_put_le32(void *_buf, u32 val) +{ + u32 *out = _buf; + *out = le_bswap32(val); +} + +#ifdef HAVE_U64_TYPEDEF +/* Functions for loading and storing unaligned u64 values of different + endianness. */ +static inline u64 buf_get_be64(const void *_buf) +{ + return be_bswap64(*(const u64 *)_buf); +} + +static inline u64 buf_get_le64(const void *_buf) +{ + return le_bswap64(*(const u64 *)_buf); +} + +static inline void buf_put_be64(void *_buf, u64 val) +{ + u64 *out = _buf; + *out = be_bswap64(val); +} + +static inline void buf_put_le64(void *_buf, u64 val) +{ + u64 *out = _buf; + *out = le_bswap64(val); +} +#endif /*HAVE_U64_TYPEDEF*/ + +#endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ + #endif /*G10_BITHELP_H*/ diff --git a/cipher/camellia.c b/cipher/camellia.c index 038d911..03510a3 100644 --- a/cipher/camellia.c +++ b/cipher/camellia.c @@ -25,6 +25,7 @@ #include #include +#include "bufhelp.h" #include "camellia.h" /* u32 must be 32bit word */ @@ -59,17 +60,8 @@ typedef unsigned char u8; #else /* not MS-VC */ -# define GETU32(pt) \ - (((u32)(pt)[0] << 24) \ - ^ ((u32)(pt)[1] << 16) \ - ^ ((u32)(pt)[2] << 8) \ - ^ ((u32)(pt)[3])) - -# define PUTU32(ct, st) { \ - (ct)[0] = (u8)((st) >> 24); \ - (ct)[1] = (u8)((st) >> 16); \ - (ct)[2] = (u8)((st) >> 8); \ - (ct)[3] = (u8)(st); } +# define GETU32(pt) buf_get_be32(pt) +# define PUTU32(ct, st) buf_put_be32(ct, st) #endif diff --git a/cipher/cast5.c b/cipher/cast5.c index 0cd5953..ae6b509 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -42,6 +42,7 @@ #include "g10lib.h" #include "types.h" #include "cipher.h" +#include "bithelp.h" #include "bufhelp.h" #include "cipher-selftest.h" @@ -448,25 +449,11 @@ decrypt_block (void *context, byte *outbuf, const byte *inbuf) #else /*USE_ARMV6_ASM*/ -#if defined(__GNUC__) && defined(__i386__) -static inline u32 -rol(int n, u32 x) -{ - __asm__("roll %%cl,%0" - :"=r" (x) - :"0" (x),"c" (n) - :"cc"); - return x; -} -#else -#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) ) -#endif - -#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol((r),I)), \ +#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol(I,(r))), \ (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) ) -#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol((r),I)), \ +#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol(I,(r))), \ (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) ) -#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \ +#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol(I,(r))), \ (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) ) static void @@ -483,8 +470,8 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf ) /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.) */ - l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + l = buf_get_be32(inbuf + 0); + r = buf_get_be32(inbuf + 4); /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows: * Li = Ri-1; @@ -513,14 +500,8 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf ) /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and * concatenate to form the ciphertext.) */ - outbuf[0] = (r >> 24) & 0xff; - outbuf[1] = (r >> 16) & 0xff; - outbuf[2] = (r >> 8) & 0xff; - outbuf[3] = r & 0xff; - outbuf[4] = (l >> 24) & 0xff; - outbuf[5] = (l >> 16) & 0xff; - outbuf[6] = (l >> 8) & 0xff; - outbuf[7] = l & 0xff; + buf_put_be32(outbuf + 0, r); + buf_put_be32(outbuf + 4, l); } static unsigned int @@ -543,8 +524,8 @@ do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf ) Km = c->Km; Kr = c->Kr; - l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + l = buf_get_be32(inbuf + 0); + r = buf_get_be32(inbuf + 4); t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); @@ -563,14 +544,8 @@ do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf ) t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]); t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]); - outbuf[0] = (r >> 24) & 0xff; - outbuf[1] = (r >> 16) & 0xff; - outbuf[2] = (r >> 8) & 0xff; - outbuf[3] = r & 0xff; - outbuf[4] = (l >> 24) & 0xff; - outbuf[5] = (l >> 16) & 0xff; - outbuf[6] = (l >> 8) & 0xff; - outbuf[7] = l & 0xff; + buf_put_be32(outbuf + 0, r); + buf_put_be32(outbuf + 4, l); } static unsigned int @@ -949,10 +924,10 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen ) if( keylen != 16 ) return GPG_ERR_INV_KEYLEN; - x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]; - x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]; - x[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11]; - x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15]; + x[0] = buf_get_be32(key + 0); + x[1] = buf_get_be32(key + 4); + x[2] = buf_get_be32(key + 8); + x[3] = buf_get_be32(key + 12); key_schedule( x, z, k ); for(i=0; i < 16; i++ ) diff --git a/cipher/des.c b/cipher/des.c index 7db9e5d..f1550d1 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -118,6 +118,7 @@ #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" +#include "bufhelp.h" #if defined(__GNUC__) && defined(__GNU_LIBRARY__) #define working_memcmp memcmp @@ -455,14 +456,12 @@ static unsigned char weak_keys_chksum[20] = { * Macros to convert 8 bytes from/to 32bit words. */ #define READ_64BIT_DATA(data, left, right) \ - left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \ - right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; + left = buf_get_be32(data + 0); \ + right = buf_get_be32(data + 4); #define WRITE_64BIT_DATA(data, left, right) \ - data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \ - data[2] = (left >> 8) &0xff; data[3] = left &0xff; \ - data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \ - data[6] = (right >> 8) &0xff; data[7] = right &0xff; + buf_put_be32(data + 0, left); \ + buf_put_be32(data + 4, right); /* * Handy macros for encryption and decryption of data diff --git a/cipher/md4.c b/cipher/md4.c index 2de530c..e2d096c 100644 --- a/cipher/md4.c +++ b/cipher/md4.c @@ -56,6 +56,7 @@ #include "cipher.h" #include "bithelp.h" +#include "bufhelp.h" #include "hash-common.h" @@ -100,23 +101,10 @@ transform ( void *c, const unsigned char *data ) register u32 B = ctx->B; register u32 C = ctx->C; register u32 D = ctx->D; + int i; -#ifdef WORDS_BIGENDIAN - { - int i; - byte *p2; - const byte *p1; - for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 ) - { - p2[3] = *p1++; - p2[2] = *p1++; - p2[1] = *p1++; - p2[0] = *p1++; - } - } -#else - memcpy (in, data, 64); -#endif + for ( i = 0; i < 16; i++ ) + in[i] = buf_get_le32(data + i * 4); /* Round 1. */ #define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s); @@ -238,24 +226,13 @@ md4_final( void *context ) memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->bctx.buf[56] = lsb ; - hd->bctx.buf[57] = lsb >> 8; - hd->bctx.buf[58] = lsb >> 16; - hd->bctx.buf[59] = lsb >> 24; - hd->bctx.buf[60] = msb ; - hd->bctx.buf[61] = msb >> 8; - hd->bctx.buf[62] = msb >> 16; - hd->bctx.buf[63] = msb >> 24; + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); burn = transform( hd, hd->bctx.buf ); _gcry_burn_stack (burn); p = hd->bctx.buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ - *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0) -#else /* little endian */ -#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0) -#endif +#define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0) X(A); X(B); X(C); diff --git a/cipher/md5.c b/cipher/md5.c index 88745a8..db0f315 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -40,6 +40,7 @@ #include "cipher.h" #include "bithelp.h" +#include "bufhelp.h" #include "hash-common.h" @@ -91,24 +92,10 @@ transform ( void *c, const unsigned char *data ) register u32 C = ctx->C; register u32 D = ctx->D; u32 *cwp = correct_words; + int i; -#ifdef WORDS_BIGENDIAN - { - int i; - byte *p2; - const byte *p1; - for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 ) - { - p2[3] = *p1++; - p2[2] = *p1++; - p2[1] = *p1++; - p2[0] = *p1++; - } - } -#else - memcpy( correct_words, data, 64 ); -#endif - + for ( i = 0; i < 16; i++ ) + correct_words[i] = buf_get_le32(data + i * 4); #define OP(a, b, c, d, s, T) \ do \ @@ -263,24 +250,13 @@ md5_final( void *context) memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->bctx.buf[56] = lsb ; - hd->bctx.buf[57] = lsb >> 8; - hd->bctx.buf[58] = lsb >> 16; - hd->bctx.buf[59] = lsb >> 24; - hd->bctx.buf[60] = msb ; - hd->bctx.buf[61] = msb >> 8; - hd->bctx.buf[62] = msb >> 16; - hd->bctx.buf[63] = msb >> 24; + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); burn = transform( hd, hd->bctx.buf ); _gcry_burn_stack (burn); p = hd->bctx.buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ - *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0) -#else /* little endian */ -#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0) -#endif +#define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0) X(A); X(B); X(C); diff --git a/cipher/rmd160.c b/cipher/rmd160.c index 7f143df..d156e61 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -28,6 +28,7 @@ #include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */ #include "bithelp.h" +#include "bufhelp.h" /********************************* * RIPEMD-160 is not patented, see (as of 25.10.97) @@ -170,32 +171,11 @@ transform ( void *ctx, const unsigned char *data ) RMD160_CONTEXT *hd = ctx; register u32 a,b,c,d,e; u32 aa,bb,cc,dd,ee,t; -#ifdef WORDS_BIGENDIAN u32 x[16]; - { - int i; - byte *p2; - const byte *p1; - for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) - { - p2[3] = *p1++; - p2[2] = *p1++; - p2[1] = *p1++; - p2[0] = *p1++; - } - } -#else - /* This version is better because it is always aligned; - * The performance penalty on a 586-100 is about 6% which - * is acceptable - because the data is more local it might - * also be possible that this is faster on some machines. - * This function (when compiled with -02 on gcc 2.7.2) - * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec; - * [measured with a 4MB data and "gpgm --print-md rmd160"] */ - u32 x[16]; - memcpy( x, data, 64 ); -#endif + int i; + for ( i = 0; i < 16; i++ ) + x[i] = buf_get_le32(data + i * 4); #define K0 0x00000000 #define K1 0x5A827999 @@ -469,24 +449,13 @@ rmd160_final( void *context ) memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->bctx.buf[56] = lsb ; - hd->bctx.buf[57] = lsb >> 8; - hd->bctx.buf[58] = lsb >> 16; - hd->bctx.buf[59] = lsb >> 24; - hd->bctx.buf[60] = msb ; - hd->bctx.buf[61] = msb >> 8; - hd->bctx.buf[62] = msb >> 16; - hd->bctx.buf[63] = msb >> 24; + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); burn = transform( hd, hd->bctx.buf ); _gcry_burn_stack (burn); p = hd->bctx.buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \ - *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0) -#else /* little endian */ -#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) -#endif +#define X(a) do { *(u32*)p = le_bswap32(hd->h##a) ; p += 4; } while(0) X(0); X(1); X(2); diff --git a/cipher/salsa20.c b/cipher/salsa20.c index 37f2989..88f5372 100644 --- a/cipher/salsa20.c +++ b/cipher/salsa20.c @@ -75,19 +75,9 @@ typedef struct #define ROTL32(n,x) (((x)<<(n)) | ((x)>>((-(n)&31)))) -#ifdef WORDS_BIGENDIAN -# define LE_SWAP32(v) \ - ( (ROTL32( 8, v) & 0x00FF00FFul) \ - |(ROTL32(24, v) & 0xFF00FF00ul)) -#else -# define LE_SWAP32(v) (v) -#endif +#define LE_SWAP32(v) le_bswap32(v) -#define LE_READ_UINT32(p) \ - ( (((u32)(p)[3]) << 24) \ - | (((u32)(p)[2]) << 16) \ - | (((u32)(p)[1]) << 8) \ - | ((u32)(p)[0])) +#define LE_READ_UINT32(p) buf_get_le32(p) static void salsa20_setiv (void *context, const byte *iv, unsigned int ivlen); diff --git a/cipher/scrypt.c b/cipher/scrypt.c index 9e29288..6f6a7f1 100644 --- a/cipher/scrypt.c +++ b/cipher/scrypt.c @@ -58,38 +58,14 @@ /* Reads a 64-bit integer, in network, big-endian, byte order */ -#define READ_UINT64(p) \ -( (((u64) (p)[0]) << 56) \ - | (((u64) (p)[1]) << 48) \ - | (((u64) (p)[2]) << 40) \ - | (((u64) (p)[3]) << 32) \ - | (((u64) (p)[4]) << 24) \ - | (((u64) (p)[5]) << 16) \ - | (((u64) (p)[6]) << 8) \ - | ((u64) (p)[7])) - +#define READ_UINT64(p) buf_get_be64(p) /* And the other, little-endian, byteorder */ -#define LE_READ_UINT64(p) \ -( (((u64) (p)[7]) << 56) \ - | (((u64) (p)[6]) << 48) \ - | (((u64) (p)[5]) << 40) \ - | (((u64) (p)[4]) << 32) \ - | (((u64) (p)[3]) << 24) \ - | (((u64) (p)[2]) << 16) \ - | (((u64) (p)[1]) << 8) \ - | ((u64) (p)[0])) - - - -#ifdef WORDS_BIGENDIAN -#define LE_SWAP32(v) \ - ((ROTL32(8, v) & 0x00FF00FFUL) | \ - (ROTL32(24, v) & 0xFF00FF00UL)) -#else -#define LE_SWAP32(v) (v) -#endif +#define LE_READ_UINT64(p) buf_get_le64(p) + +#define LE_SWAP32(v) le_bswap32(v) + #define QROUND(x0, x1, x2, x3) do { \ x1 ^= ROTL32(7, x0 + x3); \ diff --git a/cipher/seed.c b/cipher/seed.c index 1600c55..474ccba 100644 --- a/cipher/seed.c +++ b/cipher/seed.c @@ -29,15 +29,12 @@ #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" +#include "bufhelp.h" #define NUMKC 16 -#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ - ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) -#define PUTU32(ct, st) { (ct)[0] = (byte)((st) >> 24); \ - (ct)[1] = (byte)((st) >> 16); \ - (ct)[2] = (byte)((st) >> 8); \ - (ct)[3] = (byte)(st); } +#define GETU32(pt) buf_get_be32(pt) +#define PUTU32(ct, st) buf_put_be32(ct, st) union wordbuf { diff --git a/cipher/serpent.c b/cipher/serpent.c index 72895ed..4720b9c 100644 --- a/cipher/serpent.c +++ b/cipher/serpent.c @@ -119,11 +119,6 @@ extern void _gcry_serpent_avx2_cfb_dec(serpent_context_t *ctx, static const char *serpent_test (void); -#define byte_swap_32(x) \ - (0 \ - | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \ - | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) - /* * These are the S-Boxes of Serpent from following research paper. * @@ -548,14 +543,10 @@ serpent_key_prepare (const byte *key, unsigned int key_length, int i; /* Copy key. */ - memcpy (key_prepared, key, key_length); key_length /= 4; -#ifdef WORDS_BIGENDIAN for (i = 0; i < key_length; i++) - key_prepared[i] = byte_swap_32 (key_prepared[i]); -#else - i = key_length; -#endif + key_prepared[i] = buf_get_le32 (key + i * 4); + if (i < 8) { /* Key must be padded according to the Serpent @@ -683,13 +674,10 @@ serpent_encrypt_internal (serpent_context_t *context, serpent_block_t b, b_next; int round = 0; - memcpy (b, input, sizeof (b)); -#ifdef WORDS_BIGENDIAN - b[0] = byte_swap_32 (b[0]); - b[1] = byte_swap_32 (b[1]); - b[2] = byte_swap_32 (b[2]); - b[3] = byte_swap_32 (b[3]); -#endif + b[0] = buf_get_le32 (input + 0); + b[1] = buf_get_le32 (input + 4); + b[2] = buf_get_le32 (input + 8); + b[3] = buf_get_le32 (input + 12); ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); @@ -725,13 +713,10 @@ serpent_encrypt_internal (serpent_context_t *context, ROUND_LAST (7, context->keys, b, b_next); -#ifdef WORDS_BIGENDIAN - b_next[0] = byte_swap_32 (b_next[0]); - b_next[1] = byte_swap_32 (b_next[1]); - b_next[2] = byte_swap_32 (b_next[2]); - b_next[3] = byte_swap_32 (b_next[3]); -#endif - memcpy (output, b_next, sizeof (b_next)); + buf_put_le32 (output + 0, b_next[0]); + buf_put_le32 (output + 4, b_next[1]); + buf_put_le32 (output + 8, b_next[2]); + buf_put_le32 (output + 12, b_next[3]); } static void @@ -741,13 +726,10 @@ serpent_decrypt_internal (serpent_context_t *context, serpent_block_t b, b_next; int round = ROUNDS; - memcpy (b_next, input, sizeof (b)); -#ifdef WORDS_BIGENDIAN - b_next[0] = byte_swap_32 (b_next[0]); - b_next[1] = byte_swap_32 (b_next[1]); - b_next[2] = byte_swap_32 (b_next[2]); - b_next[3] = byte_swap_32 (b_next[3]); -#endif + b_next[0] = buf_get_le32 (input + 0); + b_next[1] = buf_get_le32 (input + 4); + b_next[2] = buf_get_le32 (input + 8); + b_next[3] = buf_get_le32 (input + 12); ROUND_FIRST_INVERSE (7, context->keys, b_next, b); @@ -783,13 +765,10 @@ serpent_decrypt_internal (serpent_context_t *context, ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); -#ifdef WORDS_BIGENDIAN - b_next[0] = byte_swap_32 (b_next[0]); - b_next[1] = byte_swap_32 (b_next[1]); - b_next[2] = byte_swap_32 (b_next[2]); - b_next[3] = byte_swap_32 (b_next[3]); -#endif - memcpy (output, b_next, sizeof (b_next)); + buf_put_le32 (output + 0, b_next[0]); + buf_put_le32 (output + 4, b_next[1]); + buf_put_le32 (output + 8, b_next[2]); + buf_put_le32 (output + 12, b_next[3]); } static unsigned int diff --git a/cipher/sha1.c b/cipher/sha1.c index 382bce8..aef9f05 100644 --- a/cipher/sha1.c +++ b/cipher/sha1.c @@ -38,6 +38,7 @@ #include "g10lib.h" #include "bithelp.h" +#include "bufhelp.h" #include "cipher.h" #include "hash-common.h" @@ -108,27 +109,13 @@ static unsigned int transform (void *ctx, const unsigned char *data) { SHA1_CONTEXT *hd = ctx; + const u32 *idata = (const void *)data; register u32 a, b, c, d, e; /* Local copies of the chaining variables. */ register u32 tm; /* Helper. */ u32 x[16]; /* The array we work on. */ -#ifdef WORDS_BIGENDIAN - memcpy (x, data, 64); - data += 64; -#else - { - int i; - unsigned char *p; - - for(i=0, p=(unsigned char*)x; i < 16; i++, p += 4 ) - { - p[3] = *data++; - p[2] = *data++; - p[1] = *data++; - p[0] = *data++; - } - } -#endif +#define I(i) (x[i] = buf_get_be32(idata + i)) + /* Get the values of the chaining variables. */ a = hd->h0; b = hd->h1; @@ -137,22 +124,22 @@ transform (void *ctx, const unsigned char *data) e = hd->h4; /* Transform. */ - R( a, b, c, d, e, F1, K1, x[ 0] ); - R( e, a, b, c, d, F1, K1, x[ 1] ); - R( d, e, a, b, c, F1, K1, x[ 2] ); - R( c, d, e, a, b, F1, K1, x[ 3] ); - R( b, c, d, e, a, F1, K1, x[ 4] ); - R( a, b, c, d, e, F1, K1, x[ 5] ); - R( e, a, b, c, d, F1, K1, x[ 6] ); - R( d, e, a, b, c, F1, K1, x[ 7] ); - R( c, d, e, a, b, F1, K1, x[ 8] ); - R( b, c, d, e, a, F1, K1, x[ 9] ); - R( a, b, c, d, e, F1, K1, x[10] ); - R( e, a, b, c, d, F1, K1, x[11] ); - R( d, e, a, b, c, F1, K1, x[12] ); - R( c, d, e, a, b, F1, K1, x[13] ); - R( b, c, d, e, a, F1, K1, x[14] ); - R( a, b, c, d, e, F1, K1, x[15] ); + R( a, b, c, d, e, F1, K1, I( 0) ); + R( e, a, b, c, d, F1, K1, I( 1) ); + R( d, e, a, b, c, F1, K1, I( 2) ); + R( c, d, e, a, b, F1, K1, I( 3) ); + R( b, c, d, e, a, F1, K1, I( 4) ); + R( a, b, c, d, e, F1, K1, I( 5) ); + R( e, a, b, c, d, F1, K1, I( 6) ); + R( d, e, a, b, c, F1, K1, I( 7) ); + R( c, d, e, a, b, F1, K1, I( 8) ); + R( b, c, d, e, a, F1, K1, I( 9) ); + R( a, b, c, d, e, F1, K1, I(10) ); + R( e, a, b, c, d, F1, K1, I(11) ); + R( d, e, a, b, c, F1, K1, I(12) ); + R( c, d, e, a, b, F1, K1, I(13) ); + R( b, c, d, e, a, F1, K1, I(14) ); + R( a, b, c, d, e, F1, K1, I(15) ); R( e, a, b, c, d, F1, K1, M(16) ); R( d, e, a, b, c, F1, K1, M(17) ); R( c, d, e, a, b, F1, K1, M(18) ); @@ -275,24 +262,13 @@ sha1_final(void *context) memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->bctx.buf[56] = msb >> 24; - hd->bctx.buf[57] = msb >> 16; - hd->bctx.buf[58] = msb >> 8; - hd->bctx.buf[59] = msb ; - hd->bctx.buf[60] = lsb >> 24; - hd->bctx.buf[61] = lsb >> 16; - hd->bctx.buf[62] = lsb >> 8; - hd->bctx.buf[63] = lsb ; + buf_put_be32(hd->bctx.buf + 56, msb); + buf_put_be32(hd->bctx.buf + 60, lsb); burn = transform( hd, hd->bctx.buf ); _gcry_burn_stack (burn); p = hd->bctx.buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) -#else /* little endian */ -#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ - *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0) -#endif +#define X(a) do { *(u32*)p = be_bswap32(hd->h##a) ; p += 4; } while(0) X(0); X(1); X(2); diff --git a/cipher/sha256.c b/cipher/sha256.c index cf23f2f..ad08cc7 100644 --- a/cipher/sha256.c +++ b/cipher/sha256.c @@ -42,6 +42,7 @@ #include "g10lib.h" #include "bithelp.h" +#include "bufhelp.h" #include "cipher.h" #include "hash-common.h" @@ -168,7 +169,6 @@ transform (void *ctx, const unsigned char *data) }; u32 a,b,c,d,e,f,g,h,t1,t2; - u32 x[16]; u32 w[64]; int i; @@ -181,24 +181,8 @@ transform (void *ctx, const unsigned char *data) g = hd->h6; h = hd->h7; -#ifdef WORDS_BIGENDIAN - memcpy (x, data, 64); -#else - { - byte *p2; - - for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) - { - p2[3] = *data++; - p2[2] = *data++; - p2[1] = *data++; - p2[0] = *data++; - } - } -#endif - for (i=0; i < 16; i++) - w[i] = x[i]; + w[i] = buf_get_be32(data + i * 4); for (; i < 64; i++) w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16]; @@ -312,24 +296,13 @@ sha256_final(void *context) memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->bctx.buf[56] = msb >> 24; - hd->bctx.buf[57] = msb >> 16; - hd->bctx.buf[58] = msb >> 8; - hd->bctx.buf[59] = msb; - hd->bctx.buf[60] = lsb >> 24; - hd->bctx.buf[61] = lsb >> 16; - hd->bctx.buf[62] = lsb >> 8; - hd->bctx.buf[63] = lsb; + buf_put_be32(hd->bctx.buf + 56, msb); + buf_put_be32(hd->bctx.buf + 60, lsb); burn = transform (hd, hd->bctx.buf); _gcry_burn_stack (burn); p = hd->bctx.buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) -#else /* little endian */ -#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ - *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0) -#endif +#define X(a) do { *(u32*)p = be_bswap32(hd->h##a); p += 4; } while(0) X(0); X(1); X(2); diff --git a/cipher/sha512.c b/cipher/sha512.c index 26cbe14..505a1e4 100644 --- a/cipher/sha512.c +++ b/cipher/sha512.c @@ -50,6 +50,7 @@ #include #include "g10lib.h" #include "bithelp.h" +#include "bufhelp.h" #include "cipher.h" #include "hash-common.h" @@ -225,26 +226,8 @@ __transform (SHA512_STATE *hd, const unsigned char *data) g = hd->h6; h = hd->h7; -#ifdef WORDS_BIGENDIAN - memcpy (w, data, 128); -#else - { - int i; - byte *p2; - - for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += 8) - { - p2[7] = *data++; - p2[6] = *data++; - p2[5] = *data++; - p2[4] = *data++; - p2[3] = *data++; - p2[2] = *data++; - p2[1] = *data++; - p2[0] = *data++; - } - } -#endif + for ( t = 0; t < 16; t++ ) + w[t] = buf_get_be64(data + t * 8); #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) @@ -566,35 +549,13 @@ sha512_final (void *context) memset (hd->bctx.buf, 0, 112); /* fill next block with zeroes */ } /* append the 128 bit count */ - hd->bctx.buf[112] = msb >> 56; - hd->bctx.buf[113] = msb >> 48; - hd->bctx.buf[114] = msb >> 40; - hd->bctx.buf[115] = msb >> 32; - hd->bctx.buf[116] = msb >> 24; - hd->bctx.buf[117] = msb >> 16; - hd->bctx.buf[118] = msb >> 8; - hd->bctx.buf[119] = msb; - - hd->bctx.buf[120] = lsb >> 56; - hd->bctx.buf[121] = lsb >> 48; - hd->bctx.buf[122] = lsb >> 40; - hd->bctx.buf[123] = lsb >> 32; - hd->bctx.buf[124] = lsb >> 24; - hd->bctx.buf[125] = lsb >> 16; - hd->bctx.buf[126] = lsb >> 8; - hd->bctx.buf[127] = lsb; + buf_put_be64(hd->bctx.buf + 112, msb); + buf_put_be64(hd->bctx.buf + 120, lsb); stack_burn_depth = transform (hd, hd->bctx.buf); _gcry_burn_stack (stack_burn_depth); p = hd->bctx.buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *(u64*)p = hd->state.h##a ; p += 8; } while (0) -#else /* little endian */ -#define X(a) do { *p++ = hd->state.h##a >> 56; *p++ = hd->state.h##a >> 48; \ - *p++ = hd->state.h##a >> 40; *p++ = hd->state.h##a >> 32; \ - *p++ = hd->state.h##a >> 24; *p++ = hd->state.h##a >> 16; \ - *p++ = hd->state.h##a >> 8; *p++ = hd->state.h##a; } while(0) -#endif +#define X(a) do { *(u64*)p = be_bswap64(hd->state.h##a) ; p += 8; } while (0) X (0); X (1); X (2); diff --git a/cipher/stribog.c b/cipher/stribog.c index 1f79882..61aa222 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -27,6 +27,7 @@ #include "g10lib.h" #include "bithelp.h" +#include "bufhelp.h" #include "cipher.h" #include "hash-common.h" @@ -1304,25 +1305,8 @@ transform (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) u64 l; int i; -#ifndef WORDS_BIGENDIAN - memcpy (M, data, 64); -#else - { - byte *p2; - - for (i = 0, p2 = (byte *) M; i < 8; i++, p2 += 8) - { - p2[7] = *data++; - p2[6] = *data++; - p2[5] = *data++; - p2[4] = *data++; - p2[3] = *data++; - p2[2] = *data++; - p2[1] = *data++; - p2[0] = *data++; - } - } -#endif + for (i = 0; i < 8; i++) + M[i] = buf_get_le64(data + i * 8); g (hd->h, M, hd->N); l = hd->N[0]; @@ -1379,19 +1363,8 @@ stribog_final (void *context) g (hd->h, hd->N, Z); g (hd->h, hd->Sigma, Z); -#ifdef WORDS_BIGENDIAN for (i = 0; i < 8; i++) - { - u64 T = hd->h[i]; - T = ((T & U64_C(0x00ff00ff00ff00ff)) << 8) | - ((T & U64_C(0xff00ff00ff00ff00)) >> 8); - T = ((T & U64_C(0x0000ffff0000ffff)) << 16) | - ((T & U64_C(0xffff0000ffff0000)) >> 16); - T = ((T & U64_C(0x00000000ffffffff)) << 32) | - ((T & U64_C(0xffffffff00000000)) >> 32); - hd->h[i] = T; - } -#endif + hd->h[i] = le_bswap64(hd->h[i]); _gcry_burn_stack (768); } diff --git a/cipher/tiger.c b/cipher/tiger.c index 8f5959b..df16098 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -28,6 +28,8 @@ #include "g10lib.h" #include "cipher.h" #include "hash-common.h" +#include "bithelp.h" +#include "bufhelp.h" /* We really need a 64 bit type for this code. */ #ifdef HAVE_U64_TYPEDEF @@ -697,24 +699,10 @@ transform ( void *ctx, const unsigned char *data ) TIGER_CONTEXT *hd = ctx; u64 a,b,c,aa,bb,cc; u64 x[8]; -#ifdef WORDS_BIGENDIAN -#define MKWORD(d,n) \ - ( ((u64)(d)[8*(n)+7]) << 56 | ((u64)(d)[8*(n)+6]) << 48 \ - | ((u64)(d)[8*(n)+5]) << 40 | ((u64)(d)[8*(n)+4]) << 32 \ - | ((u64)(d)[8*(n)+3]) << 24 | ((u64)(d)[8*(n)+2]) << 16 \ - | ((u64)(d)[8*(n)+1]) << 8 | ((u64)(d)[8*(n) ]) ) - x[0] = MKWORD(data, 0); - x[1] = MKWORD(data, 1); - x[2] = MKWORD(data, 2); - x[3] = MKWORD(data, 3); - x[4] = MKWORD(data, 4); - x[5] = MKWORD(data, 5); - x[6] = MKWORD(data, 6); - x[7] = MKWORD(data, 7); -#undef MKWORD -#else - memcpy( &x[0], data, 64 ); -#endif + int i; + + for ( i = 0; i < 8; i++ ) + x[i] = buf_get_le64(data + i * 8); /* save */ a = aa = hd->a; @@ -783,30 +771,14 @@ tiger_final( void *context ) memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->bctx.buf[56] = lsb ; - hd->bctx.buf[57] = lsb >> 8; - hd->bctx.buf[58] = lsb >> 16; - hd->bctx.buf[59] = lsb >> 24; - hd->bctx.buf[60] = msb ; - hd->bctx.buf[61] = msb >> 8; - hd->bctx.buf[62] = msb >> 16; - hd->bctx.buf[63] = msb >> 24; + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); burn = transform( hd, hd->bctx.buf ); _gcry_burn_stack (burn); p = hd->bctx.buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *(u64*)p = hd->a ; p += 8; } while(0) -#else /* little endian */ -#define X(a) do { *p++ = hd->a >> 56; *p++ = hd->a >> 48; \ - *p++ = hd->a >> 40; *p++ = hd->a >> 32; \ - *p++ = hd->a >> 24; *p++ = hd->a >> 16; \ - *p++ = hd->a >> 8; *p++ = hd->a; } while(0) -#endif -#define Y(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ - *p++ = hd->a >> 16; *p++ = hd->a >> 24; \ - *p++ = hd->a >> 32; *p++ = hd->a >> 40; \ - *p++ = hd->a >> 48; *p++ = hd->a >> 56; } while(0) +#define X(a) do { *(u64*)p = be_bswap64(hd->a); p += 8; } while(0) +#define Y(a) do { *(u64*)p = le_bswap64(hd->a); p += 8; } while(0) if (hd->variant == 0) { X(a); diff --git a/cipher/twofish.c b/cipher/twofish.c index 70cdb47..17b3aa3 100644 --- a/cipher/twofish.c +++ b/cipher/twofish.c @@ -798,13 +798,12 @@ extern void _gcry_twofish_amd64_cfb_dec(const TWOFISH_context *c, byte *out, * whitening subkey number m. */ #define INPACK(n, x, m) \ - x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \ - ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m] + x = buf_get_le32(in + (n) * 4); \ + x ^= ctx->w[m] #define OUTUNPACK(n, x, m) \ x ^= ctx->w[m]; \ - out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \ - out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24 + buf_put_le32(out + (n) * 4, x) #endif /*!USE_AMD64_ASM*/ diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c index 2c3beb7..954640a 100644 --- a/cipher/whirlpool.c +++ b/cipher/whirlpool.c @@ -37,7 +37,7 @@ #include "g10lib.h" #include "cipher.h" -#include "bithelp.h" +#include "bufhelp.h" /* Size of a whirlpool block (in bytes). */ #define BLOCK_SIZE 64 @@ -65,30 +65,13 @@ typedef struct { counter. */ #define buffer_to_block(buffer, block, i) \ for (i = 0; i < 8; i++) \ - (block)[i] = ((u64) (0 \ - | (((u64) (buffer)[i * 8 + 0]) << 56) \ - | (((u64) (buffer)[i * 8 + 1]) << 48) \ - | (((u64) (buffer)[i * 8 + 2]) << 40) \ - | (((u64) (buffer)[i * 8 + 3]) << 32) \ - | (((u64) (buffer)[i * 8 + 4]) << 24) \ - | (((u64) (buffer)[i * 8 + 5]) << 16) \ - | (((u64) (buffer)[i * 8 + 6]) << 8) \ - | (((u64) (buffer)[i * 8 + 7]) << 0))); + (block)[i] = buf_get_be64((buffer) + i * 8); /* Convert the block BLOCK into a buffer BUFFER, using I as counter. */ #define block_to_buffer(buffer, block, i) \ for (i = 0; i < 8; i++) \ - { \ - (buffer)[i * 8 + 0] = (block[i] >> 56) & 0xFF; \ - (buffer)[i * 8 + 1] = (block[i] >> 48) & 0xFF; \ - (buffer)[i * 8 + 2] = (block[i] >> 40) & 0xFF; \ - (buffer)[i * 8 + 3] = (block[i] >> 32) & 0xFF; \ - (buffer)[i * 8 + 4] = (block[i] >> 24) & 0xFF; \ - (buffer)[i * 8 + 5] = (block[i] >> 16) & 0xFF; \ - (buffer)[i * 8 + 6] = (block[i] >> 8) & 0xFF; \ - (buffer)[i * 8 + 7] = (block[i] >> 0) & 0xFF; \ - } + buf_put_be64((buffer) + i * 8, (block)[i]); /* Copy the block BLOCK_SRC to BLOCK_DST, using I as counter. */ #define block_copy(block_dst, block_src, i) \ diff --git a/configure.ac b/configure.ac index 91bbf4b..2c92028 100644 --- a/configure.ac +++ b/configure.ac @@ -774,6 +774,36 @@ AC_SUBST(FALLBACK_SOCKLEN_T) # +# Check for __builtin_bswap32 intrinsic. +# +AC_CACHE_CHECK(for __builtin_bswap32, + [gcry_cv_have_builtin_bswap32], + [gcry_cv_have_builtin_bswap32=no + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [[int foo(int x) { return __builtin_bswap32(x); }]])], + [gcry_cv_have_builtin_bswap32=yes])]) +if test "$gcry_cv_have_builtin_bswap32" = "yes" ; then + AC_DEFINE(HAVE_BUILTIN_BSWAP32,1, + [Defined if compiler has '__builtin_bswap32' intrinsic]) +fi + + +# +# Check for __builtin_bswap64 intrinsic. +# +AC_CACHE_CHECK(for __builtin_bswap64, + [gcry_cv_have_builtin_bswap64], + [gcry_cv_have_builtin_bswap64=no + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [[int foo(int x) { return __builtin_bswap64(x); }]])], + [gcry_cv_have_builtin_bswap64=yes])]) +if test "$gcry_cv_have_builtin_bswap64" = "yes" ; then + AC_DEFINE(HAVE_BUILTIN_BSWAP64,1, + [Defined if compiler has '__builtin_bswap64' intrinsic]) +fi + + +# # Check for VLA support (variable length arrays). # AC_CACHE_CHECK(whether the variable length arrays are supported, From jussi.kivilinna at iki.fi Thu Sep 19 13:55:16 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 14:55:16 +0300 Subject: [PATCH] Remove i386 inline assembly version of rotation functions Message-ID: <20130919115516.23830.62549.stgit@localhost6.localdomain6> * cipher/bithelp.h (rol, ror): Remove i386 version, change macros to inline functions. * src/hmac256.c (ror): Ditto. -- (Current) compilers can optimize '(x << c) | (x >> (32-c))' to rotation instruction. So remove i386 specific assembly for manually doing this. Furthermore, compiler can generate faster code in case where 'c' is constant and can use rotate with immediate value rather than rotate with %cl register. Signed-off-by: Jussi Kivilinna --- cipher/bithelp.h | 26 ++++---------------------- src/hmac256.c | 13 ++----------- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/cipher/bithelp.h b/cipher/bithelp.h index 734dcbb..601ecac 100644 --- a/cipher/bithelp.h +++ b/cipher/bithelp.h @@ -26,33 +26,15 @@ /**************** * Rotate the 32 bit unsigned integer X by N bits left/right */ -#if defined(__GNUC__) && defined(__i386__) -static inline u32 -rol( u32 x, int n) +static inline u32 rol( u32 x, int n) { - __asm__("roll %%cl,%0" - :"=r" (x) - :"0" (x),"c" (n) - :"cc"); - return x; + return ( (x << n) | (x >> (32-n)) ); } -#else -#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) -#endif -#if defined(__GNUC__) && defined(__i386__) -static inline u32 -ror(u32 x, int n) +static inline u32 ror(u32 x, int n) { - __asm__("rorl %%cl,%0" - :"=r" (x) - :"0" (x),"c" (n) - :"cc"); - return x; + return ( (x >> n) | (x << (32-n)) ); } -#else -#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) ) -#endif /* Byte swap for 32-bit and 64-bit integers. If available, use compiler provided helpers. */ diff --git a/src/hmac256.c b/src/hmac256.c index 2fda47b..94a26da 100644 --- a/src/hmac256.c +++ b/src/hmac256.c @@ -98,19 +98,10 @@ struct hmac256_context /* Rotate a 32 bit word. */ -#if defined(__GNUC__) && defined(__i386__) -static inline u32 -ror(u32 x, int n) +static inline u32 ror(u32 x, int n) { - __asm__("rorl %%cl,%0" - :"=r" (x) - :"0" (x),"c" (n) - :"cc"); - return x; + return ( ((x) >> (n)) | ((x) << (32-(n))) ); } -#else -#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) ) -#endif #define my_wipememory2(_ptr,_set,_len) do { \ volatile char *_vptr=(volatile char *)(_ptr); \ From jussi.kivilinna at iki.fi Thu Sep 19 14:08:09 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 15:08:09 +0300 Subject: [PATCH] bufhelp: enable fast unaligned memory accesses on powerpc Message-ID: <20130919120809.29613.7793.stgit@localhost6.localdomain6> * cipher/bufhelp.h [__ppc__] (BUFHELP_FAST_UNALIGNED_ACCESS): Enable macro. [__ppc64__] (BUFHELP_FAST_UNALIGNED_ACCESS): Enable macro. -- PowerPC can handle unaligned memory accesses fast, so enable fast buffer handling in bufhelp.h. Signed-off-by: Jussi Kivilinna --- cipher/bufhelp.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h index c637dac..e7beffb 100644 --- a/cipher/bufhelp.h +++ b/cipher/bufhelp.h @@ -34,6 +34,7 @@ #if defined(__i386__) || defined(__x86_64__) || \ + defined(__ppc__) || defined(__ppc64__) || \ (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) /* These architectures are able of unaligned memory accesses and can handle those fast. From wk at gnupg.org Thu Sep 19 16:41:12 2013 From: wk at gnupg.org (Werner Koch) Date: Thu, 19 Sep 2013 16:41:12 +0200 Subject: [PATCH] Fix Stribog digest on bigendian platforms In-Reply-To: <1379300113-22064-1-git-send-email-dbaryshkov@gmail.com> (Dmitry Eremin-Solenikov's message of "Mon, 16 Sep 2013 06:55:13 +0400") References: <1379300113-22064-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <87vc1wub5j.fsf@vigenere.g10code.de> On Mon, 16 Sep 2013 04:55, dbaryshkov at gmail.com said: > * cipher/stribog.c (stribog_final): swap bytes in the result of digest > calculations. Pushed. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Thu Sep 19 17:02:57 2013 From: wk at gnupg.org (Werner Koch) Date: Thu, 19 Sep 2013 17:02:57 +0200 Subject: commit logs Message-ID: <87r4ckua5a.fsf@vigenere.g10code.de> Hi! commit logs for git.gnupg.org are send to the gnupg-commits mailing list. That is a catch all ML for all GnuPG related commit. However, there are only about 70 subscribers and I don't know whether they really scan the commits. Given that we now see a flow of patch proposals to this list here (gcrypt-devel), I wonder whether we may want to send commit logs for Libgcrypt also to here. The drawback is that the traffic will increase a bit. Shall we try that for some time? All branches or just master? Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From jussi.kivilinna at iki.fi Thu Sep 19 18:37:42 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 19:37:42 +0300 Subject: commit logs In-Reply-To: <87r4ckua5a.fsf@vigenere.g10code.de> References: <87r4ckua5a.fsf@vigenere.g10code.de> Message-ID: <523B2856.8040304@iki.fi> On 19.09.2013 18:02, Werner Koch wrote: > Hi! > > commit logs for git.gnupg.org are send to the gnupg-commits mailing > list. That is a catch all ML for all GnuPG related commit. However, > there are only about 70 subscribers and I don't know whether they really > scan the commits. > > Given that we now see a flow of patch proposals to this list here > (gcrypt-devel), I wonder whether we may want to send commit logs for > Libgcrypt also to here. The drawback is that the traffic will increase > a bit. It would give easier chance to comment patches that otherwise do not appear on mailing-list. I'd personally prefer on posting all patches to mailing list before pushing. > > Shall we try that for some time? All branches or just master? > Sure. I think master is enough, since stable changes are announced anyway. -Jussi > > Shalom-Salam, > > Werner > From grothoff at in.tum.de Thu Sep 19 17:55:17 2013 From: grothoff at in.tum.de (Christian Grothoff) Date: Thu, 19 Sep 2013 17:55:17 +0200 Subject: commit logs In-Reply-To: <87r4ckua5a.fsf@vigenere.g10code.de> References: <87r4ckua5a.fsf@vigenere.g10code.de> Message-ID: <523B1E65.3040803@in.tum.de> I dislike the idea of having both on one list, it is likely to simply decrease the number of subscribers here, without having a meaningful impact on the number of meaningful code audits. I didn't even know there was a gnupg-commits mailinglist before, so telling people about it and asking them to subscribe if they're willing and able to look over the commits is a better idea. My 2 cents Christian On 09/19/2013 05:02 PM, Werner Koch wrote: > Hi! > > commit logs for git.gnupg.org are send to the gnupg-commits mailing > list. That is a catch all ML for all GnuPG related commit. However, > there are only about 70 subscribers and I don't know whether they really > scan the commits. > > Given that we now see a flow of patch proposals to this list here > (gcrypt-devel), I wonder whether we may want to send commit logs for > Libgcrypt also to here. The drawback is that the traffic will increase > a bit. > > Shall we try that for some time? All branches or just master? > > > Shalom-Salam, > > Werner > -------------- next part -------------- A non-text attachment was scrubbed... Name: 0x48426C7E.asc Type: application/pgp-keys Size: 7098 bytes Desc: not available URL: From jussi.kivilinna at iki.fi Thu Sep 19 20:16:13 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 21:16:13 +0300 Subject: [PATCH 1/3] whirlpool: do bitcount calculation in finalization part Message-ID: <20130919181613.9047.22205.stgit@localhost6.localdomain6> * cipher/whirlpool.c (whirlpool_context_t): Remove 'length', add 'nblocks'. (whirlpool_add): Update 'nblocks' instead of 'length', and add early return at one spot. (whirlpool_write): Check for 'nblocks' overflow. (whirlpool_final): Convert 'nblocks' to bit-counter, and use whirlpool_write instead of whirlpool_add. -- Currently Whirlpool uses large 256 bit counter that is increased in the 'write' function. However, we could to bit counter calculation as is done in all the rest hash algorithms; use 64-bit block counter that is converted to bit counter in finalization function. This change does limit amount of bytes Whirlpool can process before overflowing bit counter. With 256-bit counter, overflow happens after ~1.3e67 gigabytes. With 64-bit block counter, overflow happens just after ~1.1e12 gigabytes. Main benefit for this patch is that after this change, we can use the _gcry_md_block_write helper for Whirlpool too. Signed-off-by: Jussi Kivilinna --- cipher/whirlpool.c | 58 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c index 954640a..1ee8916 100644 --- a/cipher/whirlpool.c +++ b/cipher/whirlpool.c @@ -54,7 +54,7 @@ typedef struct { whirlpool_block_t hash_state; unsigned char buffer[BLOCK_SIZE]; size_t count; - unsigned char length[32]; + u64 nblocks; } whirlpool_context_t; @@ -1274,11 +1274,6 @@ whirlpool_add (whirlpool_context_t *context, const void *buffer_arg, size_t buffer_n) { const unsigned char *buffer = buffer_arg; - u64 buffer_size; - unsigned int carry; - unsigned int i; - - buffer_size = buffer_n; if (context->count == BLOCK_SIZE) { @@ -1286,6 +1281,7 @@ whirlpool_add (whirlpool_context_t *context, whirlpool_transform (context, context->buffer); /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */ context->count = 0; + context->nblocks++; } if (! buffer) return; /* Nothing to add. */ @@ -1298,6 +1294,9 @@ whirlpool_add (whirlpool_context_t *context, buffer_n--; } whirlpool_add (context, NULL, 0); + /* Can return early now that bit counter calculation is done in final. */ + if (!buffer_n) + return; } /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */ @@ -1305,6 +1304,7 @@ whirlpool_add (whirlpool_context_t *context, { whirlpool_transform (context, buffer); context->count = 0; + context->nblocks++; buffer_n -= BLOCK_SIZE; buffer += BLOCK_SIZE; } @@ -1313,29 +1313,17 @@ whirlpool_add (whirlpool_context_t *context, context->buffer[context->count++] = *buffer++; buffer_n--; } - - /* Update bit counter. */ - carry = 0; - buffer_size <<= 3; - for (i = 1; i <= 32; i++) - { - if (! (buffer_size || carry)) - break; - - carry += context->length[32 - i] + (buffer_size & 0xFF); - context->length[32 - i] = carry; - buffer_size >>= 8; - carry >>= 8; - } - gcry_assert (! (buffer_size || carry)); } static void whirlpool_write (void *ctx, const void *buffer, size_t buffer_n) { whirlpool_context_t *context = ctx; + u64 old_nblocks = context->nblocks; whirlpool_add (context, buffer, buffer_n); + + gcry_assert (old_nblocks <= context->nblocks); } static void @@ -1343,9 +1331,25 @@ whirlpool_final (void *ctx) { whirlpool_context_t *context = ctx; unsigned int i; + u64 t, lsb, msb; + unsigned char *length; + + t = context->nblocks; + /* multiply by 64 to make a byte count */ + lsb = t << 6; + msb = t >> 58; + /* add the count */ + t = lsb; + if ((lsb += context->count) < t) + msb++; + /* multiply by 8 to make a bit count */ + t = lsb; + lsb <<= 3; + msb <<= 3; + msb |= t >> 61; /* Flush. */ - whirlpool_add (context, NULL, 0); + whirlpool_write (context, NULL, 0); /* Pad. */ context->buffer[context->count++] = 0x80; @@ -1355,15 +1359,19 @@ whirlpool_final (void *ctx) /* An extra block is necessary. */ while (context->count < 64) context->buffer[context->count++] = 0; - whirlpool_add (context, NULL, 0); + whirlpool_write (context, NULL, 0); } while (context->count < 32) context->buffer[context->count++] = 0; /* Add length of message. */ - memcpy (context->buffer + context->count, context->length, 32); + length = context->buffer + context->count; + buf_put_be64(&length[0 * 8], 0); + buf_put_be64(&length[1 * 8], 0); + buf_put_be64(&length[2 * 8], msb); + buf_put_be64(&length[3 * 8], lsb); context->count += 32; - whirlpool_add (context, NULL, 0); + whirlpool_write (context, NULL, 0); block_to_buffer (context->buffer, context->hash_state, i); } From jussi.kivilinna at iki.fi Thu Sep 19 20:16:23 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 21:16:23 +0300 Subject: [PATCH 3/3] Make Whirlpool use the _gcry_md_block_write helper In-Reply-To: <20130919181613.9047.22205.stgit@localhost6.localdomain6> References: <20130919181613.9047.22205.stgit@localhost6.localdomain6> Message-ID: <20130919181623.9047.87786.stgit@localhost6.localdomain6> * cipher/whirlpool.c (whirlpool_context_t): Add 'bctx', remove 'buffer', 'count' and 'nblocks'. (whirlpool_init): Initialize 'bctx'. (whirlpool_transform): Adjust context argument type and burn stack depth. (whirlpool_add): Remove. (whirlpool_write): Use _gcry_md_block_write. (whirlpool_final, whirlpool_read): Adjust for 'bctx' usage. -- Signed-off-by: Jussi Kivilinna --- cipher/whirlpool.c | 97 +++++++++++++++------------------------------------- 1 file changed, 28 insertions(+), 69 deletions(-) diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c index 6b5f1a9..fa632f9 100644 --- a/cipher/whirlpool.c +++ b/cipher/whirlpool.c @@ -38,6 +38,7 @@ #include "cipher.h" #include "bufhelp.h" +#include "hash-common.h" /* Size of a whirlpool block (in bytes). */ #define BLOCK_SIZE 64 @@ -51,10 +52,8 @@ typedef u64 whirlpool_block_t[BLOCK_SIZE / 8]; typedef struct { + gcry_md_block_ctx_t bctx; whirlpool_block_t hash_state; - unsigned char buffer[BLOCK_SIZE]; - size_t count; - u64 nblocks; } whirlpool_context_t; @@ -1161,12 +1160,20 @@ static const u64 C7[256] = +static unsigned int +whirlpool_transform (void *ctx, const unsigned char *data); + + + static void whirlpool_init (void *ctx) { whirlpool_context_t *context = ctx; memset (context, 0, sizeof (*context)); + + context->bctx.blocksize = BLOCK_SIZE; + context->bctx.bwrite = whirlpool_transform; } @@ -1174,8 +1181,9 @@ whirlpool_init (void *ctx) * Transform block. */ static unsigned int -whirlpool_transform (whirlpool_context_t *context, const unsigned char *data) +whirlpool_transform (void *ctx, const unsigned char *data) { + whirlpool_context_t *context = ctx; whirlpool_block_t data_block; whirlpool_block_t key; whirlpool_block_t state; @@ -1269,67 +1277,18 @@ whirlpool_transform (whirlpool_context_t *context, const unsigned char *data) block_xor (context->hash_state, state, i); return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + - 3 * sizeof(void*); -} - -static void -whirlpool_add (whirlpool_context_t *context, - const void *buffer_arg, size_t buffer_n) -{ - const unsigned char *buffer = buffer_arg; - unsigned int burn = 0; - - if (context->count == BLOCK_SIZE) - { - /* Flush the buffer. */ - burn = whirlpool_transform (context, context->buffer); - _gcry_burn_stack (burn); - burn = 0; - context->count = 0; - context->nblocks++; - } - if (! buffer) - return; /* Nothing to add. */ - - if (context->count) - { - while (buffer_n && (context->count < BLOCK_SIZE)) - { - context->buffer[context->count++] = *buffer++; - buffer_n--; - } - whirlpool_add (context, NULL, 0); - /* Can return early now that bit counter calculation is done in final. */ - if (!buffer_n) - return; - } - - while (buffer_n >= BLOCK_SIZE) - { - burn = whirlpool_transform (context, buffer); - context->count = 0; - context->nblocks++; - buffer_n -= BLOCK_SIZE; - buffer += BLOCK_SIZE; - } - while (buffer_n && (context->count < BLOCK_SIZE)) - { - context->buffer[context->count++] = *buffer++; - buffer_n--; - } - - _gcry_burn_stack (burn); + 4 * sizeof(void*); } static void whirlpool_write (void *ctx, const void *buffer, size_t buffer_n) { whirlpool_context_t *context = ctx; - u64 old_nblocks = context->nblocks; + u64 old_nblocks = context->bctx.nblocks; - whirlpool_add (context, buffer, buffer_n); + _gcry_md_block_write (context, buffer, buffer_n); - gcry_assert (old_nblocks <= context->nblocks); + gcry_assert (old_nblocks <= context->bctx.nblocks); } static void @@ -1340,13 +1299,13 @@ whirlpool_final (void *ctx) u64 t, lsb, msb; unsigned char *length; - t = context->nblocks; + t = context->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 58; /* add the count */ t = lsb; - if ((lsb += context->count) < t) + if ((lsb += context->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -1358,28 +1317,28 @@ whirlpool_final (void *ctx) whirlpool_write (context, NULL, 0); /* Pad. */ - context->buffer[context->count++] = 0x80; + context->bctx.buf[context->bctx.count++] = 0x80; - if (context->count > 32) + if (context->bctx.count > 32) { /* An extra block is necessary. */ - while (context->count < 64) - context->buffer[context->count++] = 0; + while (context->bctx.count < 64) + context->bctx.buf[context->bctx.count++] = 0; whirlpool_write (context, NULL, 0); } - while (context->count < 32) - context->buffer[context->count++] = 0; + while (context->bctx.count < 32) + context->bctx.buf[context->bctx.count++] = 0; /* Add length of message. */ - length = context->buffer + context->count; + length = context->bctx.buf + context->bctx.count; buf_put_be64(&length[0 * 8], 0); buf_put_be64(&length[1 * 8], 0); buf_put_be64(&length[2 * 8], msb); buf_put_be64(&length[3 * 8], lsb); - context->count += 32; + context->bctx.count += 32; whirlpool_write (context, NULL, 0); - block_to_buffer (context->buffer, context->hash_state, i); + block_to_buffer (context->bctx.buf, context->hash_state, i); } static byte * @@ -1387,7 +1346,7 @@ whirlpool_read (void *ctx) { whirlpool_context_t *context = ctx; - return context->buffer; + return context->bctx.buf; } gcry_md_spec_t _gcry_digest_spec_whirlpool = From jussi.kivilinna at iki.fi Thu Sep 19 20:16:18 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 19 Sep 2013 21:16:18 +0300 Subject: [PATCH 2/3] whirlpool: add stack burning after transform In-Reply-To: <20130919181613.9047.22205.stgit@localhost6.localdomain6> References: <20130919181613.9047.22205.stgit@localhost6.localdomain6> Message-ID: <20130919181618.9047.47063.stgit@localhost6.localdomain6> * cipher/whirlpool.c (whirlpool_transform): Return burn stack depth. (whirlpool_add): Do burn_stack. -- Signed-off-by: Jussi Kivilinna --- cipher/whirlpool.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c index 1ee8916..6b5f1a9 100644 --- a/cipher/whirlpool.c +++ b/cipher/whirlpool.c @@ -1173,7 +1173,7 @@ whirlpool_init (void *ctx) /* * Transform block. */ -static void +static unsigned int whirlpool_transform (whirlpool_context_t *context, const unsigned char *data) { whirlpool_block_t data_block; @@ -1267,6 +1267,9 @@ whirlpool_transform (whirlpool_context_t *context, const unsigned char *data) block_xor (context->hash_state, data_block, i); block_xor (context->hash_state, state, i); + + return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + + 3 * sizeof(void*); } static void @@ -1274,12 +1277,14 @@ whirlpool_add (whirlpool_context_t *context, const void *buffer_arg, size_t buffer_n) { const unsigned char *buffer = buffer_arg; + unsigned int burn = 0; if (context->count == BLOCK_SIZE) { /* Flush the buffer. */ - whirlpool_transform (context, context->buffer); - /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */ + burn = whirlpool_transform (context, context->buffer); + _gcry_burn_stack (burn); + burn = 0; context->count = 0; context->nblocks++; } @@ -1298,11 +1303,10 @@ whirlpool_add (whirlpool_context_t *context, if (!buffer_n) return; } - /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */ while (buffer_n >= BLOCK_SIZE) { - whirlpool_transform (context, buffer); + burn = whirlpool_transform (context, buffer); context->count = 0; context->nblocks++; buffer_n -= BLOCK_SIZE; @@ -1313,6 +1317,8 @@ whirlpool_add (whirlpool_context_t *context, context->buffer[context->count++] = *buffer++; buffer_n--; } + + _gcry_burn_stack (burn); } static void From dbaryshkov at gmail.com Thu Sep 19 20:40:20 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 19 Sep 2013 22:40:20 +0400 Subject: GOST ECC pubkey Message-ID: Hi, I'm currently looking into implementing GOST R 34.10 digital signatures. Basically they are Weierstrass elliptic curves. Two main differences from ECDSA: 1) Different equations to calculate r and s. 2) Different set of curves defined in standards/RFCs. What would you recommend me as the user interface for this pubkey? Would just a flag (like it is done for EdDSA) be enough? Should I add new s-exp type? Would you mind having a single table with both ECDSA and GOST curves? (because nobody except standards stops you from using then for other algorithms) -- With best wishes Dmitry From chris at chatsecure.org Fri Sep 20 01:59:56 2013 From: chris at chatsecure.org (Chris Ballinger) Date: Thu, 19 Sep 2013 16:59:56 -0700 Subject: --disable-asm flag not being fully honored Message-ID: When I use the --disable-asm flag it seems to not respect that setting when compiling. I was finally able to get it to compile with clang by explicitly also including the -DNO_ASM flag in CFLAGS. The main issues were related to this code (even with --disable-asm): mpih-div.c:104:6: warning: invalid use of a cast in an inline asm context requiring an l-value: accepted due to -fheinous-gnu-extensions, but clang may remove support for this in the future UDIV_QRNND_PREINV(dummy, r, r, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./mpi-internal.h:150:17: note: expanded from macro 'UDIV_QRNND_PREINV' umul_ppmm (_q, _ql, (nh), (di)); \ ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~ ./longlong.h:231:24: note: expanded from macro 'umul_ppmm' "=r" ((USItype)(xl)) \ ^ mpih-div.c:104:6: error: invalid % escape in inline assembly string UDIV_QRNND_PREINV(dummy, r, r, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -------------- next part -------------- An HTML attachment was scrubbed... URL: From gniibe at fsij.org Fri Sep 20 07:07:10 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 20 Sep 2013 14:07:10 +0900 Subject: GOST ECC pubkey In-Reply-To: References: Message-ID: <1379653630.3179.2.camel@cfw2.gniibe.org> On 2013-09-19 at 22:40 +0400, Dmitry Eremin-Solenikov wrote: > I'm currently looking into implementing GOST R 34.10 digital signatures. > Basically they are Weierstrass elliptic curves. Two main differences from ECDSA: > 1) Different equations to calculate r and s. > 2) Different set of curves defined in standards/RFCs. > > What would you recommend me as the user interface for this pubkey? > Would just a flag (like it is done for EdDSA) be enough? Should I add new s-exp > type? I read through the document, draft-dolmatov-gost34102012-00. IIUC, its domain parameters consist of: (p, a, b, m, q, P). p: the prime. a, b: coefficients which define the curve E. m: the order of the curve q: order of cyclic subgroup of elliptic curve points group P: something like base point where q * P = O Thus, I think that we need to extend the structure ecc_domain_parms_t to include "q", at first. To represent as SEXP, we need to use a character other than "q" for the order of cyclic subgroup, as it is used for Q already, as the public key. -- From gniibe at fsij.org Fri Sep 20 07:33:45 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 20 Sep 2013 14:33:45 +0900 Subject: GOST ECC pubkey In-Reply-To: <1379653630.3179.2.camel@cfw2.gniibe.org> References: <1379653630.3179.2.camel@cfw2.gniibe.org> Message-ID: <1379655225.3179.3.camel@cfw2.gniibe.org> On 2013-09-20 at 14:07 +0900, NIIBE Yutaka wrote: > I read through the document, draft-dolmatov-gost34102012-00. > > IIUC, its domain parameters consist of: (p, a, b, m, q, P). > > p: the prime. > a, b: coefficients which define the curve E. > m: the order of the curve > q: order of cyclic subgroup of elliptic curve points group > P: something like base point where q * P = O > > Thus, I think that we need to extend the structure ecc_domain_parms_t > to include "q", at first. No, I was wrong. Sorry. In the process of computation of signature or verification of signature, we don't use m, the order of the curve at all. I think that it is possible to represent GOST3410 without extending the structure ecc_domain_parms_t. Just redefine "n" as order of cyclic subgroup of elliptic curve points group for GOST3410. p: the prime a, b: coefficients which define the curve E. n: order of cyclic subgroup of elliptic curve points group G: n * G = O -- From wk at gnupg.org Fri Sep 20 11:00:15 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 20 Sep 2013 11:00:15 +0200 Subject: GOST ECC pubkey In-Reply-To: (Dmitry Eremin-Solenikov's message of "Thu, 19 Sep 2013 22:40:20 +0400") References: Message-ID: <87wqmbrhpc.fsf@vigenere.g10code.de> On Thu, 19 Sep 2013 20:40, dbaryshkov at gmail.com said: > I'm currently looking into implementing GOST R 34.10 digital signatures. > Basically they are Weierstrass elliptic curves. Two main differences from ECDSA: > 1) Different equations to calculate r and s. Which makes them different from ECDSA. You may have noticed that I am working on Ed25519 and for that I changed quite some stuff to support different ECC models. > 2) Different set of curves defined in standards/RFCs. All curves should go into ecc-curves.c. > What would you recommend me as the user interface for this pubkey? > Would just a flag (like it is done for EdDSA) be enough? Should I I am currently wondering how this can be done best. One of the problems I am facing is that we use those GCRY_PK_ECDSA et al identifiers. They have their origin in OpenPGP but I am not sure whether they make lot of sense these days. With the old algorithm like RSA we only had one parameter (key size) to fully describe the algorithm. Implementations of RSA usually supported all key sizes up to a an upper limit. With ECC this is not anymore the case. An implementation may for example support only a certain curve and describing each curve using an algorithm identifier would end up in the same big mess as the combined TLS algorithms ids. The idea for the "eddsa" flag stems from the use of flags to describe the RSA encodings ("pkcs1", "pss", etc.) it does not go nicely with ecdsa and ecdh algorithm descriptions. An option would be to always use the tag "ecc" for the key proper and "ecdsa", "ecdh", "eddsa" for the signature and encryption schemes. "gostsig" or whatever would be easy to add. Given that 1.6 is an API break, we could also decide to remove GCRY_PK_ECDSA and GCRY_PK_ECDH and replace them by a genericGCRY_PK_ECC. The different ECC schemes would then be identified by flags like we do it for RSA encodings. I am currently working on moving the s-expression parsing from pubkey.c into the modules implementing the algorithms. This saves a lot of overhead and would be a prerequisite to maybe drop the algorithm ids for public key algorithms in their entire. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Fri Sep 20 11:07:35 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 20 Sep 2013 11:07:35 +0200 Subject: --disable-asm flag not being fully honored In-Reply-To: (Chris Ballinger's message of "Thu, 19 Sep 2013 16:59:56 -0700") References: Message-ID: <87siwzrhd4.fsf@vigenere.g10code.de> On Fri, 20 Sep 2013 01:59, chris at chatsecure.org said: > When I use the --disable-asm flag it seems to not respect that setting when > compiling. I was finally able to get it to compile with clang by explicitly > also including the -DNO_ASM flag in CFLAGS. --disable-asm only disables the use of the MPI assembler modules but not of the other asm functions. > requiring an l-value: accepted due to > -fheinous-gnu-extensions, but clang may remove support for this in > the future Clang should not pretend to be GCC (by defining __GNUC__) if it does not exactly behave like GCC. I am very annoyed about that hijacking and the problems this creates for software maintainers. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From jussi.kivilinna at iki.fi Fri Sep 20 11:44:18 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Fri, 20 Sep 2013 12:44:18 +0300 Subject: --disable-asm flag not being fully honored In-Reply-To: <87siwzrhd4.fsf@vigenere.g10code.de> References: <87siwzrhd4.fsf@vigenere.g10code.de> Message-ID: <523C18F2.7080909@iki.fi> On 20.09.2013 12:07, Werner Koch wrote: > On Fri, 20 Sep 2013 01:59, chris at chatsecure.org said: >> When I use the --disable-asm flag it seems to not respect that setting when >> compiling. I was finally able to get it to compile with clang by explicitly >> also including the -DNO_ASM flag in CFLAGS. > > --disable-asm only disables the use of the MPI assembler modules but not > of the other asm functions. > >> requiring an l-value: accepted due to >> -fheinous-gnu-extensions, but clang may remove support for this in >> the future > > Clang should not pretend to be GCC (by defining __GNUC__) if it does not > exactly behave like GCC. I am very annoyed about that hijacking and the > problems this creates for software maintainers. > Maybe we could add Clang detection to configure.ac and then #undef __GNUC__ if compiler is Clang. This would be because "GCC support" in Clang appears to be broken. -Jussi > > Salam-Shalom, > > Werner > From wk at gnupg.org Fri Sep 20 13:53:52 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 20 Sep 2013 13:53:52 +0200 Subject: --disable-asm flag not being fully honored In-Reply-To: <523C18F2.7080909@iki.fi> (Jussi Kivilinna's message of "Fri, 20 Sep 2013 12:44:18 +0300") References: <87siwzrhd4.fsf@vigenere.g10code.de> <523C18F2.7080909@iki.fi> Message-ID: <874n9fr9nz.fsf@vigenere.g10code.de> On Fri, 20 Sep 2013 11:44, jussi.kivilinna at iki.fi said: > Maybe we could add Clang detection to configure.ac and then #undef __GNUC__ if compiler is Clang. This would be because "GCC support" in Clang appears to be broken. ./configure --disable-heinous-clang-illness ? Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Fri Sep 20 13:57:46 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 20 Sep 2013 13:57:46 +0200 Subject: commit logs In-Reply-To: <523B2856.8040304@iki.fi> (Jussi Kivilinna's message of "Thu, 19 Sep 2013 19:37:42 +0300") References: <87r4ckua5a.fsf@vigenere.g10code.de> <523B2856.8040304@iki.fi> Message-ID: <87zjr7pux1.fsf@vigenere.g10code.de> On Thu, 19 Sep 2013 18:37, jussi.kivilinna at iki.fi said: > It would give easier chance to comment patches that otherwise do not appear on > mailing-list. I'd personally prefer on posting all patches to mailing list > before pushing. Although this is not how I am used to work, I appreciate seeing your patches on the ML. I do not audit them, though. That is better done after they have been pushed. > Sure. I think master is enough, since stable changes are announced anyway. Let's enable it for a few weeks as an experiment, okay? Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Fri Sep 20 15:21:05 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 20 Sep 2013 15:21:05 +0200 Subject: [PATCH 1/3] whirlpool: do bitcount calculation in finalization part In-Reply-To: <20130919181613.9047.22205.stgit@localhost6.localdomain6> (Jussi Kivilinna's message of "Thu, 19 Sep 2013 21:16:13 +0300") References: <20130919181613.9047.22205.stgit@localhost6.localdomain6> Message-ID: <87vc1vpr26.fsf@vigenere.g10code.de> On Thu, 19 Sep 2013 20:16, jussi.kivilinna at iki.fi said: > With 256-bit counter, overflow happens after ~1.3e67 gigabytes. With 64-bit > block counter, overflow happens just after ~1.1e12 gigabytes. You better check with the NSA that this is okay for their data centers ;-) Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From jussi.kivilinna at iki.fi Fri Sep 20 15:44:13 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Fri, 20 Sep 2013 16:44:13 +0300 Subject: [PATCH 1/3] whirlpool: do bitcount calculation in finalization part In-Reply-To: <87vc1vpr26.fsf@vigenere.g10code.de> References: <20130919181613.9047.22205.stgit@localhost6.localdomain6> <87vc1vpr26.fsf@vigenere.g10code.de> Message-ID: <523C512D.3060500@iki.fi> On 20.09.2013 16:21, Werner Koch wrote: > On Thu, 19 Sep 2013 20:16, jussi.kivilinna at iki.fi said: > >> With 256-bit counter, overflow happens after ~1.3e67 gigabytes. With 64-bit >> block counter, overflow happens just after ~1.1e12 gigabytes. > > You better check with the NSA that this is okay for their data centers > ;-) Oh, someone might actually want hash for over 1 zettabyte of data (in distant future). If this is really needed, the nblocks overflow assert in whirlpool_white can be turned in to carry handling. - Jussi > > > Shalom-Salam, > > Werner > From jussi.kivilinna at iki.fi Fri Sep 20 16:22:43 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Fri, 20 Sep 2013 17:22:43 +0300 Subject: --disable-asm flag not being fully honored In-Reply-To: <874n9fr9nz.fsf@vigenere.g10code.de> References: <87siwzrhd4.fsf@vigenere.g10code.de> <523C18F2.7080909@iki.fi> <874n9fr9nz.fsf@vigenere.g10code.de> Message-ID: <523C5A33.3060701@iki.fi> On 20.09.2013 14:53, Werner Koch wrote: > On Fri, 20 Sep 2013 11:44, jussi.kivilinna at iki.fi said: > >> Maybe we could add Clang detection to configure.ac and then #undef __GNUC__ if compiler is Clang. This would be because "GCC support" in Clang appears to be broken. > > ./configure --disable-heinous-clang-illness > > ? Users are still going to try Clang and complain when libgcrypt does not work out of box with it. Maybe this should be dealt as portability issue and accept fact that there are broken compilers that lie about their ability to behave as GCC within '#ifdef __GNUC__/#endif'. So instead of checking for Clang specifically, we could add check for broken __GNUC__. -Jussi > > > Shalom-Salam, > > Werner > From jussi.kivilinna at iki.fi Fri Sep 20 18:32:51 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Fri, 20 Sep 2013 19:32:51 +0300 Subject: commit logs In-Reply-To: <87zjr7pux1.fsf@vigenere.g10code.de> References: <87r4ckua5a.fsf@vigenere.g10code.de> <523B2856.8040304@iki.fi> <87zjr7pux1.fsf@vigenere.g10code.de> Message-ID: <523C78B3.8070607@iki.fi> On 20.09.2013 14:57, Werner Koch wrote: > On Thu, 19 Sep 2013 18:37, jussi.kivilinna at iki.fi said: > >> It would give easier chance to comment patches that otherwise do not appear on >> mailing-list. I'd personally prefer on posting all patches to mailing list >> before pushing. > > Although this is not how I am used to work, I appreciate seeing your > patches on the ML. I do not audit them, though. That is better done > after they have been pushed. > >> Sure. I think master is enough, since stable changes are announced anyway. > > Let's enable it for a few weeks as an experiment, okay? I'm ok with it. > > > Salam-Shalom, > > Werner > From dbaryshkov at gmail.com Fri Sep 20 18:46:08 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 20 Sep 2013 20:46:08 +0400 Subject: commit logs In-Reply-To: <87zjr7pux1.fsf@vigenere.g10code.de> References: <87r4ckua5a.fsf@vigenere.g10code.de> <523B2856.8040304@iki.fi> <87zjr7pux1.fsf@vigenere.g10code.de> Message-ID: Hello, On Fri, Sep 20, 2013 at 3:57 PM, Werner Koch wrote: > On Thu, 19 Sep 2013 18:37, jussi.kivilinna at iki.fi said: > >> It would give easier chance to comment patches that otherwise do not appear on >> mailing-list. I'd personally prefer on posting all patches to mailing list >> before pushing. > > Although this is not how I am used to work, I appreciate seeing your > patches on the ML. I do not audit them, though. That is better done > after they have been pushed. What about having read-only gcrypt-commits ML with Reply-To: header set to gcrypt-devel ML ? -- With best wishes Dmitry From chris at chatsecure.org Fri Sep 20 21:07:43 2013 From: chris at chatsecure.org (Chris Ballinger) Date: Fri, 20 Sep 2013 12:07:43 -0700 Subject: --disable-asm flag not being fully honored In-Reply-To: <523C5A33.3060701@iki.fi> References: <87siwzrhd4.fsf@vigenere.g10code.de> <523C18F2.7080909@iki.fi> <874n9fr9nz.fsf@vigenere.g10code.de> <523C5A33.3060701@iki.fi> Message-ID: Yeah that sounds good to me. I wasn't trying to start a compiler war... It would be nice to eventually be able to use the ARM and x86 (especially AES-NI) assembly with clang in a way that maintains compatibility with GCC, but I'm not exactly sure what that would entail. Also, the --disable-asm flag I think should be renamed to --disable-mpi-asm if that's all it does and a new option called --disable-asm actually disable all use of assembler. Or at the very least mention in the docs that --disable-asm doesn't disable asm and you need to manually pass -DNO_ASM in your CFLAGS. On Fri, Sep 20, 2013 at 7:22 AM, Jussi Kivilinna wrote: > On 20.09.2013 14:53, Werner Koch wrote: > > On Fri, 20 Sep 2013 11:44, jussi.kivilinna at iki.fi said: > > > >> Maybe we could add Clang detection to configure.ac and then #undef > __GNUC__ if compiler is Clang. This would be because "GCC support" in Clang > appears to be broken. > > > > ./configure --disable-heinous-clang-illness > > > > ? > > Users are still going to try Clang and complain when libgcrypt does not > work out of box with it. > > Maybe this should be dealt as portability issue and accept fact that there > are broken compilers that lie about their ability to behave as GCC within > '#ifdef __GNUC__/#endif'. So instead of checking for Clang specifically, we > could add check for broken __GNUC__. > > -Jussi > > > > > > > Shalom-Salam, > > > > Werner > > > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jussi.kivilinna at iki.fi Sat Sep 21 12:47:59 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 21 Sep 2013 13:47:59 +0300 Subject: --disable-asm flag not being fully honored In-Reply-To: References: <87siwzrhd4.fsf@vigenere.g10code.de> <523C18F2.7080909@iki.fi> <874n9fr9nz.fsf@vigenere.g10code.de> <523C5A33.3060701@iki.fi> Message-ID: <523D795F.9050307@iki.fi> On 20.09.2013 22:07, Chris Ballinger wrote: > Yeah that sounds good to me. I wasn't trying to start a compiler war... > > It would be nice to eventually be able to use the ARM and x86 (especially AES-NI) assembly with clang in a way that maintains compatibility with GCC, but I'm not exactly sure what that would entail. > > Also, the --disable-asm flag I think should be renamed to --disable-mpi-asm if that's all it does and a new option called --disable-asm actually disable all use of assembler. Or at the very least mention in the docs that --disable-asm doesn't disable asm and you need to manually pass -DNO_ASM in your CFLAGS. > I did some testing with clang, on x86-64 libgcrypt builds just fine (even AES-NI is enabled). On i386, only problem is with mpi/longlong.h and easiest change is to add !__clang__ check (or make those changes that clang wants). -Jussi > > On Fri, Sep 20, 2013 at 7:22 AM, Jussi Kivilinna > wrote: > > On 20.09.2013 14:53, Werner Koch wrote: > > On Fri, 20 Sep 2013 11:44, jussi.kivilinna at iki.fi said: > > > >> Maybe we could add Clang detection to configure.ac and then #undef __GNUC__ if compiler is Clang. This would be because "GCC support" in Clang appears to be broken. > > > > ./configure --disable-heinous-clang-illness > > > > ? > > Users are still going to try Clang and complain when libgcrypt does not work out of box with it. > > Maybe this should be dealt as portability issue and accept fact that there are broken compilers that lie about their ability to behave as GCC within '#ifdef __GNUC__/#endif'. So instead of checking for Clang specifically, we could add check for broken __GNUC__. > > -Jussi > > > > > > > Shalom-Salam, > > > > Werner > > > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > > > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > From jussi.kivilinna at iki.fi Sat Sep 21 15:59:42 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 21 Sep 2013 16:59:42 +0300 Subject: [PATCH] Make libgcrypt build with Clang on i386 Message-ID: <20130921135942.29025.38120.stgit@localhost6.localdomain6> * cipher/longlong.h [__i386__] (add_ssaaaa, sub_ddmmss) (umul_ppmm, udiv_qrnnd): Do not cast asm output to USItype. -- Clang defines __GNUC__ even when it's not GCC compatible. As result Clang enables GCC-only assembly code in mpi/longlong.h and fails to build. However, since changes to make libgcrypt build with Clang are smallish, and changes do not cause problems with GCC, patch just does them. Signed-off-by: Jussi Kivilinna --- mpi/longlong.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mpi/longlong.h b/mpi/longlong.h index 773d1c7..4e315df 100644 --- a/mpi/longlong.h +++ b/mpi/longlong.h @@ -468,8 +468,8 @@ extern USItype __udiv_qrnnd (); #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addl %5,%1\n" \ "adcl %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -478,8 +478,8 @@ extern USItype __udiv_qrnnd (); #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subl %5,%1\n" \ "sbbl %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -487,15 +487,15 @@ extern USItype __udiv_qrnnd (); __CLOBBER_CC) #define umul_ppmm(w1, w0, u, v) \ __asm__ ("mull %3" \ - : "=a" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ + : "=a" ((w0)), \ + "=d" ((w1)) \ : "%0" ((USItype)(u)), \ "rm" ((USItype)(v)) \ __CLOBBER_CC) #define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divl %4" \ - : "=a" ((USItype)(q)), \ - "=d" ((USItype)(r)) \ + : "=a" ((q)), \ + "=d" ((r)) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "rm" ((USItype)(d)) \ From dbaryshkov at gmail.com Sat Sep 21 16:49:22 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Sat, 21 Sep 2013 18:49:22 +0400 Subject: [PATCH] Make libgcrypt build with Clang on i386 In-Reply-To: <20130921135942.29025.38120.stgit@localhost6.localdomain6> References: <20130921135942.29025.38120.stgit@localhost6.localdomain6> Message-ID: Hello, On Sat, Sep 21, 2013 at 5:59 PM, Jussi Kivilinna wrote: > * cipher/longlong.h [__i386__] (add_ssaaaa, sub_ddmmss) > (umul_ppmm, udiv_qrnnd): Do not cast asm output to USItype. I have nearly the same patch for PowerPC. Would it be accepted? -- With best wishes Dmitry From dbaryshkov at gmail.com Sat Sep 21 23:18:27 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Sun, 22 Sep 2013 01:18:27 +0400 Subject: [PATCH 1/2] Add an utility to calculate hashes over a set of files Message-ID: <1379798308-9307-1-git-send-email-dbaryshkov@gmail.com> * src/gchash.c: New. -- An utility like rhash that has the ability to calculate different hashes over a set of files it usefull. Add gchash utility to calculate hashes supported by libgcrypt. Signed-off-by: Dmitry Eremin-Solenikov --- src/Makefile.am | 6 ++- src/gchash.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/gchash.c diff --git a/src/Makefile.am b/src/Makefile.am index 3bc27c8..ebb42f7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,7 +29,7 @@ m4data_DATA = libgcrypt.m4 include_HEADERS = gcrypt.h lib_LTLIBRARIES = libgcrypt.la -bin_PROGRAMS = dumpsexp hmac256 mpicalc +bin_PROGRAMS = dumpsexp hmac256 mpicalc gchash if USE_RANDOM_DAEMON sbin_PROGRAMS = gcryptrnd bin_PROGRAMS += getrandom @@ -128,6 +128,10 @@ dumpsexp_SOURCES = dumpsexp.c dumpsexp_CFLAGS = $(arch_gpg_error_cflags) dumpsexp_LDADD = $(arch_gpg_error_libs) +gchash_SOURCES = gchash.c +gchash_CFLAGS = $(GPG_ERROR_CFLAGS) +gchash_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) + mpicalc_SOURCES = mpicalc.c mpicalc_CFLAGS = $(GPG_ERROR_CFLAGS) mpicalc_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) diff --git a/src/gchash.c b/src/gchash.c new file mode 100644 index 0000000..7a2aad6 --- /dev/null +++ b/src/gchash.c @@ -0,0 +1,120 @@ +/* gchash.c - Calculate hash values + * Copyright (C) 2013 Dmitry Eremin-Solenikov + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include + +#ifdef _GCRYPT_IN_LIBGCRYPT +# undef _GCRYPT_IN_LIBGCRYPT +# include "gcrypt.h" +#else +# include +#endif + + +void +init_gcrypt (void) +{ + if (!gcry_check_version (GCRYPT_VERSION)) { + fputs ("libgcrypt version mismatch\n", stderr); + exit (2); + } + + gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); + + /* Allocate a pool of 16k secure memory. This make the secure memory + * available and also drops privileges where needed. */ + gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + + gcry_control (GCRYCTL_RESUME_SECMEM_WARN); + + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); +} + +int +main (int argc, char **argv) +{ + gcry_md_hd_t hd; + gcry_error_t err; + int algo; + + init_gcrypt(); + + if (argc < 2 || (argv[1] && !strcmp(argv[1], "--help"))) + { + fprintf (stderr, "Usage: %s ...\n", argv[0]); + return 1; + } + + algo = gcry_md_map_name (argv[1]); + if (algo == GCRY_MD_NONE) + { + fprintf (stderr, "Unknown algorithm '%s'\n", argv[1]); + return 1; + } + + err = gcry_md_open(&hd, algo, 0); + if (err) + { + fprintf (stderr, "LibGCrypt error %s/%s\n", + gcry_strsource (err), + gcry_strerror (err)); + exit (1); + } + + for (argv += 2; *argv; argv++) + { + FILE *fp; + unsigned char buf[1024]; + size_t size; + int i; + unsigned char *h; + if (!strcmp (*argv, "-")) + fp = stdin; + else + fp = fopen (*argv, "r"); + + if (fp == NULL) + { + perror ("fopen"); + return 1; + } + + while (!feof (fp)) + { + size = fread (buf, 1, sizeof(buf), fp); + gcry_md_write (hd, buf, size); + } + + h = gcry_md_read(hd, 0); + + for (i = 0; i < gcry_md_get_algo_dlen (algo); i++) + printf("%02hhx", h[i]); + printf(" %s\n", *argv); + + gcry_md_reset(hd); + } + + gcry_md_close(hd); + return 0; +} -- 1.8.4.rc3 From dbaryshkov at gmail.com Sat Sep 21 23:18:28 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Sun, 22 Sep 2013 01:18:28 +0400 Subject: [PATCH 2/2] Drop _gcry_cipher_ofb_decrypt as it duplicates _gcry_cipher_ofb_encrypt In-Reply-To: <1379798308-9307-1-git-send-email-dbaryshkov@gmail.com> References: <1379798308-9307-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1379798308-9307-2-git-send-email-dbaryshkov@gmail.com> * cipher/cipher.c (cipher_decrypt): Use _gcry_cipher_ofb_encrypt for OFB decryption. * cipher/cipher-internal.h: Remove _gcry_cipher_ofb_decrypt declaration. * cipher/cipher.c: Delete _gcry_cipher_ofb_decrypt(). Signed-off-by: Dmitry Eremin-Solenikov --- cipher/cipher-internal.h | 4 --- cipher/cipher-ofb.c | 68 +----------------------------------------------- cipher/cipher.c | 2 +- 3 files changed, 2 insertions(+), 72 deletions(-) diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index 025bf2e..82a67fd 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -154,10 +154,6 @@ gcry_err_code_t _gcry_cipher_ofb_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, unsigned int outbuflen, const unsigned char *inbuf, unsigned int inbuflen); -gcry_err_code_t _gcry_cipher_ofb_decrypt -/* */ (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen); /*-- cipher-ctr.c --*/ gcry_err_code_t _gcry_cipher_ctr_encrypt diff --git a/cipher/cipher-ofb.c b/cipher/cipher-ofb.c index 3fb9b0d..48dd25f 100644 --- a/cipher/cipher-ofb.c +++ b/cipher/cipher-ofb.c @@ -47,7 +47,7 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, { /* Short enough to be encoded by the remaining XOR mask. */ /* XOR the input with the IV */ - ivp = c->u_iv.iv + c->cipher->blocksize - c->unused; + ivp = c->u_iv.iv + blocksize - c->unused; buf_xor(outbuf, ivp, inbuf, inbuflen); c->unused -= inbuflen; return 0; @@ -95,69 +95,3 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, return 0; } - - -gcry_err_code_t -_gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) -{ - unsigned char *ivp; - size_t blocksize = c->cipher->blocksize; - unsigned int burn, nburn; - - if (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - - if( inbuflen <= c->unused ) - { - /* Short enough to be encoded by the remaining XOR mask. */ - ivp = c->u_iv.iv + blocksize - c->unused; - buf_xor(outbuf, ivp, inbuf, inbuflen); - c->unused -= inbuflen; - return 0; - } - - burn = 0; - - if ( c->unused ) - { - inbuflen -= c->unused; - ivp = c->u_iv.iv + blocksize - c->unused; - buf_xor(outbuf, ivp, inbuf, c->unused); - outbuf += c->unused; - inbuf += c->unused; - c->unused = 0; - } - - /* Now we can process complete blocks. */ - while ( inbuflen >= blocksize ) - { - /* Encrypt the IV (and save the current one). */ - memcpy( c->lastiv, c->u_iv.iv, blocksize ); - nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; - buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize); - outbuf += blocksize; - inbuf += blocksize; - inbuflen -= blocksize; - } - if ( inbuflen ) - { /* Process the remaining bytes. */ - /* Encrypt the IV (and save the current one). */ - memcpy( c->lastiv, c->u_iv.iv, blocksize ); - nburn = c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; - c->unused = blocksize; - c->unused -= inbuflen; - buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen); - outbuf += inbuflen; - inbuf += inbuflen; - inbuflen = 0; - } - - if (burn > 0) - _gcry_burn_stack (burn + 4 * sizeof(void *)); - - return 0; -} diff --git a/cipher/cipher.c b/cipher/cipher.c index a17ca9b..2e775fb 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -1085,7 +1085,7 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, break; case GCRY_CIPHER_MODE_OFB: - rc = _gcry_cipher_ofb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); + rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); break; case GCRY_CIPHER_MODE_CTR: -- 1.8.4.rc3 From wk at gnupg.org Sun Sep 22 10:13:39 2013 From: wk at gnupg.org (Werner Koch) Date: Sun, 22 Sep 2013 10:13:39 +0200 Subject: [PATCH] Make libgcrypt build with Clang on i386 In-Reply-To: (Dmitry Eremin-Solenikov's message of "Sat, 21 Sep 2013 18:49:22 +0400") References: <20130921135942.29025.38120.stgit@localhost6.localdomain6> Message-ID: <87txhdnuj0.fsf@vigenere.g10code.de> On Sat, 21 Sep 2013 16:49, dbaryshkov at gmail.com said: > I have nearly the same patch for PowerPC. Would it be accepted? Both are fine. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Sun Sep 22 11:24:28 2013 From: wk at gnupg.org (Werner Koch) Date: Sun, 22 Sep 2013 11:24:28 +0200 Subject: --disable-asm flag not being fully honored In-Reply-To: (Chris Ballinger's message of "Fri, 20 Sep 2013 12:07:43 -0700") References: <87siwzrhd4.fsf@vigenere.g10code.de> <523C18F2.7080909@iki.fi> <874n9fr9nz.fsf@vigenere.g10code.de> <523C5A33.3060701@iki.fi> Message-ID: <87pps1nr8z.fsf@vigenere.g10code.de> On Fri, 20 Sep 2013 21:07, chris at chatsecure.org said: > Also, the --disable-asm flag I think should be renamed to --disable-mpi-asm > if that's all it does and a new option called --disable-asm actually > disable all use of assembler. Or at the very least mention in the docs that The problem with such an approach is that we won't get reports if the assembler code is broken. The MPI code is way more complex and in particular the CPU detection sometimes fails; thus we have this --disable-asm option. Even with --disable-asm too many folks simply use that and don't report problems. As timer permits, it is better to fix the actual problem - as long as it does not make the code more complex. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From andre at amorim.me Sun Sep 22 10:38:27 2013 From: andre at amorim.me (Andre Amorim) Date: Sun, 22 Sep 2013 09:38:27 +0100 Subject: [PATCH] Make libgcrypt build with Clang on i386 In-Reply-To: <87txhdnuj0.fsf@vigenere.g10code.de> References: <20130921135942.29025.38120.stgit@localhost6.localdomain6> <87txhdnuj0.fsf@vigenere.g10code.de> Message-ID: is it about abstract class ? On 22 September 2013 09:13, Werner Koch wrote: > On Sat, 21 Sep 2013 16:49, dbaryshkov at gmail.com said: > > > I have nearly the same patch for PowerPC. Would it be accepted? > > Both are fine. > > > Salam-Shalom, > > Werner > > > -- > Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > -- Gnupg key: 02375205 Fingerprint: F7CD D181 943B 0453 8668 AF16 84E9 7565 0237 5205 -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbaryshkov at gmail.com Thu Sep 19 23:14:12 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 20 Sep 2013 01:14:12 +0400 Subject: [PATCH] Fix errors when building with Clang on PPC Message-ID: <1379625252-17756-1-git-send-email-dbaryshkov@gmail.com> * mpi/longlong.h (add_ssaaaa, sub_ddmmss, count_leading_zeros, umul_ppmm): Do not cast asm output to USItype. Signed-off-by: Dmitry Eremin-Solenikov --- mpi/longlong.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/mpi/longlong.h b/mpi/longlong.h index 773d1c7..7b51564 100644 --- a/mpi/longlong.h +++ b/mpi/longlong.h @@ -862,22 +862,22 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); do { \ if (__builtin_constant_p (bh) && (bh) == 0) \ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "%r" ((USItype)(ah)), \ "%r" ((USItype)(al)), \ "rI" ((USItype)(bl))); \ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "%r" ((USItype)(ah)), \ "%r" ((USItype)(al)), \ "rI" ((USItype)(bl))); \ else \ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "%r" ((USItype)(ah)), \ "r" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ @@ -887,36 +887,36 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); do { \ if (__builtin_constant_p (ah) && (ah) == 0) \ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "r" ((USItype)(bh)), \ "rI" ((USItype)(al)), \ "r" ((USItype)(bl))); \ else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "r" ((USItype)(bh)), \ "rI" ((USItype)(al)), \ "r" ((USItype)(bl))); \ else if (__builtin_constant_p (bh) && (bh) == 0) \ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "r" ((USItype)(ah)), \ "rI" ((USItype)(al)), \ "r" ((USItype)(bl))); \ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "r" ((USItype)(ah)), \ "rI" ((USItype)(al)), \ "r" ((USItype)(bl))); \ else \ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "r" ((USItype)(ah)), \ "r" ((USItype)(bh)), \ "rI" ((USItype)(al)), \ @@ -924,7 +924,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); } while (0) #define count_leading_zeros(count, x) \ __asm__ ("{cntlz|cntlzw} %0,%1" \ - : "=r" ((USItype)(count)) \ + : "=r" ((count)) \ : "r" ((USItype)(x))) #define COUNT_LEADING_ZEROS_0 32 #if defined (_ARCH_PPC) @@ -932,7 +932,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("mulhwu %0,%1,%2" \ - : "=r" ((USItype) ph) \ + : "=r" (ph) \ : "%r" (__m0), \ "r" (__m1)); \ (pl) = __m0 * __m1; \ @@ -954,8 +954,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("mul %0,%2,%3" \ - : "=r" ((USItype)(xh)), \ - "=q" ((USItype)(xl)) \ + : "=r" ((xh)), \ + "=q" ((xl)) \ : "r" (__m0), \ "r" (__m1)); \ (xh) += ((((SItype) __m0 >> 31) & __m1) \ -- 1.8.4.rc3 From dbaryshkov at gmail.com Sun Sep 22 22:02:31 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 23 Sep 2013 00:02:31 +0400 Subject: [PATCH 2/2] Update .gitingore to ignore more files In-Reply-To: <1379880151-5636-1-git-send-email-dbaryshkov@gmail.com> References: <1379880151-5636-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1379880151-5636-2-git-send-email-dbaryshkov@gmail.com> * .gitignore: add more tests, temporary files, etc to the list of ignored files. Signed-off-by: Dmitry Eremin-Solenikov --- .gitignore | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.gitignore b/.gitignore index 9a2105a..3a94fbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,18 @@ *.lo *.o +*.orig +*.patch +*.swp .deps/ .libs/ +gmon.out po/*.gmo po/messages.mo /aclocal.m4 /autom4te.cache /compile /config.guess +/config.h.in~ /config.h.in /config.h /config.log @@ -35,7 +40,16 @@ cipher/Makefile cipher/libcipher.la compat/Makefile compat/libcompat.la +doc/gcrypt.?? +doc/gcrypt.aux +doc/gcrypt.cps +doc/gcrypt.dvi +doc/gcrypt.fns +doc/gcrypt.html/ doc/gcrypt.info +doc/gcrypt.log +doc/gcrypt.pdf +doc/gcrypt.toc doc/mdate-sh doc/texinfo.tex doc/stamp-vti @@ -44,9 +58,12 @@ doc/Makefile doc/fips-fsm.eps doc/fips-fsm.pdf doc/fips-fsm.png +doc/hmac256.1 doc/libgcrypt-modules.eps doc/libgcrypt-modules.pdf doc/libgcrypt-modules.png +doc/yat2m +doc/yat2m-stamp mpi/Makefile mpi/asm-syntax.h mpi/libmpi.la @@ -68,7 +85,10 @@ src/gcrypt.h src/hmac256 src/libgcrypt-config src/libgcrypt.la +src/mpicalc src/versioninfo.rc +tags +TAGS test-driver tests/Makefile tests/ac @@ -77,17 +97,26 @@ tests/ac-schemes tests/aeswrap tests/basic tests/benchmark +tests/curves +tests/dsa-rfc6979 tests/fips186-dsa tests/fipsdrv tests/hmac tests/keygen tests/keygrip tests/mpitests +tests/pkcs1v2 tests/prime tests/pubkey tests/random tests/register tests/rsacvt +tests/t-convert +tests/t-ed25519 +tests/t-kdf tests/t-mpi-bit +tests/t-mpi-point tests/tsexp tests/version +tests/*.log +tests/*.trs -- 1.8.4.rc3 From wk at gnupg.org Mon Sep 23 08:05:12 2013 From: wk at gnupg.org (Werner Koch) Date: Mon, 23 Sep 2013 08:05:12 +0200 Subject: [PATCH 2/2] Update .gitingore to ignore more files In-Reply-To: <1379880151-5636-2-git-send-email-dbaryshkov@gmail.com> (Dmitry Eremin-Solenikov's message of "Mon, 23 Sep 2013 00:02:31 +0400") References: <1379880151-5636-1-git-send-email-dbaryshkov@gmail.com> <1379880151-5636-2-git-send-email-dbaryshkov@gmail.com> Message-ID: <87siwwm5t3.fsf@vigenere.g10code.de> On Sun, 22 Sep 2013 22:02, dbaryshkov at gmail.com said: > +*.orig > +*.patch > +*.swp I want to know if such files show up in my source dirs. > .deps/ > .libs/ I highly suggest to do out-of-tree builds. This make life much easier. > +/config.h.in~ For example I have this in my ~/.gitignore /GPATH /GRTAGS /GSYMS /GTAGS *~ .#* \#*# x y out err po/*.gmo po/messages.mo a.out Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Sun Sep 22 22:02:30 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 23 Sep 2013 00:02:30 +0400 Subject: [PATCH 1/2] Drop automake-installed files Message-ID: <1379880151-5636-1-git-send-email-dbaryshkov@gmail.com> * compile, config.guess, config.sub, depcomp, doc/mdate.sh, doc/texinfo.tex, install-sh, missing, mkinstalldirs: Drop files. * .gitignore: Ignore freshly removed files. * autogen.sh: call automake with --add-missing argument to install missing files. -- Automake 1.13 and 1.14 add another script - test-driver. Moreover they are not fully compatible with provided missing script. So drop files that can be installed by automake. They are better to be in sync with automake used. Signed-off-by: Dmitry Eremin-Solenikov --- .gitignore | 10 + autogen.sh | 4 +- compile | 142 -- config.guess | 1534 ------------ config.sub | 1786 ------------- depcomp | 584 ----- doc/mdate-sh | 201 -- doc/texinfo.tex | 7482 ------------------------------------------------------- install-sh | 520 ---- missing | 360 --- mkinstalldirs | 161 -- 11 files changed, 12 insertions(+), 12772 deletions(-) delete mode 100755 compile delete mode 100755 config.guess delete mode 100755 config.sub delete mode 100755 depcomp delete mode 100755 doc/mdate-sh delete mode 100644 doc/texinfo.tex delete mode 100755 install-sh delete mode 100755 missing delete mode 100755 mkinstalldirs diff --git a/.gitignore b/.gitignore index ec7f8bb..9a2105a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,11 +6,18 @@ po/*.gmo po/messages.mo /aclocal.m4 /autom4te.cache +/compile +/config.guess /config.h.in /config.h /config.log /config.status +/config.sub /configure +/depcomp +/install-sh +/missing +/mkinstalldirs /libtool /stamp-h1 /Makefile.in @@ -29,6 +36,8 @@ cipher/libcipher.la compat/Makefile compat/libcompat.la doc/gcrypt.info +doc/mdate-sh +doc/texinfo.tex doc/stamp-vti doc/version.texi doc/Makefile @@ -60,6 +69,7 @@ src/hmac256 src/libgcrypt-config src/libgcrypt.la src/versioninfo.rc +test-driver tests/Makefile tests/ac tests/ac-data diff --git a/autogen.sh b/autogen.sh index 841c2c2..df7953b 100755 --- a/autogen.sh +++ b/autogen.sh @@ -269,8 +269,8 @@ echo "Running aclocal -I m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..." $ACLOCAL -I m4 $ACLOCAL_FLAGS echo "Running autoheader..." $AUTOHEADER -echo "Running automake --gnu ..." -$AUTOMAKE --gnu; +echo "Running automake --gnu --add-missing ..." +$AUTOMAKE --gnu --add-missing; echo "Running autoconf${FORCE} ..." $AUTOCONF${FORCE} diff --git a/compile b/compile deleted file mode 100755 index 1b1d232..0000000 --- a/compile +++ /dev/null @@ -1,142 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand `-c -o'. - -scriptversion=2005-05-14.22 - -# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. -# Written by Tom Tromey . -# -# 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; either version 2, or (at your option) -# any later version. -# -# 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; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand `-c -o'. -Remove `-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file `INSTALL'. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "compile $scriptversion" - exit $? - ;; -esac - -ofile= -cfile= -eat= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we strip `-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also - # ok. - exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` - -# Create the lock directory. -# Note: use `[/.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d -while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then - mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/config.guess b/config.guess deleted file mode 100755 index ad5f74a..0000000 --- a/config.guess +++ /dev/null @@ -1,1534 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. - -timestamp='2012-07-31' - -# This file 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; either version 2 of the License, or -# (at your option) any later version. -# -# 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; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi at noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf at swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green at stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green at stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/config.sub b/config.sub deleted file mode 100755 index b15df57..0000000 --- a/config.sub +++ /dev/null @@ -1,1786 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. - -timestamp='2012-07-31' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file 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; either version 2 of the License, or -# (at your option) any later version. -# -# 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; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 \ - | ns16k | ns32k \ - | open8 \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i386-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/depcomp b/depcomp deleted file mode 100755 index ca5ea4e..0000000 --- a/depcomp +++ /dev/null @@ -1,584 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2006-10-15.18 - -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software -# Foundation, Inc. - -# 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; either version 2, or (at your option) -# any later version. - -# 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; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> $depfile - echo >> $depfile - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> $depfile - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` - tmpdepfile="$stripped.u" - if test "$libtool" = yes; then - "$@" -Wc,-M - else - "$@" -M - fi - stat=$? - - if test -f "$tmpdepfile"; then : - else - stripped=`echo "$stripped" | sed 's,^.*/,,'` - tmpdepfile="$stripped.u" - fi - - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - - if test -f "$tmpdepfile"; then - outname="$stripped.o" - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" - sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. - sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. - "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no - for arg in "$@"; do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix="`echo $object | sed 's/^.*\././'`" - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o, - # because we must use -o when running libtool. - "$@" || exit $? - IFS=" " - for arg - do - case "$arg" in - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/doc/mdate-sh b/doc/mdate-sh deleted file mode 100755 index cd916c0..0000000 --- a/doc/mdate-sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/bin/sh -# Get modification time of a file or directory and pretty-print it. - -scriptversion=2005-06-29.22 - -# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software -# Foundation, Inc. -# written by Ulrich Drepper , June 1995 -# -# 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; either version 2, or (at your option) -# any later version. -# -# 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; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -case $1 in - '') - echo "$0: No file. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: mdate-sh [--help] [--version] FILE - -Pretty-print the modification time of FILE. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "mdate-sh $scriptversion" - exit $? - ;; -esac - -# Prevent date giving response in another language. -LANG=C -export LANG -LC_ALL=C -export LC_ALL -LC_TIME=C -export LC_TIME - -# GNU ls changes its time format in response to the TIME_STYLE -# variable. Since we cannot assume `unset' works, revert this -# variable to its documented default. -if test "${TIME_STYLE+set}" = set; then - TIME_STYLE=posix-long-iso - export TIME_STYLE -fi - -save_arg1=$1 - -# Find out how to get the extended ls output of a file or directory. -if ls -L /dev/null 1>/dev/null 2>&1; then - ls_command='ls -L -l -d' -else - ls_command='ls -l -d' -fi - -# A `ls -l' line looks as follows on OS/2. -# drwxrwx--- 0 Aug 11 2001 foo -# This differs from Unix, which adds ownership information. -# drwxrwx--- 2 root root 4096 Aug 11 2001 foo -# -# To find the date, we split the line on spaces and iterate on words -# until we find a month. This cannot work with files whose owner is a -# user named `Jan', or `Feb', etc. However, it's unlikely that `/' -# will be owned by a user whose name is a month. So we first look at -# the extended ls output of the root directory to decide how many -# words should be skipped to get the date. - -# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. -set x`ls -l -d /` - -# Find which argument is the month. -month= -command= -until test $month -do - shift - # Add another shift to the command. - command="$command shift;" - case $1 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; - esac -done - -# Get the extended ls output of the file or directory. -set dummy x`eval "$ls_command \"\$save_arg1\""` - -# Remove all preceding arguments -eval $command - -# Because of the dummy argument above, month is in $2. -# -# On a POSIX system, we should have -# -# $# = 5 -# $1 = file size -# $2 = month -# $3 = day -# $4 = year or time -# $5 = filename -# -# On Darwin 7.7.0 and 7.6.0, we have -# -# $# = 4 -# $1 = day -# $2 = month -# $3 = year or time -# $4 = filename - -# Get the month. -case $2 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; -esac - -case $3 in - ???*) day=$1;; - *) day=$3; shift;; -esac - -# Here we have to deal with the problem that the ls output gives either -# the time of day or the year. -case $3 in - *:*) set `date`; eval year=\$$# - case $2 in - Jan) nummonthtod=1;; - Feb) nummonthtod=2;; - Mar) nummonthtod=3;; - Apr) nummonthtod=4;; - May) nummonthtod=5;; - Jun) nummonthtod=6;; - Jul) nummonthtod=7;; - Aug) nummonthtod=8;; - Sep) nummonthtod=9;; - Oct) nummonthtod=10;; - Nov) nummonthtod=11;; - Dec) nummonthtod=12;; - esac - # For the first six month of the year the time notation can also - # be used for files modified in the last year. - if (expr $nummonth \> $nummonthtod) > /dev/null; - then - year=`expr $year - 1` - fi;; - *) year=$3;; -esac - -# The result. -echo $day $month $year - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/doc/texinfo.tex b/doc/texinfo.tex deleted file mode 100644 index 8083622..0000000 --- a/doc/texinfo.tex +++ /dev/null @@ -1,7482 +0,0 @@ -% texinfo.tex -- TeX macros to handle Texinfo files. -% -% Load plain if necessary, i.e., if running under initex. -\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi -% -\def\texinfoversion{2006-10-04.17} -% -% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, -% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free -% Software Foundation, Inc. -% -% This texinfo.tex file 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; either version 2, or (at -% your option) any later version. -% -% This texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write -% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -% Boston, MA 02110-1301, USA. -% -% As a special exception, when this file is read by TeX when processing -% a Texinfo source document, you may use the result without -% restriction. (This has been our intent since Texinfo was invented.) -% -% Please try the latest version of texinfo.tex before submitting bug -% reports; you can get the latest version from: -% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or -% ftp://tug.org/tex/texinfo.tex -% (and all CTAN mirrors, see http://www.ctan.org). -% The texinfo.tex in any given distribution could well be out -% of date, so if that's what you're using, please check. -% -% Send bug reports to bug-texinfo at gnu.org. Please include including a -% complete document in each bug report with which we can reproduce the -% problem. Patches are, of course, greatly appreciated. -% -% To process a Texinfo manual with TeX, it's most reliable to use the -% texi2dvi shell script that comes with the distribution. For a simple -% manual foo.texi, however, you can get away with this: -% tex foo.texi -% texindex foo.?? -% tex foo.texi -% tex foo.texi -% dvips foo.dvi -o # or whatever; this makes foo.ps. -% The extra TeX runs get the cross-reference information correct. -% Sometimes one run after texindex suffices, and sometimes you need more -% than two; texi2dvi does it as many times as necessary. -% -% It is possible to adapt texinfo.tex for other languages, to some -% extent. You can get the existing language-specific files from the -% full Texinfo distribution. -% -% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. - - -\message{Loading texinfo [version \texinfoversion]:} - -% If in a .fmt file, print the version number -% and turn on active characters that we couldn't do earlier because -% they might have appeared in the input file name. -\everyjob{\message{[Texinfo version \texinfoversion]}% - \catcode`+=\active \catcode`\_=\active} - -\message{Basics,} -\chardef\other=12 - -% We never want plain's \outer definition of \+ in Texinfo. -% For @tex, we can use \tabalign. -\let\+ = \relax - -% Save some plain tex macros whose names we will redefine. -\let\ptexb=\b -\let\ptexbullet=\bullet -\let\ptexc=\c -\let\ptexcomma=\, -\let\ptexdot=\. -\let\ptexdots=\dots -\let\ptexend=\end -\let\ptexequiv=\equiv -\let\ptexexclam=\! -\let\ptexfootnote=\footnote -\let\ptexgtr=> -\let\ptexhat=^ -\let\ptexi=\i -\let\ptexindent=\indent -\let\ptexinsert=\insert -\let\ptexlbrace=\{ -\let\ptexless=< -\let\ptexnewwrite\newwrite -\let\ptexnoindent=\noindent -\let\ptexplus=+ -\let\ptexrbrace=\} -\let\ptexslash=\/ -\let\ptexstar=\* -\let\ptext=\t - -% If this character appears in an error message or help string, it -% starts a new line in the output. -\newlinechar = `^^J - -% Use TeX 3.0's \inputlineno to get the line number, for better error -% messages, but if we're using an old version of TeX, don't do anything. -% -\ifx\inputlineno\thisisundefined - \let\linenumber = \empty % Pre-3.0. -\else - \def\linenumber{l.\the\inputlineno:\space} -\fi - -% Set up fixed words for English if not already set. -\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi -\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi -\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi -\ifx\putwordin\undefined \gdef\putwordin{in}\fi -\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi -\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi -\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi -\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi -\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi -\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi -\ifx\putwordof\undefined \gdef\putwordof{of}\fi -\ifx\putwordon\undefined \gdef\putwordon{on}\fi -\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi -\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi -\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi -\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi -\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi -\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi -\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi -% -\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi -\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi -\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi -\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi -\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi -\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi -\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi -\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi -\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi -\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi -\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi -\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi -% -\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi -\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi -\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi -\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi -\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi - -% Since the category of space is not known, we have to be careful. -\chardef\spacecat = 10 -\def\spaceisspace{\catcode`\ =\spacecat} - -% sometimes characters are active, so we need control sequences. -\chardef\colonChar = `\: -\chardef\commaChar = `\, -\chardef\dashChar = `\- -\chardef\dotChar = `\. -\chardef\exclamChar= `\! -\chardef\lquoteChar= `\` -\chardef\questChar = `\? -\chardef\rquoteChar= `\' -\chardef\semiChar = `\; -\chardef\underChar = `\_ - -% Ignore a token. -% -\def\gobble#1{} - -% The following is used inside several \edef's. -\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} - -% Hyphenation fixes. -\hyphenation{ - Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script - ap-pen-dix bit-map bit-maps - data-base data-bases eshell fall-ing half-way long-est man-u-script - man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm - par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces - spell-ing spell-ings - stand-alone strong-est time-stamp time-stamps which-ever white-space - wide-spread wrap-around -} - -% Margin to add to right of even pages, to left of odd pages. -\newdimen\bindingoffset -\newdimen\normaloffset -\newdimen\pagewidth \newdimen\pageheight - -% For a final copy, take out the rectangles -% that mark overfull boxes (in case you have decided -% that the text looks ok even though it passes the margin). -% -\def\finalout{\overfullrule=0pt} - -% @| inserts a changebar to the left of the current line. It should -% surround any changed text. This approach does *not* work if the -% change spans more than two lines of output. To handle that, we would -% have adopt a much more difficult approach (putting marks into the main -% vertical list for the beginning and end of each change). -% -\def\|{% - % \vadjust can only be used in horizontal mode. - \leavevmode - % - % Append this vertical mode material after the current line in the output. - \vadjust{% - % We want to insert a rule with the height and depth of the current - % leading; that is exactly what \strutbox is supposed to record. - \vskip-\baselineskip - % - % \vadjust-items are inserted at the left edge of the type. So - % the \llap here moves out into the left-hand margin. - \llap{% - % - % For a thicker or thinner bar, change the `1pt'. - \vrule height\baselineskip width1pt - % - % This is the space between the bar and the text. - \hskip 12pt - }% - }% -} - -% Sometimes it is convenient to have everything in the transcript file -% and nothing on the terminal. We don't just call \tracingall here, -% since that produces some useless output on the terminal. We also make -% some effort to order the tracing commands to reduce output in the log -% file; cf. trace.sty in LaTeX. -% -\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% -\def\loggingall{% - \tracingstats2 - \tracingpages1 - \tracinglostchars2 % 2 gives us more in etex - \tracingparagraphs1 - \tracingoutput1 - \tracingmacros2 - \tracingrestores1 - \showboxbreadth\maxdimen \showboxdepth\maxdimen - \ifx\eTeXversion\undefined\else % etex gives us more logging - \tracingscantokens1 - \tracingifs1 - \tracinggroups1 - \tracingnesting2 - \tracingassigns1 - \fi - \tracingcommands3 % 3 gives us more in etex - \errorcontextlines16 -}% - -% add check for \lastpenalty to plain's definitions. If the last thing -% we did was a \nobreak, we don't want to insert more space. -% -\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount - \removelastskip\penalty-50\smallskip\fi\fi} -\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount - \removelastskip\penalty-100\medskip\fi\fi} -\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount - \removelastskip\penalty-200\bigskip\fi\fi} - -% For @cropmarks command. -% Do @cropmarks to get crop marks. -% -\newif\ifcropmarks -\let\cropmarks = \cropmarkstrue -% -% Dimensions to add cropmarks at corners. -% Added by P. A. MacKay, 12 Nov. 1986 -% -\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines -\newdimen\cornerlong \cornerlong=1pc -\newdimen\cornerthick \cornerthick=.3pt -\newdimen\topandbottommargin \topandbottommargin=.75in - -% Main output routine. -\chardef\PAGE = 255 -\output = {\onepageout{\pagecontents\PAGE}} - -\newbox\headlinebox -\newbox\footlinebox - -% \onepageout takes a vbox as an argument. Note that \pagecontents -% does insertions, but you have to call it yourself. -\def\onepageout#1{% - \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi - % - \ifodd\pageno \advance\hoffset by \bindingoffset - \else \advance\hoffset by -\bindingoffset\fi - % - % Do this outside of the \shipout so @code etc. will be expanded in - % the headline as they should be, not taken literally (outputting ''code). - \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% - \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% - % - {% - % Have to do this stuff outside the \shipout because we want it to - % take effect in \write's, yet the group defined by the \vbox ends - % before the \shipout runs. - % - \indexdummies % don't expand commands in the output. - \normalturnoffactive % \ in index entries must not stay \, e.g., if - % the page break happens to be in the middle of an example. - % We don't want .vr (or whatever) entries like this: - % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} - % "\acronym" won't work when it's read back in; - % it needs to be - % {\code {{\tt \backslashcurfont }acronym} - \shipout\vbox{% - % Do this early so pdf references go to the beginning of the page. - \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi - % - \ifcropmarks \vbox to \outervsize\bgroup - \hsize = \outerhsize - \vskip-\topandbottommargin - \vtop to0pt{% - \line{\ewtop\hfil\ewtop}% - \nointerlineskip - \line{% - \vbox{\moveleft\cornerthick\nstop}% - \hfill - \vbox{\moveright\cornerthick\nstop}% - }% - \vss}% - \vskip\topandbottommargin - \line\bgroup - \hfil % center the page within the outer (page) hsize. - \ifodd\pageno\hskip\bindingoffset\fi - \vbox\bgroup - \fi - % - \unvbox\headlinebox - \pagebody{#1}% - \ifdim\ht\footlinebox > 0pt - % Only leave this space if the footline is nonempty. - % (We lessened \vsize for it in \oddfootingyyy.) - % The \baselineskip=24pt in plain's \makefootline has no effect. - \vskip 24pt - \unvbox\footlinebox - \fi - % - \ifcropmarks - \egroup % end of \vbox\bgroup - \hfil\egroup % end of (centering) \line\bgroup - \vskip\topandbottommargin plus1fill minus1fill - \boxmaxdepth = \cornerthick - \vbox to0pt{\vss - \line{% - \vbox{\moveleft\cornerthick\nsbot}% - \hfill - \vbox{\moveright\cornerthick\nsbot}% - }% - \nointerlineskip - \line{\ewbot\hfil\ewbot}% - }% - \egroup % \vbox from first cropmarks clause - \fi - }% end of \shipout\vbox - }% end of group with \indexdummies - \advancepageno - \ifnum\outputpenalty>-20000 \else\dosupereject\fi -} - -\newinsert\margin \dimen\margin=\maxdimen - -\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} -{\catcode`\@ =11 -\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi -% marginal hacks, juha at viisa.uucp (Juha Takala) -\ifvoid\margin\else % marginal info is present - \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi -\dimen@=\dp#1 \unvbox#1 -\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi -\ifr at ggedbottom \kern-\dimen@ \vfil \fi} -} - -% Here are the rules for the cropmarks. Note that they are -% offset so that the space between them is truly \outerhsize or \outervsize -% (P. A. MacKay, 12 November, 1986) -% -\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} -\def\nstop{\vbox - {\hrule height\cornerthick depth\cornerlong width\cornerthick}} -\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} -\def\nsbot{\vbox - {\hrule height\cornerlong depth\cornerthick width\cornerthick}} - -% Parse an argument, then pass it to #1. The argument is the rest of -% the input line (except we remove a trailing comment). #1 should be a -% macro which expects an ordinary undelimited TeX argument. -% -\def\parsearg{\parseargusing{}} -\def\parseargusing#1#2{% - \def\argtorun{#2}% - \begingroup - \obeylines - \spaceisspace - #1% - \parseargline\empty% Insert the \empty token, see \finishparsearg below. -} - -{\obeylines % - \gdef\parseargline#1^^M{% - \endgroup % End of the group started in \parsearg. - \argremovecomment #1\comment\ArgTerm% - }% -} - -% First remove any @comment, then any @c comment. -\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} -\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} - -% Each occurence of `\^^M' or `\^^M' is replaced by a single space. -% -% \argremovec might leave us with trailing space, e.g., -% @end itemize @c foo -% This space token undergoes the same procedure and is eventually removed -% by \finishparsearg. -% -\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} -\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} -\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% - \def\temp{#3}% - \ifx\temp\empty - % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: - \let\temp\finishparsearg - \else - \let\temp\argcheckspaces - \fi - % Put the space token in: - \temp#1 #3\ArgTerm -} - -% If a _delimited_ argument is enclosed in braces, they get stripped; so -% to get _exactly_ the rest of the line, we had to prevent such situation. -% We prepended an \empty token at the very beginning and we expand it now, -% just before passing the control to \argtorun. -% (Similarily, we have to think about #3 of \argcheckspacesY above: it is -% either the null string, or it ends with \^^M---thus there is no danger -% that a pair of braces would be stripped. -% -% But first, we have to remove the trailing space token. -% -\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} - -% \parseargdef\foo{...} -% is roughly equivalent to -% \def\foo{\parsearg\Xfoo} -% \def\Xfoo#1{...} -% -% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my -% favourite TeX trick. --kasal, 16nov03 - -\def\parseargdef#1{% - \expandafter \doparseargdef \csname\string#1\endcsname #1% -} -\def\doparseargdef#1#2{% - \def#2{\parsearg#1}% - \def#1##1% -} - -% Several utility definitions with active space: -{ - \obeyspaces - \gdef\obeyedspace{ } - - % Make each space character in the input produce a normal interword - % space in the output. Don't allow a line break at this space, as this - % is used only in environments like @example, where each line of input - % should produce a line of output anyway. - % - \gdef\sepspaces{\obeyspaces\let =\tie} - - % If an index command is used in an @example environment, any spaces - % therein should become regular spaces in the raw index file, not the - % expansion of \tie (\leavevmode \penalty \@M \ ). - \gdef\unsepspaces{\let =\space} -} - - -\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} - -% Define the framework for environments in texinfo.tex. It's used like this: -% -% \envdef\foo{...} -% \def\Efoo{...} -% -% It's the responsibility of \envdef to insert \begingroup before the -% actual body; @end closes the group after calling \Efoo. \envdef also -% defines \thisenv, so the current environment is known; @end checks -% whether the environment name matches. The \checkenv macro can also be -% used to check whether the current environment is the one expected. -% -% Non-false conditionals (@iftex, @ifset) don't fit into this, so they -% are not treated as enviroments; they don't open a group. (The -% implementation of @end takes care not to call \endgroup in this -% special case.) - - -% At runtime, environments start with this: -\def\startenvironment#1{\begingroup\def\thisenv{#1}} -% initialize -\let\thisenv\empty - -% ... but they get defined via ``\envdef\foo{...}'': -\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} -\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} - -% Check whether we're in the right environment: -\def\checkenv#1{% - \def\temp{#1}% - \ifx\thisenv\temp - \else - \badenverr - \fi -} - -% Evironment mismatch, #1 expected: -\def\badenverr{% - \errhelp = \EMsimple - \errmessage{This command can appear only \inenvironment\temp, - not \inenvironment\thisenv}% -} -\def\inenvironment#1{% - \ifx#1\empty - out of any environment% - \else - in environment \expandafter\string#1% - \fi -} - -% @end foo executes the definition of \Efoo. -% But first, it executes a specialized version of \checkenv -% -\parseargdef\end{% - \if 1\csname iscond.#1\endcsname - \else - % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03 - \expandafter\checkenv\csname#1\endcsname - \csname E#1\endcsname - \endgroup - \fi -} - -\newhelp\EMsimple{Press RETURN to continue.} - - -%% Simple single-character @ commands - -% @@ prints an @ -% Kludge this until the fonts are right (grr). -\def\@{{\tt\char64}} - -% This is turned off because it was never documented -% and you can use @w{...} around a quote to suppress ligatures. -%% Define @` and @' to be the same as ` and ' -%% but suppressing ligatures. -%\def\`{{`}} -%\def\'{{'}} - -% Used to generate quoted braces. -\def\mylbrace {{\tt\char123}} -\def\myrbrace {{\tt\char125}} -\let\{=\mylbrace -\let\}=\myrbrace -\begingroup - % Definitions to produce \{ and \} commands for indices, - % and @{ and @} for the aux/toc files. - \catcode`\{ = \other \catcode`\} = \other - \catcode`\[ = 1 \catcode`\] = 2 - \catcode`\! = 0 \catcode`\\ = \other - !gdef!lbracecmd[\{]% - !gdef!rbracecmd[\}]% - !gdef!lbraceatcmd[@{]% - !gdef!rbraceatcmd[@}]% -!endgroup - -% @comma{} to avoid , parsing problems. -\let\comma = , - -% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent -% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. -\let\, = \c -\let\dotaccent = \. -\def\ringaccent#1{{\accent23 #1}} -\let\tieaccent = \t -\let\ubaraccent = \b -\let\udotaccent = \d - -% Other special characters: @questiondown @exclamdown @ordf @ordm -% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. -\def\questiondown{?`} -\def\exclamdown{!`} -\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} -\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} - -% Dotless i and dotless j, used for accents. -\def\imacro{i} -\def\jmacro{j} -\def\dotless#1{% - \def\temp{#1}% - \ifx\temp\imacro \ptexi - \else\ifx\temp\jmacro \j - \else \errmessage{@dotless can be used only with i or j}% - \fi\fi -} - -% The \TeX{} logo, as in plain, but resetting the spacing so that a -% period following counts as ending a sentence. (Idea found in latex.) -% -\edef\TeX{\TeX \spacefactor=1000 } - -% @LaTeX{} logo. Not quite the same results as the definition in -% latex.ltx, since we use a different font for the raised A; it's most -% convenient for us to use an explicitly smaller font, rather than using -% the \scriptstyle font (since we don't reset \scriptstyle and -% \scriptscriptstyle). -% -\def\LaTeX{% - L\kern-.36em - {\setbox0=\hbox{T}% - \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}% - \kern-.15em - \TeX -} - -% Be sure we're in horizontal mode when doing a tie, since we make space -% equivalent to this in @example-like environments. Otherwise, a space -% at the beginning of a line will start with \penalty -- and -% since \penalty is valid in vertical mode, we'd end up putting the -% penalty on the vertical list instead of in the new paragraph. -{\catcode`@ = 11 - % Avoid using \@M directly, because that causes trouble - % if the definition is written into an index file. - \global\let\tiepenalty = \@M - \gdef\tie{\leavevmode\penalty\tiepenalty\ } -} - -% @: forces normal size whitespace following. -\def\:{\spacefactor=1000 } - -% @* forces a line break. -\def\*{\hfil\break\hbox{}\ignorespaces} - -% @/ allows a line break. -\let\/=\allowbreak - -% @. is an end-of-sentence period. -\def\.{.\spacefactor=\endofsentencespacefactor\space} - -% @! is an end-of-sentence bang. -\def\!{!\spacefactor=\endofsentencespacefactor\space} - -% @? is an end-of-sentence query. -\def\?{?\spacefactor=\endofsentencespacefactor\space} - -% @frenchspacing on|off says whether to put extra space after punctuation. -% -\def\onword{on} -\def\offword{off} -% -\parseargdef\frenchspacing{% - \def\temp{#1}% - \ifx\temp\onword \plainfrenchspacing - \else\ifx\temp\offword \plainnonfrenchspacing - \else - \errhelp = \EMsimple - \errmessage{Unknown @frenchspacing option `\temp', must be on/off}% - \fi\fi -} - -% @w prevents a word break. Without the \leavevmode, @w at the -% beginning of a paragraph, when TeX is still in vertical mode, would -% produce a whole line of output instead of starting the paragraph. -\def\w#1{\leavevmode\hbox{#1}} - -% @group ... @end group forces ... to be all on one page, by enclosing -% it in a TeX vbox. We use \vtop instead of \vbox to construct the box -% to keep its height that of a normal line. According to the rules for -% \topskip (p.114 of the TeXbook), the glue inserted is -% max (\topskip - \ht (first item), 0). If that height is large, -% therefore, no glue is inserted, and the space between the headline and -% the text is small, which looks bad. -% -% Another complication is that the group might be very large. This can -% cause the glue on the previous page to be unduly stretched, because it -% does not have much material. In this case, it's better to add an -% explicit \vfill so that the extra space is at the bottom. The -% threshold for doing this is if the group is more than \vfilllimit -% percent of a page (\vfilllimit can be changed inside of @tex). -% -\newbox\groupbox -\def\vfilllimit{0.7} -% -\envdef\group{% - \ifnum\catcode`\^^M=\active \else - \errhelp = \groupinvalidhelp - \errmessage{@group invalid in context where filling is enabled}% - \fi - \startsavinginserts - % - \setbox\groupbox = \vtop\bgroup - % Do @comment since we are called inside an environment such as - % @example, where each end-of-line in the input causes an - % end-of-line in the output. We don't want the end-of-line after - % the `@group' to put extra space in the output. Since @group - % should appear on a line by itself (according to the Texinfo - % manual), we don't worry about eating any user text. - \comment -} -% -% The \vtop produces a box with normal height and large depth; thus, TeX puts -% \baselineskip glue before it, and (when the next line of text is done) -% \lineskip glue after it. Thus, space below is not quite equal to space -% above. But it's pretty close. -\def\Egroup{% - % To get correct interline space between the last line of the group - % and the first line afterwards, we have to propagate \prevdepth. - \endgraf % Not \par, as it may have been set to \lisppar. - \global\dimen1 = \prevdepth - \egroup % End the \vtop. - % \dimen0 is the vertical size of the group's box. - \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox - % \dimen2 is how much space is left on the page (more or less). - \dimen2 = \pageheight \advance\dimen2 by -\pagetotal - % if the group doesn't fit on the current page, and it's a big big - % group, force a page break. - \ifdim \dimen0 > \dimen2 - \ifdim \pagetotal < \vfilllimit\pageheight - \page - \fi - \fi - \box\groupbox - \prevdepth = \dimen1 - \checkinserts -} -% -% TeX puts in an \escapechar (i.e., `@') at the beginning of the help -% message, so this ends up printing `@group can only ...'. -% -\newhelp\groupinvalidhelp{% -group can only be used in environments such as @example,^^J% -where each line of input produces a line of output.} - -% @need space-in-mils -% forces a page break if there is not space-in-mils remaining. - -\newdimen\mil \mil=0.001in - -% Old definition--didn't work. -%\parseargdef\need{\par % -%% This method tries to make TeX break the page naturally -%% if the depth of the box does not fit. -%{\baselineskip=0pt% -%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak -%\prevdepth=-1000pt -%}} - -\parseargdef\need{% - % Ensure vertical mode, so we don't make a big box in the middle of a - % paragraph. - \par - % - % If the @need value is less than one line space, it's useless. - \dimen0 = #1\mil - \dimen2 = \ht\strutbox - \advance\dimen2 by \dp\strutbox - \ifdim\dimen0 > \dimen2 - % - % Do a \strut just to make the height of this box be normal, so the - % normal leading is inserted relative to the preceding line. - % And a page break here is fine. - \vtop to #1\mil{\strut\vfil}% - % - % TeX does not even consider page breaks if a penalty added to the - % main vertical list is 10000 or more. But in order to see if the - % empty box we just added fits on the page, we must make it consider - % page breaks. On the other hand, we don't want to actually break the - % page after the empty box. So we use a penalty of 9999. - % - % There is an extremely small chance that TeX will actually break the - % page at this \penalty, if there are no other feasible breakpoints in - % sight. (If the user is using lots of big @group commands, which - % almost-but-not-quite fill up a page, TeX will have a hard time doing - % good page breaking, for example.) However, I could not construct an - % example where a page broke at this \penalty; if it happens in a real - % document, then we can reconsider our strategy. - \penalty9999 - % - % Back up by the size of the box, whether we did a page break or not. - \kern -#1\mil - % - % Do not allow a page break right after this kern. - \nobreak - \fi -} - -% @br forces paragraph break (and is undocumented). - -\let\br = \par - -% @page forces the start of a new page. -% -\def\page{\par\vfill\supereject} - -% @exdent text.... -% outputs text on separate line in roman font, starting at standard page margin - -% This records the amount of indent in the innermost environment. -% That's how much \exdent should take out. -\newskip\exdentamount - -% This defn is used inside fill environments such as @defun. -\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} - -% This defn is used inside nofill environments such as @example. -\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount - \leftline{\hskip\leftskip{\rm#1}}}} - -% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current -% paragraph. For more general purposes, use the \margin insertion -% class. WHICH is `l' or `r'. -% -\newskip\inmarginspacing \inmarginspacing=1cm -\def\strutdepth{\dp\strutbox} -% -\def\doinmargin#1#2{\strut\vadjust{% - \nobreak - \kern-\strutdepth - \vtop to \strutdepth{% - \baselineskip=\strutdepth - \vss - % if you have multiple lines of stuff to put here, you'll need to - % make the vbox yourself of the appropriate size. - \ifx#1l% - \llap{\ignorespaces #2\hskip\inmarginspacing}% - \else - \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% - \fi - \null - }% -}} -\def\inleftmargin{\doinmargin l} -\def\inrightmargin{\doinmargin r} -% -% @inmargin{TEXT [, RIGHT-TEXT]} -% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; -% else use TEXT for both). -% -\def\inmargin#1{\parseinmargin #1,,\finish} -\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \def\lefttext{#1}% have both texts - \def\righttext{#2}% - \else - \def\lefttext{#1}% have only one text - \def\righttext{#1}% - \fi - % - \ifodd\pageno - \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin - \else - \def\temp{\inleftmargin\lefttext}% - \fi - \temp -} - -% @include file insert text of that file as input. -% -\def\include{\parseargusing\filenamecatcodes\includezzz} -\def\includezzz#1{% - \pushthisfilestack - \def\thisfile{#1}% - {% - \makevalueexpandable - \def\temp{\input #1 }% - \expandafter - }\temp - \popthisfilestack -} -\def\filenamecatcodes{% - \catcode`\\=\other - \catcode`~=\other - \catcode`^=\other - \catcode`_=\other - \catcode`|=\other - \catcode`<=\other - \catcode`>=\other - \catcode`+=\other - \catcode`-=\other -} - -\def\pushthisfilestack{% - \expandafter\pushthisfilestackX\popthisfilestack\StackTerm -} -\def\pushthisfilestackX{% - \expandafter\pushthisfilestackY\thisfile\StackTerm -} -\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% - \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% -} - -\def\popthisfilestack{\errthisfilestackempty} -\def\errthisfilestackempty{\errmessage{Internal error: - the stack of filenames is empty.}} - -\def\thisfile{} - -% @center line -% outputs that line, centered. -% -\parseargdef\center{% - \ifhmode - \let\next\centerH - \else - \let\next\centerV - \fi - \next{\hfil \ignorespaces#1\unskip \hfil}% -} -\def\centerH#1{% - {% - \hfil\break - \advance\hsize by -\leftskip - \advance\hsize by -\rightskip - \line{#1}% - \break - }% -} -\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}} - -% @sp n outputs n lines of vertical space - -\parseargdef\sp{\vskip #1\baselineskip} - -% @comment ...line which is ignored... -% @c is the same as @comment -% @ignore ... @end ignore is another way to write a comment - -\def\comment{\begingroup \catcode`\^^M=\other% -\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% -\commentxxx} -{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} - -\let\c=\comment - -% @paragraphindent NCHARS -% We'll use ems for NCHARS, close enough. -% NCHARS can also be the word `asis' or `none'. -% We cannot feasibly implement @paragraphindent asis, though. -% -\def\asisword{asis} % no translation, these are keywords -\def\noneword{none} -% -\parseargdef\paragraphindent{% - \def\temp{#1}% - \ifx\temp\asisword - \else - \ifx\temp\noneword - \defaultparindent = 0pt - \else - \defaultparindent = #1em - \fi - \fi - \parindent = \defaultparindent -} - -% @exampleindent NCHARS -% We'll use ems for NCHARS like @paragraphindent. -% It seems @exampleindent asis isn't necessary, but -% I preserve it to make it similar to @paragraphindent. -\parseargdef\exampleindent{% - \def\temp{#1}% - \ifx\temp\asisword - \else - \ifx\temp\noneword - \lispnarrowing = 0pt - \else - \lispnarrowing = #1em - \fi - \fi -} - -% @firstparagraphindent WORD -% If WORD is `none', then suppress indentation of the first paragraph -% after a section heading. If WORD is `insert', then do indent at such -% paragraphs. -% -% The paragraph indentation is suppressed or not by calling -% \suppressfirstparagraphindent, which the sectioning commands do. -% We switch the definition of this back and forth according to WORD. -% By default, we suppress indentation. -% -\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} -\def\insertword{insert} -% -\parseargdef\firstparagraphindent{% - \def\temp{#1}% - \ifx\temp\noneword - \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent - \else\ifx\temp\insertword - \let\suppressfirstparagraphindent = \relax - \else - \errhelp = \EMsimple - \errmessage{Unknown @firstparagraphindent option `\temp'}% - \fi\fi -} - -% Here is how we actually suppress indentation. Redefine \everypar to -% \kern backwards by \parindent, and then reset itself to empty. -% -% We also make \indent itself not actually do anything until the next -% paragraph. -% -\gdef\dosuppressfirstparagraphindent{% - \gdef\indent{% - \restorefirstparagraphindent - \indent - }% - \gdef\noindent{% - \restorefirstparagraphindent - \noindent - }% - \global\everypar = {% - \kern -\parindent - \restorefirstparagraphindent - }% -} - -\gdef\restorefirstparagraphindent{% - \global \let \indent = \ptexindent - \global \let \noindent = \ptexnoindent - \global \everypar = {}% -} - - -% @asis just yields its argument. Used with @table, for example. -% -\def\asis#1{#1} - -% @math outputs its argument in math mode. -% -% One complication: _ usually means subscripts, but it could also mean -% an actual _ character, as in @math{@var{some_variable} + 1}. So make -% _ active, and distinguish by seeing if the current family is \slfam, -% which is what @var uses. -{ - \catcode`\_ = \active - \gdef\mathunderscore{% - \catcode`\_=\active - \def_{\ifnum\fam=\slfam \_\else\sb\fi}% - } -} -% Another complication: we want \\ (and @\) to output a \ character. -% FYI, plain.tex uses \\ as a temporary control sequence (why?), but -% this is not advertised and we don't care. Texinfo does not -% otherwise define @\. -% -% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. -\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} -% -\def\math{% - \tex - \mathunderscore - \let\\ = \mathbackslash - \mathactive - $\finishmath -} -\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. - -% Some active characters (such as <) are spaced differently in math. -% We have to reset their definitions in case the @math was an argument -% to a command which sets the catcodes (such as @item or @section). -% -{ - \catcode`^ = \active - \catcode`< = \active - \catcode`> = \active - \catcode`+ = \active - \gdef\mathactive{% - \let^ = \ptexhat - \let< = \ptexless - \let> = \ptexgtr - \let+ = \ptexplus - } -} - -% @bullet and @minus need the same treatment as @math, just above. -\def\bullet{$\ptexbullet$} -\def\minus{$-$} - -% @dots{} outputs an ellipsis using the current font. -% We do .5em per period so that it has the same spacing in the cm -% typewriter fonts as three actual period characters; on the other hand, -% in other typewriter fonts three periods are wider than 1.5em. So do -% whichever is larger. -% -\def\dots{% - \leavevmode - \setbox0=\hbox{...}% get width of three periods - \ifdim\wd0 > 1.5em - \dimen0 = \wd0 - \else - \dimen0 = 1.5em - \fi - \hbox to \dimen0{% - \hskip 0pt plus.25fil - .\hskip 0pt plus1fil - .\hskip 0pt plus1fil - .\hskip 0pt plus.5fil - }% -} - -% @enddots{} is an end-of-sentence ellipsis. -% -\def\enddots{% - \dots - \spacefactor=\endofsentencespacefactor -} - -% @comma{} is so commas can be inserted into text without messing up -% Texinfo's parsing. -% -\let\comma = , - -% @refill is a no-op. -\let\refill=\relax - -% If working on a large document in chapters, it is convenient to -% be able to disable indexing, cross-referencing, and contents, for test runs. -% This is done with @novalidate (before @setfilename). -% -\newif\iflinks \linkstrue % by default we want the aux files. -\let\novalidate = \linksfalse - -% @setfilename is done at the beginning of every texinfo file. -% So open here the files we need to have open while reading the input. -% This makes it possible to make a .fmt file for texinfo. -\def\setfilename{% - \fixbackslash % Turn off hack to swallow `\input texinfo'. - \iflinks - \tryauxfile - % Open the new aux file. TeX will close it automatically at exit. - \immediate\openout\auxfile=\jobname.aux - \fi % \openindices needs to do some work in any case. - \openindices - \let\setfilename=\comment % Ignore extra @setfilename cmds. - % - % If texinfo.cnf is present on the system, read it. - % Useful for site-wide @afourpaper, etc. - \openin 1 texinfo.cnf - \ifeof 1 \else \input texinfo.cnf \fi - \closein 1 - % - \comment % Ignore the actual filename. -} - -% Called from \setfilename. -% -\def\openindices{% - \newindex{cp}% - \newcodeindex{fn}% - \newcodeindex{vr}% - \newcodeindex{tp}% - \newcodeindex{ky}% - \newcodeindex{pg}% -} - -% @bye. -\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} - - -\message{pdf,} -% adobe `portable' document format -\newcount\tempnum -\newcount\lnkcount -\newtoks\filename -\newcount\filenamelength -\newcount\pgn -\newtoks\toksA -\newtoks\toksB -\newtoks\toksC -\newtoks\toksD -\newbox\boxA -\newcount\countA -\newif\ifpdf -\newif\ifpdfmakepagedest - -% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 -% can be set). So we test for \relax and 0 as well as \undefined, -% borrowed from ifpdf.sty. -\ifx\pdfoutput\undefined -\else - \ifx\pdfoutput\relax - \else - \ifcase\pdfoutput - \else - \pdftrue - \fi - \fi -\fi - -% PDF uses PostScript string constants for the names of xref targets, -% for display in the outlines, and in other places. Thus, we have to -% double any backslashes. Otherwise, a name like "\node" will be -% interpreted as a newline (\n), followed by o, d, e. Not good. -% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html -% (and related messages, the final outcome is that it is up to the TeX -% user to double the backslashes and otherwise make the string valid, so -% that's what we do). - -% double active backslashes. -% -{\catcode`\@=0 \catcode`\\=\active - @gdef at activebackslashdouble{% - @catcode`@\=@active - @let\=@doublebackslash} -} - -% To handle parens, we must adopt a different approach, since parens are -% not active characters. hyperref.dtx (which has the same problem as -% us) handles it with this amazing macro to replace tokens. I've -% tinkered with it a little for texinfo, but it's definitely from there. -% -% #1 is the tokens to replace. -% #2 is the replacement. -% #3 is the control sequence with the string. -% -\def\HyPsdSubst#1#2#3{% - \def\HyPsdReplace##1#1##2\END{% - ##1% - \ifx\\##2\\% - \else - #2% - \HyReturnAfterFi{% - \HyPsdReplace##2\END - }% - \fi - }% - \xdef#3{\expandafter\HyPsdReplace#3#1\END}% -} -\long\def\HyReturnAfterFi#1\fi{\fi#1} - -% #1 is a control sequence in which to do the replacements. -\def\backslashparens#1{% - \xdef#1{#1}% redefine it as its expansion; the definition is simply - % \lastnode when called from \setref -> \pdfmkdest. - \HyPsdSubst{(}{\realbackslash(}{#1}% - \HyPsdSubst{)}{\realbackslash)}{#1}% -} - -\ifpdf - \input pdfcolor - \pdfcatalog{/PageMode /UseOutlines}% - % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). - \def\dopdfimage#1#2#3{% - \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% - \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% - % without \immediate, pdftex seg faults when the same image is - % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) - \ifnum\pdftexversion < 14 - \immediate\pdfimage - \else - \immediate\pdfximage - \fi - \ifdim \wd0 >0pt width \imagewidth \fi - \ifdim \wd2 >0pt height \imageheight \fi - \ifnum\pdftexversion<13 - #1.pdf% - \else - {#1.pdf}% - \fi - \ifnum\pdftexversion < 14 \else - \pdfrefximage \pdflastximage - \fi} - \def\pdfmkdest#1{{% - % We have to set dummies so commands such as @code, and characters - % such as \, aren't expanded when present in a section title. - \atdummies - \activebackslashdouble - \def\pdfdestname{#1}% - \backslashparens\pdfdestname - \pdfdest name{\pdfdestname} xyz% - }}% - % - % used to mark target names; must be expandable. - \def\pdfmkpgn#1{#1}% - % - \let\linkcolor = \Blue % was Cyan, but that seems light? - \def\endlink{\Black\pdfendlink} - % Adding outlines to PDF; macros for calculating structure of outlines - % come from Petr Olsak - \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% - \else \csname#1\endcsname \fi} - \def\advancenumber#1{\tempnum=\expnumber{#1}\relax - \advance\tempnum by 1 - \expandafter\xdef\csname#1\endcsname{\the\tempnum}} - % - % #1 is the section text, which is what will be displayed in the - % outline by the pdf viewer. #2 is the pdf expression for the number - % of subentries (or empty, for subsubsections). #3 is the node text, - % which might be empty if this toc entry had no corresponding node. - % #4 is the page number - % - \def\dopdfoutline#1#2#3#4{% - % Generate a link to the node text if that exists; else, use the - % page number. We could generate a destination for the section - % text in the case where a section has no node, but it doesn't - % seem worth the trouble, since most documents are normally structured. - \def\pdfoutlinedest{#3}% - \ifx\pdfoutlinedest\empty - \def\pdfoutlinedest{#4}% - \else - % Doubled backslashes in the name. - {\activebackslashdouble \xdef\pdfoutlinedest{#3}% - \backslashparens\pdfoutlinedest}% - \fi - % - % Also double the backslashes in the display string. - {\activebackslashdouble \xdef\pdfoutlinetext{#1}% - \backslashparens\pdfoutlinetext}% - % - \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% - } - % - \def\pdfmakeoutlines{% - \begingroup - % Thanh's hack / proper braces in bookmarks - \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace - \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace - % - % Read toc silently, to get counts of subentries for \pdfoutline. - \def\numchapentry##1##2##3##4{% - \def\thischapnum{##2}% - \def\thissecnum{0}% - \def\thissubsecnum{0}% - }% - \def\numsecentry##1##2##3##4{% - \advancenumber{chap\thischapnum}% - \def\thissecnum{##2}% - \def\thissubsecnum{0}% - }% - \def\numsubsecentry##1##2##3##4{% - \advancenumber{sec\thissecnum}% - \def\thissubsecnum{##2}% - }% - \def\numsubsubsecentry##1##2##3##4{% - \advancenumber{subsec\thissubsecnum}% - }% - \def\thischapnum{0}% - \def\thissecnum{0}% - \def\thissubsecnum{0}% - % - % use \def rather than \let here because we redefine \chapentry et - % al. a second time, below. - \def\appentry{\numchapentry}% - \def\appsecentry{\numsecentry}% - \def\appsubsecentry{\numsubsecentry}% - \def\appsubsubsecentry{\numsubsubsecentry}% - \def\unnchapentry{\numchapentry}% - \def\unnsecentry{\numsecentry}% - \def\unnsubsecentry{\numsubsecentry}% - \def\unnsubsubsecentry{\numsubsubsecentry}% - \readdatafile{toc}% - % - % Read toc second time, this time actually producing the outlines. - % The `-' means take the \expnumber as the absolute number of - % subentries, which we calculated on our first read of the .toc above. - % - % We use the node names as the destinations. - \def\numchapentry##1##2##3##4{% - \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% - \def\numsecentry##1##2##3##4{% - \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% - \def\numsubsecentry##1##2##3##4{% - \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% - \def\numsubsubsecentry##1##2##3##4{% count is always zero - \dopdfoutline{##1}{}{##3}{##4}}% - % - % PDF outlines are displayed using system fonts, instead of - % document fonts. Therefore we cannot use special characters, - % since the encoding is unknown. For example, the eogonek from - % Latin 2 (0xea) gets translated to a | character. Info from - % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. - % - % xx to do this right, we have to translate 8-bit characters to - % their "best" equivalent, based on the @documentencoding. Right - % now, I guess we'll just let the pdf reader have its way. - \indexnofonts - \setupdatafile - \catcode`\\=\active \otherbackslash - \input \jobname.toc - \endgroup - } - % - \def\skipspaces#1{\def\PP{#1}\def\D{|}% - \ifx\PP\D\let\nextsp\relax - \else\let\nextsp\skipspaces - \ifx\p\space\else\addtokens{\filename}{\PP}% - \advance\filenamelength by 1 - \fi - \fi - \nextsp} - \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} - \ifnum\pdftexversion < 14 - \let \startlink \pdfannotlink - \else - \let \startlink \pdfstartlink - \fi - % make a live url in pdf output. - \def\pdfurl#1{% - \begingroup - % it seems we really need yet another set of dummies; have not - % tried to figure out what each command should do in the context - % of @url. for now, just make @/ a no-op, that's the only one - % people have actually reported a problem with. - % - \normalturnoffactive - \def\@{@}% - \let\/=\empty - \makevalueexpandable - \leavevmode\Red - \startlink attr{/Border [0 0 0]}% - user{/Subtype /Link /A << /S /URI /URI (#1) >>}% - \endgroup} - \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} - \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} - \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} - \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} - \def\maketoks{% - \expandafter\poptoks\the\toksA|ENDTOKS|\relax - \ifx\first0\adn0 - \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 - \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 - \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 - \else - \ifnum0=\countA\else\makelink\fi - \ifx\first.\let\next=\done\else - \let\next=\maketoks - \addtokens{\toksB}{\the\toksD} - \ifx\first,\addtokens{\toksB}{\space}\fi - \fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \next} - \def\makelink{\addtokens{\toksB}% - {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} - \def\pdflink#1{% - \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} - \linkcolor #1\endlink} - \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} -\else - \let\pdfmkdest = \gobble - \let\pdfurl = \gobble - \let\endlink = \relax - \let\linkcolor = \relax - \let\pdfmakeoutlines = \relax -\fi % \ifx\pdfoutput - - -\message{fonts,} - -% Change the current font style to #1, remembering it in \curfontstyle. -% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in -% italics, not bold italics. -% -\def\setfontstyle#1{% - \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. - \csname ten#1\endcsname % change the current font -} - -% Select #1 fonts with the current style. -% -\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} - -\def\rm{\fam=0 \setfontstyle{rm}} -\def\it{\fam=\itfam \setfontstyle{it}} -\def\sl{\fam=\slfam \setfontstyle{sl}} -\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} -\def\tt{\fam=\ttfam \setfontstyle{tt}} - -% Texinfo sort of supports the sans serif font style, which plain TeX does not. -% So we set up a \sf. -\newfam\sffam -\def\sf{\fam=\sffam \setfontstyle{sf}} -\let\li = \sf % Sometimes we call it \li, not \sf. - -% We don't need math for this font style. -\def\ttsl{\setfontstyle{ttsl}} - - -% Default leading. -\newdimen\textleading \textleading = 13.2pt - -% Set the baselineskip to #1, and the lineskip and strut size -% correspondingly. There is no deep meaning behind these magic numbers -% used as factors; they just match (closely enough) what Knuth defined. -% -\def\lineskipfactor{.08333} -\def\strutheightpercent{.70833} -\def\strutdepthpercent {.29167} -% -\def\setleading#1{% - \normalbaselineskip = #1\relax - \normallineskip = \lineskipfactor\normalbaselineskip - \normalbaselines - \setbox\strutbox =\hbox{% - \vrule width0pt height\strutheightpercent\baselineskip - depth \strutdepthpercent \baselineskip - }% -} - - -% Set the font macro #1 to the font named #2, adding on the -% specified font prefix (normally `cm'). -% #3 is the font's design size, #4 is a scale factor -\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} - - -% Use cm as the default font prefix. -% To specify the font prefix, you must define \fontprefix -% before you read in texinfo.tex. -\ifx\fontprefix\undefined -\def\fontprefix{cm} -\fi -% Support font families that don't use the same naming scheme as CM. -\def\rmshape{r} -\def\rmbshape{bx} %where the normal face is bold -\def\bfshape{b} -\def\bxshape{bx} -\def\ttshape{tt} -\def\ttbshape{tt} -\def\ttslshape{sltt} -\def\itshape{ti} -\def\itbshape{bxti} -\def\slshape{sl} -\def\slbshape{bxsl} -\def\sfshape{ss} -\def\sfbshape{ss} -\def\scshape{csc} -\def\scbshape{csc} - -% Definitions for a main text size of 11pt. This is the default in -% Texinfo. -% -\def\definetextfontsizexi{ -% Text fonts (11.2pt, magstep1). -\def\textnominalsize{11pt} -\edef\mainmagstep{\magstephalf} -\setfont\textrm\rmshape{10}{\mainmagstep} -\setfont\texttt\ttshape{10}{\mainmagstep} -\setfont\textbf\bfshape{10}{\mainmagstep} -\setfont\textit\itshape{10}{\mainmagstep} -\setfont\textsl\slshape{10}{\mainmagstep} -\setfont\textsf\sfshape{10}{\mainmagstep} -\setfont\textsc\scshape{10}{\mainmagstep} -\setfont\textttsl\ttslshape{10}{\mainmagstep} -\font\texti=cmmi10 scaled \mainmagstep -\font\textsy=cmsy10 scaled \mainmagstep - -% A few fonts for @defun names and args. -\setfont\defbf\bfshape{10}{\magstep1} -\setfont\deftt\ttshape{10}{\magstep1} -\setfont\defttsl\ttslshape{10}{\magstep1} -\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} - -% Fonts for indices, footnotes, small examples (9pt). -\def\smallnominalsize{9pt} -\setfont\smallrm\rmshape{9}{1000} -\setfont\smalltt\ttshape{9}{1000} -\setfont\smallbf\bfshape{10}{900} -\setfont\smallit\itshape{9}{1000} -\setfont\smallsl\slshape{9}{1000} -\setfont\smallsf\sfshape{9}{1000} -\setfont\smallsc\scshape{10}{900} -\setfont\smallttsl\ttslshape{10}{900} -\font\smalli=cmmi9 -\font\smallsy=cmsy9 - -% Fonts for small examples (8pt). -\def\smallernominalsize{8pt} -\setfont\smallerrm\rmshape{8}{1000} -\setfont\smallertt\ttshape{8}{1000} -\setfont\smallerbf\bfshape{10}{800} -\setfont\smallerit\itshape{8}{1000} -\setfont\smallersl\slshape{8}{1000} -\setfont\smallersf\sfshape{8}{1000} -\setfont\smallersc\scshape{10}{800} -\setfont\smallerttsl\ttslshape{10}{800} -\font\smalleri=cmmi8 -\font\smallersy=cmsy8 - -% Fonts for title page (20.4pt): -\def\titlenominalsize{20pt} -\setfont\titlerm\rmbshape{12}{\magstep3} -\setfont\titleit\itbshape{10}{\magstep4} -\setfont\titlesl\slbshape{10}{\magstep4} -\setfont\titlett\ttbshape{12}{\magstep3} -\setfont\titlettsl\ttslshape{10}{\magstep4} -\setfont\titlesf\sfbshape{17}{\magstep1} -\let\titlebf=\titlerm -\setfont\titlesc\scbshape{10}{\magstep4} -\font\titlei=cmmi12 scaled \magstep3 -\font\titlesy=cmsy10 scaled \magstep4 -\def\authorrm{\secrm} -\def\authortt{\sectt} - -% Chapter (and unnumbered) fonts (17.28pt). -\def\chapnominalsize{17pt} -\setfont\chaprm\rmbshape{12}{\magstep2} -\setfont\chapit\itbshape{10}{\magstep3} -\setfont\chapsl\slbshape{10}{\magstep3} -\setfont\chaptt\ttbshape{12}{\magstep2} -\setfont\chapttsl\ttslshape{10}{\magstep3} -\setfont\chapsf\sfbshape{17}{1000} -\let\chapbf=\chaprm -\setfont\chapsc\scbshape{10}{\magstep3} -\font\chapi=cmmi12 scaled \magstep2 -\font\chapsy=cmsy10 scaled \magstep3 - -% Section fonts (14.4pt). -\def\secnominalsize{14pt} -\setfont\secrm\rmbshape{12}{\magstep1} -\setfont\secit\itbshape{10}{\magstep2} -\setfont\secsl\slbshape{10}{\magstep2} -\setfont\sectt\ttbshape{12}{\magstep1} -\setfont\secttsl\ttslshape{10}{\magstep2} -\setfont\secsf\sfbshape{12}{\magstep1} -\let\secbf\secrm -\setfont\secsc\scbshape{10}{\magstep2} -\font\seci=cmmi12 scaled \magstep1 -\font\secsy=cmsy10 scaled \magstep2 - -% Subsection fonts (13.15pt). -\def\ssecnominalsize{13pt} -\setfont\ssecrm\rmbshape{12}{\magstephalf} -\setfont\ssecit\itbshape{10}{1315} -\setfont\ssecsl\slbshape{10}{1315} -\setfont\ssectt\ttbshape{12}{\magstephalf} -\setfont\ssecttsl\ttslshape{10}{1315} -\setfont\ssecsf\sfbshape{12}{\magstephalf} -\let\ssecbf\ssecrm -\setfont\ssecsc\scbshape{10}{1315} -\font\sseci=cmmi12 scaled \magstephalf -\font\ssecsy=cmsy10 scaled 1315 - -% Reduced fonts for @acro in text (10pt). -\def\reducednominalsize{10pt} -\setfont\reducedrm\rmshape{10}{1000} -\setfont\reducedtt\ttshape{10}{1000} -\setfont\reducedbf\bfshape{10}{1000} -\setfont\reducedit\itshape{10}{1000} -\setfont\reducedsl\slshape{10}{1000} -\setfont\reducedsf\sfshape{10}{1000} -\setfont\reducedsc\scshape{10}{1000} -\setfont\reducedttsl\ttslshape{10}{1000} -\font\reducedi=cmmi10 -\font\reducedsy=cmsy10 - -% reset the current fonts -\textfonts -\rm -} % end of 11pt text font size definitions - - -% Definitions to make the main text be 10pt Computer Modern, with -% section, chapter, etc., sizes following suit. This is for the GNU -% Press printing of the Emacs 22 manual. Maybe other manuals in the -% future. Used with @smallbook, which sets the leading to 12pt. -% -\def\definetextfontsizex{% -% Text fonts (10pt). -\def\textnominalsize{10pt} -\edef\mainmagstep{1000} -\setfont\textrm\rmshape{10}{\mainmagstep} -\setfont\texttt\ttshape{10}{\mainmagstep} -\setfont\textbf\bfshape{10}{\mainmagstep} -\setfont\textit\itshape{10}{\mainmagstep} -\setfont\textsl\slshape{10}{\mainmagstep} -\setfont\textsf\sfshape{10}{\mainmagstep} -\setfont\textsc\scshape{10}{\mainmagstep} -\setfont\textttsl\ttslshape{10}{\mainmagstep} -\font\texti=cmmi10 scaled \mainmagstep -\font\textsy=cmsy10 scaled \mainmagstep - -% A few fonts for @defun names and args. -\setfont\defbf\bfshape{10}{\magstephalf} -\setfont\deftt\ttshape{10}{\magstephalf} -\setfont\defttsl\ttslshape{10}{\magstephalf} -\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} - -% Fonts for indices, footnotes, small examples (9pt). -\def\smallnominalsize{9pt} -\setfont\smallrm\rmshape{9}{1000} -\setfont\smalltt\ttshape{9}{1000} -\setfont\smallbf\bfshape{10}{900} -\setfont\smallit\itshape{9}{1000} -\setfont\smallsl\slshape{9}{1000} -\setfont\smallsf\sfshape{9}{1000} -\setfont\smallsc\scshape{10}{900} -\setfont\smallttsl\ttslshape{10}{900} -\font\smalli=cmmi9 -\font\smallsy=cmsy9 - -% Fonts for small examples (8pt). -\def\smallernominalsize{8pt} -\setfont\smallerrm\rmshape{8}{1000} -\setfont\smallertt\ttshape{8}{1000} -\setfont\smallerbf\bfshape{10}{800} -\setfont\smallerit\itshape{8}{1000} -\setfont\smallersl\slshape{8}{1000} -\setfont\smallersf\sfshape{8}{1000} -\setfont\smallersc\scshape{10}{800} -\setfont\smallerttsl\ttslshape{10}{800} -\font\smalleri=cmmi8 -\font\smallersy=cmsy8 - -% Fonts for title page (20.4pt): -\def\titlenominalsize{20pt} -\setfont\titlerm\rmbshape{12}{\magstep3} -\setfont\titleit\itbshape{10}{\magstep4} -\setfont\titlesl\slbshape{10}{\magstep4} -\setfont\titlett\ttbshape{12}{\magstep3} -\setfont\titlettsl\ttslshape{10}{\magstep4} -\setfont\titlesf\sfbshape{17}{\magstep1} -\let\titlebf=\titlerm -\setfont\titlesc\scbshape{10}{\magstep4} -\font\titlei=cmmi12 scaled \magstep3 -\font\titlesy=cmsy10 scaled \magstep4 -\def\authorrm{\secrm} -\def\authortt{\sectt} - -% Chapter fonts (14.4pt). -\def\chapnominalsize{14pt} -\setfont\chaprm\rmbshape{12}{\magstep1} -\setfont\chapit\itbshape{10}{\magstep2} -\setfont\chapsl\slbshape{10}{\magstep2} -\setfont\chaptt\ttbshape{12}{\magstep1} -\setfont\chapttsl\ttslshape{10}{\magstep2} -\setfont\chapsf\sfbshape{12}{\magstep1} -\let\chapbf\chaprm -\setfont\chapsc\scbshape{10}{\magstep2} -\font\chapi=cmmi12 scaled \magstep1 -\font\chapsy=cmsy10 scaled \magstep2 - -% Section fonts (12pt). -\def\secnominalsize{12pt} -\setfont\secrm\rmbshape{12}{1000} -\setfont\secit\itbshape{10}{\magstep1} -\setfont\secsl\slbshape{10}{\magstep1} -\setfont\sectt\ttbshape{12}{1000} -\setfont\secttsl\ttslshape{10}{\magstep1} -\setfont\secsf\sfbshape{12}{1000} -\let\secbf\secrm -\setfont\secsc\scbshape{10}{\magstep1} -\font\seci=cmmi12 -\font\secsy=cmsy10 scaled \magstep1 - -% Subsection fonts (10pt). -\def\ssecnominalsize{10pt} -\setfont\ssecrm\rmbshape{10}{1000} -\setfont\ssecit\itbshape{10}{1000} -\setfont\ssecsl\slbshape{10}{1000} -\setfont\ssectt\ttbshape{10}{1000} -\setfont\ssecttsl\ttslshape{10}{1000} -\setfont\ssecsf\sfbshape{10}{1000} -\let\ssecbf\ssecrm -\setfont\ssecsc\scbshape{10}{1000} -\font\sseci=cmmi10 -\font\ssecsy=cmsy10 - -% Reduced fonts for @acro in text (9pt). -\def\reducednominalsize{9pt} -\setfont\reducedrm\rmshape{9}{1000} -\setfont\reducedtt\ttshape{9}{1000} -\setfont\reducedbf\bfshape{10}{900} -\setfont\reducedit\itshape{9}{1000} -\setfont\reducedsl\slshape{9}{1000} -\setfont\reducedsf\sfshape{9}{1000} -\setfont\reducedsc\scshape{10}{900} -\setfont\reducedttsl\ttslshape{10}{900} -\font\reducedi=cmmi9 -\font\reducedsy=cmsy9 - -% reduce space between paragraphs -\divide\parskip by 2 - -% reset the current fonts -\textfonts -\rm -} % end of 10pt text font size definitions - - -% We provide the user-level command -% @fonttextsize 10 -% (or 11) to redefine the text font size. pt is assumed. -% -\def\xword{10} -\def\xiword{11} -% -\parseargdef\fonttextsize{% - \def\textsizearg{#1}% - \wlog{doing @fonttextsize \textsizearg}% - % - % Set \globaldefs so that documents can use this inside @tex, since - % makeinfo 4.8 does not support it, but we need it nonetheless. - % - \begingroup \globaldefs=1 - \ifx\textsizearg\xword \definetextfontsizex - \else \ifx\textsizearg\xiword \definetextfontsizexi - \else - \errhelp=\EMsimple - \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} - \fi\fi - \endgroup -} - - -% In order for the font changes to affect most math symbols and letters, -% we have to define the \textfont of the standard families. Since -% texinfo doesn't allow for producing subscripts and superscripts except -% in the main text, we don't bother to reset \scriptfont and -% \scriptscriptfont (which would also require loading a lot more fonts). -% -\def\resetmathfonts{% - \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy - \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf - \textfont\ttfam=\tentt \textfont\sffam=\tensf -} - -% The font-changing commands redefine the meanings of \tenSTYLE, instead -% of just \STYLE. We do this because \STYLE needs to also set the -% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire -% \tenSTYLE to set the current font. -% -% Each font-changing command also sets the names \lsize (one size lower) -% and \lllsize (three sizes lower). These relative commands are used in -% the LaTeX logo and acronyms. -% -% This all needs generalizing, badly. -% -\def\textfonts{% - \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl - \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc - \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy - \let\tenttsl=\textttsl - \def\curfontsize{text}% - \def\lsize{reduced}\def\lllsize{smaller}% - \resetmathfonts \setleading{\textleading}} -\def\titlefonts{% - \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl - \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc - \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy - \let\tenttsl=\titlettsl - \def\curfontsize{title}% - \def\lsize{chap}\def\lllsize{subsec}% - \resetmathfonts \setleading{25pt}} -\def\titlefont#1{{\titlefonts\rm #1}} -\def\chapfonts{% - \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl - \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc - \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy - \let\tenttsl=\chapttsl - \def\curfontsize{chap}% - \def\lsize{sec}\def\lllsize{text}% - \resetmathfonts \setleading{19pt}} -\def\secfonts{% - \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl - \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc - \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy - \let\tenttsl=\secttsl - \def\curfontsize{sec}% - \def\lsize{subsec}\def\lllsize{reduced}% - \resetmathfonts \setleading{16pt}} -\def\subsecfonts{% - \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl - \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc - \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy - \let\tenttsl=\ssecttsl - \def\curfontsize{ssec}% - \def\lsize{text}\def\lllsize{small}% - \resetmathfonts \setleading{15pt}} -\let\subsubsecfonts = \subsecfonts -\def\reducedfonts{% - \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl - \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc - \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy - \let\tenttsl=\reducedttsl - \def\curfontsize{reduced}% - \def\lsize{small}\def\lllsize{smaller}% - \resetmathfonts \setleading{10.5pt}} -\def\smallfonts{% - \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl - \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc - \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy - \let\tenttsl=\smallttsl - \def\curfontsize{small}% - \def\lsize{smaller}\def\lllsize{smaller}% - \resetmathfonts \setleading{10.5pt}} -\def\smallerfonts{% - \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl - \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc - \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy - \let\tenttsl=\smallerttsl - \def\curfontsize{smaller}% - \def\lsize{smaller}\def\lllsize{smaller}% - \resetmathfonts \setleading{9.5pt}} - -% Set the fonts to use with the @small... environments. -\let\smallexamplefonts = \smallfonts - -% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample -% can fit this many characters: -% 8.5x11=86 smallbook=72 a4=90 a5=69 -% If we use \scriptfonts (8pt), then we can fit this many characters: -% 8.5x11=90+ smallbook=80 a4=90+ a5=77 -% For me, subjectively, the few extra characters that fit aren't worth -% the additional smallness of 8pt. So I'm making the default 9pt. -% -% By the way, for comparison, here's what fits with @example (10pt): -% 8.5x11=71 smallbook=60 a4=75 a5=58 -% -% I wish the USA used A4 paper. -% --karl, 24jan03. - - -% Set up the default fonts, so we can use them for creating boxes. -% -\definetextfontsizexi - -% Define these so they can be easily changed for other fonts. -\def\angleleft{$\langle$} -\def\angleright{$\rangle$} - -% Count depth in font-changes, for error checks -\newcount\fontdepth \fontdepth=0 - -% Fonts for short table of contents. -\setfont\shortcontrm\rmshape{12}{1000} -\setfont\shortcontbf\bfshape{10}{\magstep1} % no cmb12 -\setfont\shortcontsl\slshape{12}{1000} -\setfont\shortconttt\ttshape{12}{1000} - -%% Add scribe-like font environments, plus @l for inline lisp (usually sans -%% serif) and @ii for TeX italic - -% \smartitalic{ARG} outputs arg in italics, followed by an italic correction -% unless the following character is such as not to need one. -\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else - \ptexslash\fi\fi\fi} -\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} -\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} - -% like \smartslanted except unconditionally uses \ttsl. -% @var is set to this for defun arguments. -\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx} - -% like \smartslanted except unconditionally use \sl. We never want -% ttsl for book titles, do we? -\def\cite#1{{\sl #1}\futurelet\next\smartitalicx} - -\let\i=\smartitalic -\let\slanted=\smartslanted -\let\var=\smartslanted -\let\dfn=\smartslanted -\let\emph=\smartitalic - -% @b, explicit bold. -\def\b#1{{\bf #1}} -\let\strong=\b - -% @sansserif, explicit sans. -\def\sansserif#1{{\sf #1}} - -% We can't just use \exhyphenpenalty, because that only has effect at -% the end of a paragraph. Restore normal hyphenation at the end of the -% group within which \nohyphenation is presumably called. -% -\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} -\def\restorehyphenation{\hyphenchar\font = `- } - -% Set sfcode to normal for the chars that usually have another value. -% Can't use plain's \frenchspacing because it uses the `\x notation, and -% sometimes \x has an active definition that messes things up. -% -\catcode`@=11 - \def\plainfrenchspacing{% - \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m - \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m - \def\endofsentencespacefactor{1000}% for @. and friends - } - \def\plainnonfrenchspacing{% - \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 - \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 - \def\endofsentencespacefactor{3000}% for @. and friends - } -\catcode`@=\other -\def\endofsentencespacefactor{3000}% default - -\def\t#1{% - {\tt \rawbackslash \plainfrenchspacing #1}% - \null -} -\def\samp#1{`\tclose{#1}'\null} -\setfont\keyrm\rmshape{8}{1000} -\font\keysy=cmsy9 -\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% - \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% - \vbox{\hrule\kern-0.4pt - \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% - \kern-0.4pt\hrule}% - \kern-.06em\raise0.4pt\hbox{\angleright}}}} -% The old definition, with no lozenge: -%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} -\def\ctrl #1{{\tt \rawbackslash \hat}#1} - -% @file, @option are the same as @samp. -\let\file=\samp -\let\option=\samp - -% @code is a modification of @t, -% which makes spaces the same size as normal in the surrounding text. -\def\tclose#1{% - {% - % Change normal interword space to be same as for the current font. - \spaceskip = \fontdimen2\font - % - % Switch to typewriter. - \tt - % - % But `\ ' produces the large typewriter interword space. - \def\ {{\spaceskip = 0pt{} }}% - % - % Turn off hyphenation. - \nohyphenation - % - \rawbackslash - \plainfrenchspacing - #1% - }% - \null -} - -% We *must* turn on hyphenation at `-' and `_' in @code. -% Otherwise, it is too hard to avoid overfull hboxes -% in the Emacs manual, the Library manual, etc. - -% Unfortunately, TeX uses one parameter (\hyphenchar) to control -% both hyphenation at - and hyphenation within words. -% We must therefore turn them both off (\tclose does that) -% and arrange explicitly to hyphenate at a dash. -% -- rms. -{ - \catcode`\-=\active \catcode`\_=\active - \catcode`\'=\active \catcode`\`=\active - % - \global\def\code{\begingroup - \catcode\rquoteChar=\active \catcode\lquoteChar=\active - \let'\codequoteright \let`\codequoteleft - % - \catcode\dashChar=\active \catcode\underChar=\active - \ifallowcodebreaks - \let-\codedash - \let_\codeunder - \else - \let-\realdash - \let_\realunder - \fi - \codex - } -} - -\def\realdash{-} -\def\codedash{-\discretionary{}{}{}} -\def\codeunder{% - % this is all so @math{@code{var_name}+1} can work. In math mode, _ - % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) - % will therefore expand the active definition of _, which is us - % (inside @code that is), therefore an endless loop. - \ifusingtt{\ifmmode - \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. - \else\normalunderscore \fi - \discretionary{}{}{}}% - {\_}% -} -\def\codex #1{\tclose{#1}\endgroup} - -% An additional complication: the above will allow breaks after, e.g., -% each of the four underscores in __typeof__. This is undesirable in -% some manuals, especially if they don't have long identifiers in -% general. @allowcodebreaks provides a way to control this. -% -\newif\ifallowcodebreaks \allowcodebreakstrue - -\def\keywordtrue{true} -\def\keywordfalse{false} - -\parseargdef\allowcodebreaks{% - \def\txiarg{#1}% - \ifx\txiarg\keywordtrue - \allowcodebreakstrue - \else\ifx\txiarg\keywordfalse - \allowcodebreaksfalse - \else - \errhelp = \EMsimple - \errmessage{Unknown @allowcodebreaks option `\txiarg'}% - \fi\fi -} - -% @kbd is like @code, except that if the argument is just one @key command, -% then @kbd has no effect. - -% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), -% `example' (@kbd uses ttsl only inside of @example and friends), -% or `code' (@kbd uses normal tty font always). -\parseargdef\kbdinputstyle{% - \def\txiarg{#1}% - \ifx\txiarg\worddistinct - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% - \else\ifx\txiarg\wordexample - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% - \else\ifx\txiarg\wordcode - \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% - \else - \errhelp = \EMsimple - \errmessage{Unknown @kbdinputstyle option `\txiarg'}% - \fi\fi\fi -} -\def\worddistinct{distinct} -\def\wordexample{example} -\def\wordcode{code} - -% Default is `distinct.' -\kbdinputstyle distinct - -\def\xkey{\key} -\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% -\ifx\one\xkey\ifx\threex\three \key{#2}% -\else{\tclose{\kbdfont\look}}\fi -\else{\tclose{\kbdfont\look}}\fi} - -% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. -\let\indicateurl=\code -\let\env=\code -\let\command=\code - -% @uref (abbreviation for `urlref') takes an optional (comma-separated) -% second argument specifying the text to display and an optional third -% arg as text to display instead of (rather than in addition to) the url -% itself. First (mandatory) arg is the url. Perhaps eventually put in -% a hypertex \special here. -% -\def\uref#1{\douref #1,,,\finish} -\def\douref#1,#2,#3,#4\finish{\begingroup - \unsepspaces - \pdfurl{#1}% - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt - \unhbox0 % third arg given, show only that - \else - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \ifpdf - \unhbox0 % PDF: 2nd arg given, show only it - \else - \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url - \fi - \else - \code{#1}% only url given, so show it - \fi - \fi - \endlink -\endgroup} - -% @url synonym for @uref, since that's how everyone uses it. -% -\let\url=\uref - -% rms does not like angle brackets --karl, 17may97. -% So now @email is just like @uref, unless we are pdf. -% -%\def\email#1{\angleleft{\tt #1}\angleright} -\ifpdf - \def\email#1{\doemail#1,,\finish} - \def\doemail#1,#2,#3\finish{\begingroup - \unsepspaces - \pdfurl{mailto:#1}% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi - \endlink - \endgroup} -\else - \let\email=\uref -\fi - -% Check if we are currently using a typewriter font. Since all the -% Computer Modern typewriter fonts have zero interword stretch (and -% shrink), and it is reasonable to expect all typewriter fonts to have -% this property, we can check that font parameter. -% -\def\ifmonospace{\ifdim\fontdimen3\font=0pt } - -% Typeset a dimension, e.g., `in' or `pt'. The only reason for the -% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. -% -\def\dmn#1{\thinspace #1} - -\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} - -% @l was never documented to mean ``switch to the Lisp font'', -% and it is not used as such in any manual I can find. We need it for -% Polish suppressed-l. --karl, 22sep96. -%\def\l#1{{\li #1}\null} - -% Explicit font changes: @r, @sc, undocumented @ii. -\def\r#1{{\rm #1}} % roman font -\def\sc#1{{\smallcaps#1}} % smallcaps font -\def\ii#1{{\it #1}} % italic font - -% @acronym for "FBI", "NATO", and the like. -% We print this one point size smaller, since it's intended for -% all-uppercase. -% -\def\acronym#1{\doacronym #1,,\finish} -\def\doacronym#1,#2,#3\finish{% - {\selectfonts\lsize #1}% - \def\temp{#2}% - \ifx\temp\empty \else - \space ({\unsepspaces \ignorespaces \temp \unskip})% - \fi -} - -% @abbr for "Comput. J." and the like. -% No font change, but don't do end-of-sentence spacing. -% -\def\abbr#1{\doabbr #1,,\finish} -\def\doabbr#1,#2,#3\finish{% - {\plainfrenchspacing #1}% - \def\temp{#2}% - \ifx\temp\empty \else - \space ({\unsepspaces \ignorespaces \temp \unskip})% - \fi -} - -% @pounds{} is a sterling sign, which Knuth put in the CM italic font. -% -\def\pounds{{\it\$}} - -% @euro{} comes from a separate font, depending on the current style. -% We use the free feym* fonts from the eurosym package by Henrik -% Theiling, which support regular, slanted, bold and bold slanted (and -% "outlined" (blackboard board, sort of) versions, which we don't need). -% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. -% -% Although only regular is the truly official Euro symbol, we ignore -% that. The Euro is designed to be slightly taller than the regular -% font height. -% -% feymr - regular -% feymo - slanted -% feybr - bold -% feybo - bold slanted -% -% There is no good (free) typewriter version, to my knowledge. -% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. -% Hmm. -% -% Also doesn't work in math. Do we need to do math with euro symbols? -% Hope not. -% -% -\def\euro{{\eurofont e}} -\def\eurofont{% - % We set the font at each command, rather than predefining it in - % \textfonts and the other font-switching commands, so that - % installations which never need the symbol don't have to have the - % font installed. - % - % There is only one designed size (nominal 10pt), so we always scale - % that to the current nominal size. - % - % By the way, simply using "at 1em" works for cmr10 and the like, but - % does not work for cmbx10 and other extended/shrunken fonts. - % - \def\eurosize{\csname\curfontsize nominalsize\endcsname}% - % - \ifx\curfontstyle\bfstylename - % bold: - \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize - \else - % regular: - \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize - \fi - \thiseurofont -} - -% @registeredsymbol - R in a circle. The font for the R should really -% be smaller yet, but lllsize is the best we can do for now. -% Adapted from the plain.tex definition of \copyright. -% -\def\registeredsymbol{% - $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% - \hfil\crcr\Orb}}% - }$% -} - -% @textdegree - the normal degrees sign. -% -\def\textdegree{$^\circ$} - -% Laurent Siebenmann reports \Orb undefined with: -% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 -% so we'll define it if necessary. -% -\ifx\Orb\undefined -\def\Orb{\mathhexbox20D} -\fi - - -\message{page headings,} - -\newskip\titlepagetopglue \titlepagetopglue = 1.5in -\newskip\titlepagebottomglue \titlepagebottomglue = 2pc - -% First the title page. Must do @settitle before @titlepage. -\newif\ifseenauthor -\newif\iffinishedtitlepage - -% Do an implicit @contents or @shortcontents after @end titlepage if the -% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. -% -\newif\ifsetcontentsaftertitlepage - \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue -\newif\ifsetshortcontentsaftertitlepage - \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue - -\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% - \endgroup\page\hbox{}\page} - -\envdef\titlepage{% - % Open one extra group, as we want to close it in the middle of \Etitlepage. - \begingroup - \parindent=0pt \textfonts - % Leave some space at the very top of the page. - \vglue\titlepagetopglue - % No rule at page bottom unless we print one at the top with @title. - \finishedtitlepagetrue - % - % Most title ``pages'' are actually two pages long, with space - % at the top of the second. We don't want the ragged left on the second. - \let\oldpage = \page - \def\page{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - \let\page = \oldpage - \page - \null - }% -} - -\def\Etitlepage{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - % It is important to do the page break before ending the group, - % because the headline and footline are only empty inside the group. - % If we use the new definition of \page, we always get a blank page - % after the title page, which we certainly don't want. - \oldpage - \endgroup - % - % Need this before the \...aftertitlepage checks so that if they are - % in effect the toc pages will come out with page numbers. - \HEADINGSon - % - % If they want short, they certainly want long too. - \ifsetshortcontentsaftertitlepage - \shortcontents - \contents - \global\let\shortcontents = \relax - \global\let\contents = \relax - \fi - % - \ifsetcontentsaftertitlepage - \contents - \global\let\contents = \relax - \global\let\shortcontents = \relax - \fi -} - -\def\finishtitlepage{% - \vskip4pt \hrule height 2pt width \hsize - \vskip\titlepagebottomglue - \finishedtitlepagetrue -} - -%%% Macros to be used within @titlepage: - -\let\subtitlerm=\tenrm -\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} - -\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines - \let\tt=\authortt} - -\parseargdef\title{% - \checkenv\titlepage - \leftline{\titlefonts\rm #1} - % print a rule at the page bottom also. - \finishedtitlepagefalse - \vskip4pt \hrule height 4pt width \hsize \vskip4pt -} - -\parseargdef\subtitle{% - \checkenv\titlepage - {\subtitlefont \rightline{#1}}% -} - -% @author should come last, but may come many times. -% It can also be used inside @quotation. -% -\parseargdef\author{% - \def\temp{\quotation}% - \ifx\thisenv\temp - \def\quotationauthor{#1}% printed in \Equotation. - \else - \checkenv\titlepage - \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi - {\authorfont \leftline{#1}}% - \fi -} - - -%%% Set up page headings and footings. - -\let\thispage=\folio - -\newtoks\evenheadline % headline on even pages -\newtoks\oddheadline % headline on odd pages -\newtoks\evenfootline % footline on even pages -\newtoks\oddfootline % footline on odd pages - -% Now make TeX use those variables -\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline - \else \the\evenheadline \fi}} -\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline - \else \the\evenfootline \fi}\HEADINGShook} -\let\HEADINGShook=\relax - -% Commands to set those variables. -% For example, this is what @headings on does -% @evenheading @thistitle|@thispage|@thischapter -% @oddheading @thischapter|@thispage|@thistitle -% @evenfooting @thisfile|| -% @oddfooting ||@thisfile - - -\def\evenheading{\parsearg\evenheadingxxx} -\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} -\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% -\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\def\oddheading{\parsearg\oddheadingxxx} -\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} -\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% -\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% - -\def\evenfooting{\parsearg\evenfootingxxx} -\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} -\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% -\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\def\oddfooting{\parsearg\oddfootingxxx} -\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} -\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% - \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% - % - % Leave some space for the footline. Hopefully ok to assume - % @evenfooting will not be used by itself. - \global\advance\pageheight by -12pt - \global\advance\vsize by -12pt -} - -\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} - - -% @headings double turns headings on for double-sided printing. -% @headings single turns headings on for single-sided printing. -% @headings off turns them off. -% @headings on same as @headings double, retained for compatibility. -% @headings after turns on double-sided headings after this page. -% @headings doubleafter turns on double-sided headings after this page. -% @headings singleafter turns on single-sided headings after this page. -% By default, they are off at the start of a document, -% and turned `on' after @end titlepage. - -\def\headings #1 {\csname HEADINGS#1\endcsname} - -\def\HEADINGSoff{% -\global\evenheadline={\hfil} \global\evenfootline={\hfil} -\global\oddheadline={\hfil} \global\oddfootline={\hfil}} -\HEADINGSoff -% When we turn headings on, set the page number to 1. -% For double-sided printing, put current file name in lower left corner, -% chapter name on inside top of right hand pages, document -% title on inside top of left hand pages, and page numbers on outside top -% edge of all pages. -\def\HEADINGSdouble{% -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage -} -\let\contentsalignmacro = \chappager - -% For single-sided printing, chapter title goes across top left of page, -% page number on top right. -\def\HEADINGSsingle{% -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chappager -} -\def\HEADINGSon{\HEADINGSdouble} - -\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} -\let\HEADINGSdoubleafter=\HEADINGSafter -\def\HEADINGSdoublex{% -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage -} - -\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} -\def\HEADINGSsinglex{% -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chappager -} - -% Subroutines used in generating headings -% This produces Day Month Year style of output. -% Only define if not already defined, in case a txi-??.tex file has set -% up a different format (e.g., txi-cs.tex does this). -\ifx\today\undefined -\def\today{% - \number\day\space - \ifcase\month - \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr - \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug - \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec - \fi - \space\number\year} -\fi - -% @settitle line... specifies the title of the document, for headings. -% It generates no output of its own. -\def\thistitle{\putwordNoTitle} -\def\settitle{\parsearg{\gdef\thistitle}} - - -\message{tables,} -% Tables -- @table, @ftable, @vtable, @item(x). - -% default indentation of table text -\newdimen\tableindent \tableindent=.8in -% default indentation of @itemize and @enumerate text -\newdimen\itemindent \itemindent=.3in -% margin between end of table item and start of table text. -\newdimen\itemmargin \itemmargin=.1in - -% used internally for \itemindent minus \itemmargin -\newdimen\itemmax - -% Note @table, @ftable, and @vtable define @item, @itemx, etc., with -% these defs. -% They also define \itemindex -% to index the item name in whatever manner is desired (perhaps none). - -\newif\ifitemxneedsnegativevskip - -\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} - -\def\internalBitem{\smallbreak \parsearg\itemzzz} -\def\internalBitemx{\itemxpar \parsearg\itemzzz} - -\def\itemzzz #1{\begingroup % - \advance\hsize by -\rightskip - \advance\hsize by -\tableindent - \setbox0=\hbox{\itemindicate{#1}}% - \itemindex{#1}% - \nobreak % This prevents a break before @itemx. - % - % If the item text does not fit in the space we have, put it on a line - % by itself, and do not allow a page break either before or after that - % line. We do not start a paragraph here because then if the next - % command is, e.g., @kindex, the whatsit would get put into the - % horizontal list on a line by itself, resulting in extra blank space. - \ifdim \wd0>\itemmax - % - % Make this a paragraph so we get the \parskip glue and wrapping, - % but leave it ragged-right. - \begingroup - \advance\leftskip by-\tableindent - \advance\hsize by\tableindent - \advance\rightskip by0pt plus1fil - \leavevmode\unhbox0\par - \endgroup - % - % We're going to be starting a paragraph, but we don't want the - % \parskip glue -- logically it's part of the @item we just started. - \nobreak \vskip-\parskip - % - % Stop a page break at the \parskip glue coming up. However, if - % what follows is an environment such as @example, there will be no - % \parskip glue; then the negative vskip we just inserted would - % cause the example and the item to crash together. So we use this - % bizarre value of 10001 as a signal to \aboveenvbreak to insert - % \parskip glue after all. Section titles are handled this way also. - % - \penalty 10001 - \endgroup - \itemxneedsnegativevskipfalse - \else - % The item text fits into the space. Start a paragraph, so that the - % following text (if any) will end up on the same line. - \noindent - % Do this with kerns and \unhbox so that if there is a footnote in - % the item text, it can migrate to the main vertical list and - % eventually be printed. - \nobreak\kern-\tableindent - \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 - \unhbox0 - \nobreak\kern\dimen0 - \endgroup - \itemxneedsnegativevskiptrue - \fi -} - -\def\item{\errmessage{@item while not in a list environment}} -\def\itemx{\errmessage{@itemx while not in a list environment}} - -% @table, @ftable, @vtable. -\envdef\table{% - \let\itemindex\gobble - \tablecheck{table}% -} -\envdef\ftable{% - \def\itemindex ##1{\doind {fn}{\code{##1}}}% - \tablecheck{ftable}% -} -\envdef\vtable{% - \def\itemindex ##1{\doind {vr}{\code{##1}}}% - \tablecheck{vtable}% -} -\def\tablecheck#1{% - \ifnum \the\catcode`\^^M=\active - \endgroup - \errmessage{This command won't work in this context; perhaps the problem is - that we are \inenvironment\thisenv}% - \def\next{\doignore{#1}}% - \else - \let\next\tablex - \fi - \next -} -\def\tablex#1{% - \def\itemindicate{#1}% - \parsearg\tabley -} -\def\tabley#1{% - {% - \makevalueexpandable - \edef\temp{\noexpand\tablez #1\space\space\space}% - \expandafter - }\temp \endtablez -} -\def\tablez #1 #2 #3 #4\endtablez{% - \aboveenvbreak - \ifnum 0#1>0 \advance \leftskip by #1\mil \fi - \ifnum 0#2>0 \tableindent=#2\mil \fi - \ifnum 0#3>0 \advance \rightskip by #3\mil \fi - \itemmax=\tableindent - \advance \itemmax by -\itemmargin - \advance \leftskip by \tableindent - \exdentamount=\tableindent - \parindent = 0pt - \parskip = \smallskipamount - \ifdim \parskip=0pt \parskip=2pt \fi - \let\item = \internalBitem - \let\itemx = \internalBitemx -} -\def\Etable{\endgraf\afterenvbreak} -\let\Eftable\Etable -\let\Evtable\Etable -\let\Eitemize\Etable -\let\Eenumerate\Etable - -% This is the counter used by @enumerate, which is really @itemize - -\newcount \itemno - -\envdef\itemize{\parsearg\doitemize} - -\def\doitemize#1{% - \aboveenvbreak - \itemmax=\itemindent - \advance\itemmax by -\itemmargin - \advance\leftskip by \itemindent - \exdentamount=\itemindent - \parindent=0pt - \parskip=\smallskipamount - \ifdim\parskip=0pt \parskip=2pt \fi - \def\itemcontents{#1}% - % @itemize with no arg is equivalent to @itemize @bullet. - \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi - \let\item=\itemizeitem -} - -% Definition of @item while inside @itemize and @enumerate. -% -\def\itemizeitem{% - \advance\itemno by 1 % for enumerations - {\let\par=\endgraf \smallbreak}% reasonable place to break - {% - % If the document has an @itemize directly after a section title, a - % \nobreak will be last on the list, and \sectionheading will have - % done a \vskip-\parskip. In that case, we don't want to zero - % parskip, or the item text will crash with the heading. On the - % other hand, when there is normal text preceding the item (as there - % usually is), we do want to zero parskip, or there would be too much - % space. In that case, we won't have a \nobreak before. At least - % that's the theory. - \ifnum\lastpenalty<10000 \parskip=0in \fi - \noindent - \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% - \vadjust{\penalty 1200}}% not good to break after first line of item. - \flushcr -} - -% \splitoff TOKENS\endmark defines \first to be the first token in -% TOKENS, and \rest to be the remainder. -% -\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% - -% Allow an optional argument of an uppercase letter, lowercase letter, -% or number, to specify the first label in the enumerated list. No -% argument is the same as `1'. -% -\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} -\def\enumeratey #1 #2\endenumeratey{% - % If we were given no argument, pretend we were given `1'. - \def\thearg{#1}% - \ifx\thearg\empty \def\thearg{1}\fi - % - % Detect if the argument is a single token. If so, it might be a - % letter. Otherwise, the only valid thing it can be is a number. - % (We will always have one token, because of the test we just made. - % This is a good thing, since \splitoff doesn't work given nothing at - % all -- the first parameter is undelimited.) - \expandafter\splitoff\thearg\endmark - \ifx\rest\empty - % Only one token in the argument. It could still be anything. - % A ``lowercase letter'' is one whose \lccode is nonzero. - % An ``uppercase letter'' is one whose \lccode is both nonzero, and - % not equal to itself. - % Otherwise, we assume it's a number. - % - % We need the \relax at the end of the \ifnum lines to stop TeX from - % continuing to look for a . - % - \ifnum\lccode\expandafter`\thearg=0\relax - \numericenumerate % a number (we hope) - \else - % It's a letter. - \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax - \lowercaseenumerate % lowercase letter - \else - \uppercaseenumerate % uppercase letter - \fi - \fi - \else - % Multiple tokens in the argument. We hope it's a number. - \numericenumerate - \fi -} - -% An @enumerate whose labels are integers. The starting integer is -% given in \thearg. -% -\def\numericenumerate{% - \itemno = \thearg - \startenumeration{\the\itemno}% -} - -% The starting (lowercase) letter is in \thearg. -\def\lowercaseenumerate{% - \itemno = \expandafter`\thearg - \startenumeration{% - % Be sure we're not beyond the end of the alphabet. - \ifnum\itemno=0 - \errmessage{No more lowercase letters in @enumerate; get a bigger - alphabet}% - \fi - \char\lccode\itemno - }% -} - -% The starting (uppercase) letter is in \thearg. -\def\uppercaseenumerate{% - \itemno = \expandafter`\thearg - \startenumeration{% - % Be sure we're not beyond the end of the alphabet. - \ifnum\itemno=0 - \errmessage{No more uppercase letters in @enumerate; get a bigger - alphabet} - \fi - \char\uccode\itemno - }% -} - -% Call \doitemize, adding a period to the first argument and supplying the -% common last two arguments. Also subtract one from the initial value in -% \itemno, since @item increments \itemno. -% -\def\startenumeration#1{% - \advance\itemno by -1 - \doitemize{#1.}\flushcr -} - -% @alphaenumerate and @capsenumerate are abbreviations for giving an arg -% to @enumerate. -% -\def\alphaenumerate{\enumerate{a}} -\def\capsenumerate{\enumerate{A}} -\def\Ealphaenumerate{\Eenumerate} -\def\Ecapsenumerate{\Eenumerate} - - -% @multitable macros -% Amy Hendrickson, 8/18/94, 3/6/96 -% -% @multitable ... @end multitable will make as many columns as desired. -% Contents of each column will wrap at width given in preamble. Width -% can be specified either with sample text given in a template line, -% or in percent of \hsize, the current width of text on page. - -% Table can continue over pages but will only break between lines. - -% To make preamble: -% -% Either define widths of columns in terms of percent of \hsize: -% @multitable @columnfractions .25 .3 .45 -% @item ... -% -% Numbers following @columnfractions are the percent of the total -% current hsize to be used for each column. You may use as many -% columns as desired. - - -% Or use a template: -% @multitable {Column 1 template} {Column 2 template} {Column 3 template} -% @item ... -% using the widest term desired in each column. - -% Each new table line starts with @item, each subsequent new column -% starts with @tab. Empty columns may be produced by supplying @tab's -% with nothing between them for as many times as empty columns are needed, -% ie, @tab at tab@tab will produce two empty columns. - -% @item, @tab do not need to be on their own lines, but it will not hurt -% if they are. - -% Sample multitable: - -% @multitable {Column 1 template} {Column 2 template} {Column 3 template} -% @item first col stuff @tab second col stuff @tab third col -% @item -% first col stuff -% @tab -% second col stuff -% @tab -% third col -% @item first col stuff @tab second col stuff -% @tab Many paragraphs of text may be used in any column. -% -% They will wrap at the width determined by the template. -% @item at tab@tab This will be in third column. -% @end multitable - -% Default dimensions may be reset by user. -% @multitableparskip is vertical space between paragraphs in table. -% @multitableparindent is paragraph indent in table. -% @multitablecolmargin is horizontal space to be left between columns. -% @multitablelinespace is space to leave between table items, baseline -% to baseline. -% 0pt means it depends on current normal line spacing. -% -\newskip\multitableparskip -\newskip\multitableparindent -\newdimen\multitablecolspace -\newskip\multitablelinespace -\multitableparskip=0pt -\multitableparindent=6pt -\multitablecolspace=12pt -\multitablelinespace=0pt - -% Macros used to set up halign preamble: -% -\let\endsetuptable\relax -\def\xendsetuptable{\endsetuptable} -\let\columnfractions\relax -\def\xcolumnfractions{\columnfractions} -\newif\ifsetpercent - -% #1 is the @columnfraction, usually a decimal number like .5, but might -% be just 1. We just use it, whatever it is. -% -\def\pickupwholefraction#1 {% - \global\advance\colcount by 1 - \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% - \setuptable -} - -\newcount\colcount -\def\setuptable#1{% - \def\firstarg{#1}% - \ifx\firstarg\xendsetuptable - \let\go = \relax - \else - \ifx\firstarg\xcolumnfractions - \global\setpercenttrue - \else - \ifsetpercent - \let\go\pickupwholefraction - \else - \global\advance\colcount by 1 - \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a - % separator; typically that is always in the input, anyway. - \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% - \fi - \fi - \ifx\go\pickupwholefraction - % Put the argument back for the \pickupwholefraction call, so - % we'll always have a period there to be parsed. - \def\go{\pickupwholefraction#1}% - \else - \let\go = \setuptable - \fi% - \fi - \go -} - -% multitable-only commands. -% -% @headitem starts a heading row, which we typeset in bold. -% Assignments have to be global since we are inside the implicit group -% of an alignment entry. Note that \everycr resets \everytab. -\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}% -% -% A \tab used to include \hskip1sp. But then the space in a template -% line is not enough. That is bad. So let's go back to just `&' until -% we encounter the problem it was intended to solve again. -% --karl, nathan at acm.org, 20apr99. -\def\tab{\checkenv\multitable &\the\everytab}% - -% @multitable ... @end multitable definitions: -% -\newtoks\everytab % insert after every tab. -% -\envdef\multitable{% - \vskip\parskip - \startsavinginserts - % - % @item within a multitable starts a normal row. - % We use \def instead of \let so that if one of the multitable entries - % contains an @itemize, we don't choke on the \item (seen as \crcr aka - % \endtemplate) expanding \doitemize. - \def\item{\crcr}% - % - \tolerance=9500 - \hbadness=9500 - \setmultitablespacing - \parskip=\multitableparskip - \parindent=\multitableparindent - \overfullrule=0pt - \global\colcount=0 - % - \everycr = {% - \noalign{% - \global\everytab={}% - \global\colcount=0 % Reset the column counter. - % Check for saved footnotes, etc. - \checkinserts - % Keeps underfull box messages off when table breaks over pages. - %\filbreak - % Maybe so, but it also creates really weird page breaks when the - % table breaks over pages. Wouldn't \vfil be better? Wait until the - % problem manifests itself, so it can be fixed for real --karl. - }% - }% - % - \parsearg\domultitable -} -\def\domultitable#1{% - % To parse everything between @multitable and @item: - \setuptable#1 \endsetuptable - % - % This preamble sets up a generic column definition, which will - % be used as many times as user calls for columns. - % \vtop will set a single line and will also let text wrap and - % continue for many paragraphs if desired. - \halign\bgroup &% - \global\advance\colcount by 1 - \multistrut - \vtop{% - % Use the current \colcount to find the correct column width: - \hsize=\expandafter\csname col\the\colcount\endcsname - % - % In order to keep entries from bumping into each other - % we will add a \leftskip of \multitablecolspace to all columns after - % the first one. - % - % If a template has been used, we will add \multitablecolspace - % to the width of each template entry. - % - % If the user has set preamble in terms of percent of \hsize we will - % use that dimension as the width of the column, and the \leftskip - % will keep entries from bumping into each other. Table will start at - % left margin and final column will justify at right margin. - % - % Make sure we don't inherit \rightskip from the outer environment. - \rightskip=0pt - \ifnum\colcount=1 - % The first column will be indented with the surrounding text. - \advance\hsize by\leftskip - \else - \ifsetpercent \else - % If user has not set preamble in terms of percent of \hsize - % we will advance \hsize by \multitablecolspace. - \advance\hsize by \multitablecolspace - \fi - % In either case we will make \leftskip=\multitablecolspace: - \leftskip=\multitablecolspace - \fi - % Ignoring space at the beginning and end avoids an occasional spurious - % blank line, when TeX decides to break the line at the space before the - % box from the multistrut, so the strut ends up on a line by itself. - % For example: - % @multitable @columnfractions .11 .89 - % @item @code{#} - % @tab Legal holiday which is valid in major parts of the whole country. - % Is automatically provided with highlighting sequences respectively - % marking characters. - \noindent\ignorespaces##\unskip\multistrut - }\cr -} -\def\Emultitable{% - \crcr - \egroup % end the \halign - \global\setpercentfalse -} - -\def\setmultitablespacing{% - \def\multistrut{\strut}% just use the standard line spacing - % - % Compute \multitablelinespace (if not defined by user) for use in - % \multitableparskip calculation. We used define \multistrut based on - % this, but (ironically) that caused the spacing to be off. - % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. -\ifdim\multitablelinespace=0pt -\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip -\global\advance\multitablelinespace by-\ht0 -\fi -%% Test to see if parskip is larger than space between lines of -%% table. If not, do nothing. -%% If so, set to same dimension as multitablelinespace. -\ifdim\multitableparskip>\multitablelinespace -\global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. -\fi% -\ifdim\multitableparskip=0pt -\global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. -\fi} - - -\message{conditionals,} - -% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, -% @ifnotxml always succeed. They currently do nothing; we don't -% attempt to check whether the conditionals are properly nested. But we -% have to remember that they are conditionals, so that @end doesn't -% attempt to close an environment group. -% -\def\makecond#1{% - \expandafter\let\csname #1\endcsname = \relax - \expandafter\let\csname iscond.#1\endcsname = 1 -} -\makecond{iftex} -\makecond{ifnotdocbook} -\makecond{ifnothtml} -\makecond{ifnotinfo} -\makecond{ifnotplaintext} -\makecond{ifnotxml} - -% Ignore @ignore, @ifhtml, @ifinfo, and the like. -% -\def\direntry{\doignore{direntry}} -\def\documentdescription{\doignore{documentdescription}} -\def\docbook{\doignore{docbook}} -\def\html{\doignore{html}} -\def\ifdocbook{\doignore{ifdocbook}} -\def\ifhtml{\doignore{ifhtml}} -\def\ifinfo{\doignore{ifinfo}} -\def\ifnottex{\doignore{ifnottex}} -\def\ifplaintext{\doignore{ifplaintext}} -\def\ifxml{\doignore{ifxml}} -\def\ignore{\doignore{ignore}} -\def\menu{\doignore{menu}} -\def\xml{\doignore{xml}} - -% Ignore text until a line `@end #1', keeping track of nested conditionals. -% -% A count to remember the depth of nesting. -\newcount\doignorecount - -\def\doignore#1{\begingroup - % Scan in ``verbatim'' mode: - \obeylines - \catcode`\@ = \other - \catcode`\{ = \other - \catcode`\} = \other - % - % Make sure that spaces turn into tokens that match what \doignoretext wants. - \spaceisspace - % - % Count number of #1's that we've seen. - \doignorecount = 0 - % - % Swallow text until we reach the matching `@end #1'. - \dodoignore{#1}% -} - -{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. - \obeylines % - % - \gdef\dodoignore#1{% - % #1 contains the command name as a string, e.g., `ifinfo'. - % - % Define a command to find the next `@end #1'. - \long\def\doignoretext##1^^M at end #1{% - \doignoretextyyy##1^^M@#1\_STOP_}% - % - % And this command to find another #1 command, at the beginning of a - % line. (Otherwise, we would consider a line `@c @ifset', for - % example, to count as an @ifset for nesting.) - \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% - % - % And now expand that command. - \doignoretext ^^M% - }% -} - -\def\doignoreyyy#1{% - \def\temp{#1}% - \ifx\temp\empty % Nothing found. - \let\next\doignoretextzzz - \else % Found a nested condition, ... - \advance\doignorecount by 1 - \let\next\doignoretextyyy % ..., look for another. - % If we're here, #1 ends with ^^M\ifinfo (for example). - \fi - \next #1% the token \_STOP_ is present just after this macro. -} - -% We have to swallow the remaining "\_STOP_". -% -\def\doignoretextzzz#1{% - \ifnum\doignorecount = 0 % We have just found the outermost @end. - \let\next\enddoignore - \else % Still inside a nested condition. - \advance\doignorecount by -1 - \let\next\doignoretext % Look for the next @end. - \fi - \next -} - -% Finish off ignored text. -{ \obeylines% - % Ignore anything after the last `@end #1'; this matters in verbatim - % environments, where otherwise the newline after an ignored conditional - % would result in a blank line in the output. - \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% -} - - -% @set VAR sets the variable VAR to an empty value. -% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. -% -% Since we want to separate VAR from REST-OF-LINE (which might be -% empty), we can't just use \parsearg; we have to insert a space of our -% own to delimit the rest of the line, and then take it out again if we -% didn't need it. -% We rely on the fact that \parsearg sets \catcode`\ =10. -% -\parseargdef\set{\setyyy#1 \endsetyyy} -\def\setyyy#1 #2\endsetyyy{% - {% - \makevalueexpandable - \def\temp{#2}% - \edef\next{\gdef\makecsname{SET#1}}% - \ifx\temp\empty - \next{}% - \else - \setzzz#2\endsetzzz - \fi - }% -} -% Remove the trailing space \setxxx inserted. -\def\setzzz#1 \endsetzzz{\next{#1}} - -% @clear VAR clears (i.e., unsets) the variable VAR. -% -\parseargdef\clear{% - {% - \makevalueexpandable - \global\expandafter\let\csname SET#1\endcsname=\relax - }% -} - -% @value{foo} gets the text saved in variable foo. -\def\value{\begingroup\makevalueexpandable\valuexxx} -\def\valuexxx#1{\expandablevalue{#1}\endgroup} -{ - \catcode`\- = \active \catcode`\_ = \active - % - \gdef\makevalueexpandable{% - \let\value = \expandablevalue - % We don't want these characters active, ... - \catcode`\-=\other \catcode`\_=\other - % ..., but we might end up with active ones in the argument if - % we're called from @code, as @code{@value{foo-bar_}}, though. - % So \let them to their normal equivalents. - \let-\realdash \let_\normalunderscore - } -} - -% We have this subroutine so that we can handle at least some @value's -% properly in indexes (we call \makevalueexpandable in \indexdummies). -% The command has to be fully expandable (if the variable is set), since -% the result winds up in the index file. This means that if the -% variable's value contains other Texinfo commands, it's almost certain -% it will fail (although perhaps we could fix that with sufficient work -% to do a one-level expansion on the result, instead of complete). -% -\def\expandablevalue#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - {[No value for ``#1'']}% - \message{Variable `#1', used in @value, is not set.}% - \else - \csname SET#1\endcsname - \fi -} - -% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined -% with @set. -% -% To get special treatment of `@end ifset,' call \makeond and the redefine. -% -\makecond{ifset} -\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} -\def\doifset#1#2{% - {% - \makevalueexpandable - \let\next=\empty - \expandafter\ifx\csname SET#2\endcsname\relax - #1% If not set, redefine \next. - \fi - \expandafter - }\next -} -\def\ifsetfail{\doignore{ifset}} - -% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been -% defined with @set, or has been undefined with @clear. -% -% The `\else' inside the `\doifset' parameter is a trick to reuse the -% above code: if the variable is not set, do nothing, if it is set, -% then redefine \next to \ifclearfail. -% -\makecond{ifclear} -\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} -\def\ifclearfail{\doignore{ifclear}} - -% @dircategory CATEGORY -- specify a category of the dir file -% which this file should belong to. Ignore this in TeX. -\let\dircategory=\comment - -% @defininfoenclose. -\let\definfoenclose=\comment - - -\message{indexing,} -% Index generation facilities - -% Define \newwrite to be identical to plain tex's \newwrite -% except not \outer, so it can be used within macros and \if's. -\edef\newwrite{\makecsname{ptexnewwrite}} - -% \newindex {foo} defines an index named foo. -% It automatically defines \fooindex such that -% \fooindex ...rest of line... puts an entry in the index foo. -% It also defines \fooindfile to be the number of the output channel for -% the file that accumulates this index. The file's extension is foo. -% The name of an index should be no more than 2 characters long -% for the sake of vms. -% -\def\newindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 % Open the file - \fi - \expandafter\xdef\csname#1index\endcsname{% % Define @#1index - \noexpand\doindex{#1}} -} - -% @defindex foo == \newindex{foo} -% -\def\defindex{\parsearg\newindex} - -% Define @defcodeindex, like @defindex except put all entries in @code. -% -\def\defcodeindex{\parsearg\newcodeindex} -% -\def\newcodeindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 - \fi - \expandafter\xdef\csname#1index\endcsname{% - \noexpand\docodeindex{#1}}% -} - - -% @synindex foo bar makes index foo feed into index bar. -% Do this instead of @defindex foo if you don't want it as a separate index. -% -% @syncodeindex foo bar similar, but put all entries made for index foo -% inside @code. -% -\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} -\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} - -% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), -% #3 the target index (bar). -\def\dosynindex#1#2#3{% - % Only do \closeout if we haven't already done it, else we'll end up - % closing the target index. - \expandafter \ifx\csname donesynindex#2\endcsname \undefined - % The \closeout helps reduce unnecessary open files; the limit on the - % Acorn RISC OS is a mere 16 files. - \expandafter\closeout\csname#2indfile\endcsname - \expandafter\let\csname\donesynindex#2\endcsname = 1 - \fi - % redefine \fooindfile: - \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname - \expandafter\let\csname#2indfile\endcsname=\temp - % redefine \fooindex: - \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% -} - -% Define \doindex, the driver for all \fooindex macros. -% Argument #1 is generated by the calling \fooindex macro, -% and it is "foo", the name of the index. - -% \doindex just uses \parsearg; it calls \doind for the actual work. -% This is because \doind is more useful to call from other macros. - -% There is also \dosubind {index}{topic}{subtopic} -% which makes an entry in a two-level index such as the operation index. - -\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} -\def\singleindexer #1{\doind{\indexname}{#1}} - -% like the previous two, but they put @code around the argument. -\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} -\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} - -% Take care of Texinfo commands that can appear in an index entry. -% Since there are some commands we want to expand, and others we don't, -% we have to laboriously prevent expansion for those that we don't. -% -\def\indexdummies{% - \escapechar = `\\ % use backslash in output files. - \def\@{@}% change to @@ when we switch to @ as escape char in index files. - \def\ {\realbackslash\space }% - % - % Need these in case \tex is in effect and \{ is a \delimiter again. - % But can't use \lbracecmd and \rbracecmd because texindex assumes - % braces and backslashes are used only as delimiters. - \let\{ = \mylbrace - \let\} = \myrbrace - % - % I don't entirely understand this, but when an index entry is - % generated from a macro call, the \endinput which \scanmacro inserts - % causes processing to be prematurely terminated. This is, - % apparently, because \indexsorttmp is fully expanded, and \endinput - % is an expandable command. The redefinition below makes \endinput - % disappear altogether for that purpose -- although logging shows that - % processing continues to some further point. On the other hand, it - % seems \endinput does not hurt in the printed index arg, since that - % is still getting written without apparent harm. - % - % Sample source (mac-idx3.tex, reported by Graham Percival to - % help-texinfo, 22may06): - % @macro funindex {WORD} - % @findex xyz - % @end macro - % ... - % @funindex commtest - % - % The above is not enough to reproduce the bug, but it gives the flavor. - % - % Sample whatsit resulting: - % . at write3{\entry{xyz}{@folio }{@code {xyz at endinput }}} - % - % So: - \let\endinput = \empty - % - % Do the redefinitions. - \commondummies -} - -% For the aux and toc files, @ is the escape character. So we want to -% redefine everything using @ as the escape character (instead of -% \realbackslash, still used for index files). When everything uses @, -% this will be simpler. -% -\def\atdummies{% - \def\@{@@}% - \def\ {@ }% - \let\{ = \lbraceatcmd - \let\} = \rbraceatcmd - % - % Do the redefinitions. - \commondummies - \otherbackslash -} - -% Called from \indexdummies and \atdummies. -% -\def\commondummies{% - % - % \definedummyword defines \#1 as \string\#1\space, thus effectively - % preventing its expansion. This is used only for control% words, - % not control letters, because the \space would be incorrect for - % control characters, but is needed to separate the control word - % from whatever follows. - % - % For control letters, we have \definedummyletter, which omits the - % space. - % - % These can be used both for control words that take an argument and - % those that do not. If it is followed by {arg} in the input, then - % that will dutifully get written to the index (or wherever). - % - \def\definedummyword ##1{\def##1{\string##1\space}}% - \def\definedummyletter##1{\def##1{\string##1}}% - \let\definedummyaccent\definedummyletter - % - \commondummiesnofonts - % - \definedummyletter\_% - % - % Non-English letters. - \definedummyword\AA - \definedummyword\AE - \definedummyword\L - \definedummyword\OE - \definedummyword\O - \definedummyword\aa - \definedummyword\ae - \definedummyword\l - \definedummyword\oe - \definedummyword\o - \definedummyword\ss - \definedummyword\exclamdown - \definedummyword\questiondown - \definedummyword\ordf - \definedummyword\ordm - % - % Although these internal commands shouldn't show up, sometimes they do. - \definedummyword\bf - \definedummyword\gtr - \definedummyword\hat - \definedummyword\less - \definedummyword\sf - \definedummyword\sl - \definedummyword\tclose - \definedummyword\tt - % - \definedummyword\LaTeX - \definedummyword\TeX - % - % Assorted special characters. - \definedummyword\bullet - \definedummyword\comma - \definedummyword\copyright - \definedummyword\registeredsymbol - \definedummyword\dots - \definedummyword\enddots - \definedummyword\equiv - \definedummyword\error - \definedummyword\euro - \definedummyword\expansion - \definedummyword\minus - \definedummyword\pounds - \definedummyword\point - \definedummyword\print - \definedummyword\result - \definedummyword\textdegree - % - % We want to disable all macros so that they are not expanded by \write. - \macrolist - % - \normalturnoffactive - % - % Handle some cases of @value -- where it does not contain any - % (non-fully-expandable) commands. - \makevalueexpandable -} - -% \commondummiesnofonts: common to \commondummies and \indexnofonts. -% -\def\commondummiesnofonts{% - % Control letters and accents. - \definedummyletter\!% - \definedummyaccent\"% - \definedummyaccent\'% - \definedummyletter\*% - \definedummyaccent\,% - \definedummyletter\.% - \definedummyletter\/% - \definedummyletter\:% - \definedummyaccent\=% - \definedummyletter\?% - \definedummyaccent\^% - \definedummyaccent\`% - \definedummyaccent\~% - \definedummyword\u - \definedummyword\v - \definedummyword\H - \definedummyword\dotaccent - \definedummyword\ringaccent - \definedummyword\tieaccent - \definedummyword\ubaraccent - \definedummyword\udotaccent - \definedummyword\dotless - % - % Texinfo font commands. - \definedummyword\b - \definedummyword\i - \definedummyword\r - \definedummyword\sc - \definedummyword\t - % - % Commands that take arguments. - \definedummyword\acronym - \definedummyword\cite - \definedummyword\code - \definedummyword\command - \definedummyword\dfn - \definedummyword\emph - \definedummyword\env - \definedummyword\file - \definedummyword\kbd - \definedummyword\key - \definedummyword\math - \definedummyword\option - \definedummyword\pxref - \definedummyword\ref - \definedummyword\samp - \definedummyword\strong - \definedummyword\tie - \definedummyword\uref - \definedummyword\url - \definedummyword\var - \definedummyword\verb - \definedummyword\w - \definedummyword\xref -} - -% \indexnofonts is used when outputting the strings to sort the index -% by, and when constructing control sequence names. It eliminates all -% control sequences and just writes whatever the best ASCII sort string -% would be for a given command (usually its argument). -% -\def\indexnofonts{% - % Accent commands should become @asis. - \def\definedummyaccent##1{\let##1\asis}% - % We can just ignore other control letters. - \def\definedummyletter##1{\let##1\empty}% - % Hopefully, all control words can become @asis. - \let\definedummyword\definedummyaccent - % - \commondummiesnofonts - % - % Don't no-op \tt, since it isn't a user-level command - % and is used in the definitions of the active chars like <, >, |, etc. - % Likewise with the other plain tex font commands. - %\let\tt=\asis - % - \def\ { }% - \def\@{@}% - % how to handle braces? - \def\_{\normalunderscore}% - % - % Non-English letters. - \def\AA{AA}% - \def\AE{AE}% - \def\L{L}% - \def\OE{OE}% - \def\O{O}% - \def\aa{aa}% - \def\ae{ae}% - \def\l{l}% - \def\oe{oe}% - \def\o{o}% - \def\ss{ss}% - \def\exclamdown{!}% - \def\questiondown{?}% - \def\ordf{a}% - \def\ordm{o}% - % - \def\LaTeX{LaTeX}% - \def\TeX{TeX}% - % - % Assorted special characters. - % (The following {} will end up in the sort string, but that's ok.) - \def\bullet{bullet}% - \def\comma{,}% - \def\copyright{copyright}% - \def\registeredsymbol{R}% - \def\dots{...}% - \def\enddots{...}% - \def\equiv{==}% - \def\error{error}% - \def\euro{euro}% - \def\expansion{==>}% - \def\minus{-}% - \def\pounds{pounds}% - \def\point{.}% - \def\print{-|}% - \def\result{=>}% - \def\textdegree{degrees}% - % - % We need to get rid of all macros, leaving only the arguments (if present). - % Of course this is not nearly correct, but it is the best we can do for now. - % makeinfo does not expand macros in the argument to @deffn, which ends up - % writing an index entry, and texindex isn't prepared for an index sort entry - % that starts with \. - % - % Since macro invocations are followed by braces, we can just redefine them - % to take a single TeX argument. The case of a macro invocation that - % goes to end-of-line is not handled. - % - \macrolist -} - -\let\indexbackslash=0 %overridden during \printindex. -\let\SETmarginindex=\relax % put index entries in margin (undocumented)? - -% Most index entries go through here, but \dosubind is the general case. -% #1 is the index name, #2 is the entry text. -\def\doind#1#2{\dosubind{#1}{#2}{}} - -% Workhorse for all \fooindexes. -% #1 is name of index, #2 is stuff to put there, #3 is subentry -- -% empty if called from \doind, as we usually are (the main exception -% is with most defuns, which call us directly). -% -\def\dosubind#1#2#3{% - \iflinks - {% - % Store the main index entry text (including the third arg). - \toks0 = {#2}% - % If third arg is present, precede it with a space. - \def\thirdarg{#3}% - \ifx\thirdarg\empty \else - \toks0 = \expandafter{\the\toks0 \space #3}% - \fi - % - \edef\writeto{\csname#1indfile\endcsname}% - % - \ifvmode - \dosubindsanitize - \else - \dosubindwrite - \fi - }% - \fi -} - -% Write the entry in \toks0 to the index file: -% -\def\dosubindwrite{% - % Put the index entry in the margin if desired. - \ifx\SETmarginindex\relax\else - \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% - \fi - % - % Remember, we are within a group. - \indexdummies % Must do this here, since \bf, etc expand at this stage - \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now - % so it will be output as is; and it will print as backslash. - % - % Process the index entry with all font commands turned off, to - % get the string to sort by. - {\indexnofonts - \edef\temp{\the\toks0}% need full expansion - \xdef\indexsorttmp{\temp}% - }% - % - % Set up the complete index entry, with both the sort key and - % the original text, including any font commands. We write - % three arguments to \entry to the .?? file (four in the - % subentry case), texindex reduces to two when writing the .??s - % sorted result. - \edef\temp{% - \write\writeto{% - \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% - }% - \temp -} - -% Take care of unwanted page breaks: -% -% If a skip is the last thing on the list now, preserve it -% by backing up by \lastskip, doing the \write, then inserting -% the skip again. Otherwise, the whatsit generated by the -% \write will make \lastskip zero. The result is that sequences -% like this: -% @end defun -% @tindex whatever -% @defun ... -% will have extra space inserted, because the \medbreak in the -% start of the @defun won't see the skip inserted by the @end of -% the previous defun. -% -% But don't do any of this if we're not in vertical mode. We -% don't want to do a \vskip and prematurely end a paragraph. -% -% Avoid page breaks due to these extra skips, too. -% -% But wait, there is a catch there: -% We'll have to check whether \lastskip is zero skip. \ifdim is not -% sufficient for this purpose, as it ignores stretch and shrink parts -% of the skip. The only way seems to be to check the textual -% representation of the skip. -% -% The following is almost like \def\zeroskipmacro{0.0pt} except that -% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). -% -\edef\zeroskipmacro{\expandafter\the\csname z at skip\endcsname} -% -% ..., ready, GO: -% -\def\dosubindsanitize{% - % \lastskip and \lastpenalty cannot both be nonzero simultaneously. - \skip0 = \lastskip - \edef\lastskipmacro{\the\lastskip}% - \count255 = \lastpenalty - % - % If \lastskip is nonzero, that means the last item was a - % skip. And since a skip is discardable, that means this - % -\skip0 glue we're inserting is preceded by a - % non-discardable item, therefore it is not a potential - % breakpoint, therefore no \nobreak needed. - \ifx\lastskipmacro\zeroskipmacro - \else - \vskip-\skip0 - \fi - % - \dosubindwrite - % - \ifx\lastskipmacro\zeroskipmacro - % If \lastskip was zero, perhaps the last item was a penalty, and - % perhaps it was >=10000, e.g., a \nobreak. In that case, we want - % to re-insert the same penalty (values >10000 are used for various - % signals); since we just inserted a non-discardable item, any - % following glue (such as a \parskip) would be a breakpoint. For example: - % - % @deffn deffn-whatever - % @vindex index-whatever - % Description. - % would allow a break between the index-whatever whatsit - % and the "Description." paragraph. - \ifnum\count255>9999 \penalty\count255 \fi - \else - % On the other hand, if we had a nonzero \lastskip, - % this make-up glue would be preceded by a non-discardable item - % (the whatsit from the \write), so we must insert a \nobreak. - \nobreak\vskip\skip0 - \fi -} - -% The index entry written in the file actually looks like -% \entry {sortstring}{page}{topic} -% or -% \entry {sortstring}{page}{topic}{subtopic} -% The texindex program reads in these files and writes files -% containing these kinds of lines: -% \initial {c} -% before the first topic whose initial is c -% \entry {topic}{pagelist} -% for a topic that is used without subtopics -% \primary {topic} -% for the beginning of a topic that is used with subtopics -% \secondary {subtopic}{pagelist} -% for each subtopic. - -% Define the user-accessible indexing commands -% @findex, @vindex, @kindex, @cindex. - -\def\findex {\fnindex} -\def\kindex {\kyindex} -\def\cindex {\cpindex} -\def\vindex {\vrindex} -\def\tindex {\tpindex} -\def\pindex {\pgindex} - -\def\cindexsub {\begingroup\obeylines\cindexsub} -{\obeylines % -\gdef\cindexsub "#1" #2^^M{\endgroup % -\dosubind{cp}{#2}{#1}}} - -% Define the macros used in formatting output of the sorted index material. - -% @printindex causes a particular index (the ??s file) to get printed. -% It does not print any chapter heading (usually an @unnumbered). -% -\parseargdef\printindex{\begingroup - \dobreak \chapheadingskip{10000}% - % - \smallfonts \rm - \tolerance = 9500 - \everypar = {}% don't want the \kern\-parindent from indentation suppression. - % - % See if the index file exists and is nonempty. - % Change catcode of @ here so that if the index file contains - % \initial {@} - % as its first line, TeX doesn't complain about mismatched braces - % (because it thinks @} is a control sequence). - \catcode`\@ = 11 - \openin 1 \jobname.#1s - \ifeof 1 - % \enddoublecolumns gets confused if there is no text in the index, - % and it loses the chapter title and the aux file entries for the - % index. The easiest way to prevent this problem is to make sure - % there is some text. - \putwordIndexNonexistent - \else - % - % If the index file exists but is empty, then \openin leaves \ifeof - % false. We have to make TeX try to read something from the file, so - % it can discover if there is anything in it. - \read 1 to \temp - \ifeof 1 - \putwordIndexIsEmpty - \else - % Index files are almost Texinfo source, but we use \ as the escape - % character. It would be better to use @, but that's too big a change - % to make right now. - \def\indexbackslash{\backslashcurfont}% - \catcode`\\ = 0 - \escapechar = `\\ - \begindoublecolumns - \input \jobname.#1s - \enddoublecolumns - \fi - \fi - \closein 1 -\endgroup} - -% These macros are used by the sorted index file itself. -% Change them to control the appearance of the index. - -\def\initial#1{{% - % Some minor font changes for the special characters. - \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt - % - % Remove any glue we may have, we'll be inserting our own. - \removelastskip - % - % We like breaks before the index initials, so insert a bonus. - \nobreak - \vskip 0pt plus 3\baselineskip - \penalty 0 - \vskip 0pt plus -3\baselineskip - % - % Typeset the initial. Making this add up to a whole number of - % baselineskips increases the chance of the dots lining up from column - % to column. It still won't often be perfect, because of the stretch - % we need before each entry, but it's better. - % - % No shrink because it confuses \balancecolumns. - \vskip 1.67\baselineskip plus .5\baselineskip - \leftline{\secbf #1}% - % Do our best not to break after the initial. - \nobreak - \vskip .33\baselineskip plus .1\baselineskip -}} - -% \entry typesets a paragraph consisting of the text (#1), dot leaders, and -% then page number (#2) flushed to the right margin. It is used for index -% and table of contents entries. The paragraph is indented by \leftskip. -% -% A straightforward implementation would start like this: -% \def\entry#1#2{... -% But this frozes the catcodes in the argument, and can cause problems to -% @code, which sets - active. This problem was fixed by a kludge--- -% ``-'' was active throughout whole index, but this isn't really right. -% -% The right solution is to prevent \entry from swallowing the whole text. -% --kasal, 21nov03 -\def\entry{% - \begingroup - % - % Start a new paragraph if necessary, so our assignments below can't - % affect previous text. - \par - % - % Do not fill out the last line with white space. - \parfillskip = 0in - % - % No extra space above this paragraph. - \parskip = 0in - % - % Do not prefer a separate line ending with a hyphen to fewer lines. - \finalhyphendemerits = 0 - % - % \hangindent is only relevant when the entry text and page number - % don't both fit on one line. In that case, bob suggests starting the - % dots pretty far over on the line. Unfortunately, a large - % indentation looks wrong when the entry text itself is broken across - % lines. So we use a small indentation and put up with long leaders. - % - % \hangafter is reset to 1 (which is the value we want) at the start - % of each paragraph, so we need not do anything with that. - \hangindent = 2em - % - % When the entry text needs to be broken, just fill out the first line - % with blank space. - \rightskip = 0pt plus1fil - % - % A bit of stretch before each entry for the benefit of balancing - % columns. - \vskip 0pt plus1pt - % - % Swallow the left brace of the text (first parameter): - \afterassignment\doentry - \let\temp = -} -\def\doentry{% - \bgroup % Instead of the swallowed brace. - \noindent - \aftergroup\finishentry - % And now comes the text of the entry. -} -\def\finishentry#1{% - % #1 is the page number. - % - % The following is kludged to not output a line of dots in the index if - % there are no page numbers. The next person who breaks this will be - % cursed by a Unix daemon. - \def\tempa{{\rm }}% - \def\tempb{#1}% - \edef\tempc{\tempa}% - \edef\tempd{\tempb}% - \ifx\tempc\tempd - \ % - \else - % - % If we must, put the page number on a line of its own, and fill out - % this line with blank space. (The \hfil is overwhelmed with the - % fill leaders glue in \indexdotfill if the page number does fit.) - \hfil\penalty50 - \null\nobreak\indexdotfill % Have leaders before the page number. - % - % The `\ ' here is removed by the implicit \unskip that TeX does as - % part of (the primitive) \par. Without it, a spurious underfull - % \hbox ensues. - \ifpdf - \pdfgettoks#1.% - \ \the\toksA - \else - \ #1% - \fi - \fi - \par - \endgroup -} - -% Like plain.tex's \dotfill, except uses up at least 1 em. -\def\indexdotfill{\cleaders - \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} - -\def\primary #1{\line{#1\hfil}} - -\newskip\secondaryindent \secondaryindent=0.5cm -\def\secondary#1#2{{% - \parfillskip=0in - \parskip=0in - \hangindent=1in - \hangafter=1 - \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill - \ifpdf - \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. - \else - #2 - \fi - \par -}} - -% Define two-column mode, which we use to typeset indexes. -% Adapted from the TeXbook, page 416, which is to say, -% the manmac.tex format used to print the TeXbook itself. -\catcode`\@=11 - -\newbox\partialpage -\newdimen\doublecolumnhsize - -\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns - % Grab any single-column material above us. - \output = {% - % - % Here is a possibility not foreseen in manmac: if we accumulate a - % whole lot of material, we might end up calling this \output - % routine twice in a row (see the doublecol-lose test, which is - % essentially a couple of indexes with @setchapternewpage off). In - % that case we just ship out what is in \partialpage with the normal - % output routine. Generally, \partialpage will be empty when this - % runs and this will be a no-op. See the indexspread.tex test case. - \ifvoid\partialpage \else - \onepageout{\pagecontents\partialpage}% - \fi - % - \global\setbox\partialpage = \vbox{% - % Unvbox the main output page. - \unvbox\PAGE - \kern-\topskip \kern\baselineskip - }% - }% - \eject % run that output routine to set \partialpage - % - % Use the double-column output routine for subsequent pages. - \output = {\doublecolumnout}% - % - % Change the page size parameters. We could do this once outside this - % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 - % format, but then we repeat the same computation. Repeating a couple - % of assignments once per index is clearly meaningless for the - % execution time, so we may as well do it in one place. - % - % First we halve the line length, less a little for the gutter between - % the columns. We compute the gutter based on the line length, so it - % changes automatically with the paper format. The magic constant - % below is chosen so that the gutter has the same value (well, +-<1pt) - % as it did when we hard-coded it. - % - % We put the result in a separate register, \doublecolumhsize, so we - % can restore it in \pagesofar, after \hsize itself has (potentially) - % been clobbered. - % - \doublecolumnhsize = \hsize - \advance\doublecolumnhsize by -.04154\hsize - \divide\doublecolumnhsize by 2 - \hsize = \doublecolumnhsize - % - % Double the \vsize as well. (We don't need a separate register here, - % since nobody clobbers \vsize.) - \vsize = 2\vsize -} - -% The double-column output routine for all double-column pages except -% the last. -% -\def\doublecolumnout{% - \splittopskip=\topskip \splitmaxdepth=\maxdepth - % Get the available space for the double columns -- the normal - % (undoubled) page height minus any material left over from the - % previous page. - \dimen@ = \vsize - \divide\dimen@ by 2 - \advance\dimen@ by -\ht\partialpage - % - % box0 will be the left-hand column, box2 the right. - \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ - \onepageout\pagesofar - \unvbox255 - \penalty\outputpenalty -} -% -% Re-output the contents of the output page -- any previous material, -% followed by the two boxes we just split, in box0 and box2. -\def\pagesofar{% - \unvbox\partialpage - % - \hsize = \doublecolumnhsize - \wd0=\hsize \wd2=\hsize - \hbox to\pagewidth{\box0\hfil\box2}% -} -% -% All done with double columns. -\def\enddoublecolumns{% - \output = {% - % Split the last of the double-column material. Leave it on the - % current page, no automatic page break. - \balancecolumns - % - % If we end up splitting too much material for the current page, - % though, there will be another page break right after this \output - % invocation ends. Having called \balancecolumns once, we do not - % want to call it again. Therefore, reset \output to its normal - % definition right away. (We hope \balancecolumns will never be - % called on to balance too much material, but if it is, this makes - % the output somewhat more palatable.) - \global\output = {\onepageout{\pagecontents\PAGE}}% - }% - \eject - \endgroup % started in \begindoublecolumns - % - % \pagegoal was set to the doubled \vsize above, since we restarted - % the current page. We're now back to normal single-column - % typesetting, so reset \pagegoal to the normal \vsize (after the - % \endgroup where \vsize got restored). - \pagegoal = \vsize -} -% -% Called at the end of the double column material. -\def\balancecolumns{% - \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. - \dimen@ = \ht0 - \advance\dimen@ by \topskip - \advance\dimen@ by-\baselineskip - \divide\dimen@ by 2 % target to split to - %debug\message{final 2-column material height=\the\ht0, target=\the\dimen at .}% - \splittopskip = \topskip - % Loop until we get a decent breakpoint. - {% - \vbadness = 10000 - \loop - \global\setbox3 = \copy0 - \global\setbox1 = \vsplit3 to \dimen@ - \ifdim\ht3>\dimen@ - \global\advance\dimen@ by 1pt - \repeat - }% - %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% - \setbox0=\vbox to\dimen@{\unvbox1}% - \setbox2=\vbox to\dimen@{\unvbox3}% - % - \pagesofar -} -\catcode`\@ = \other - - -\message{sectioning,} -% Chapters, sections, etc. - -% \unnumberedno is an oxymoron, of course. But we count the unnumbered -% sections so that we can refer to them unambiguously in the pdf -% outlines by their "section number". We avoid collisions with chapter -% numbers by starting them at 10000. (If a document ever has 10000 -% chapters, we're in trouble anyway, I'm sure.) -\newcount\unnumberedno \unnumberedno = 10000 -\newcount\chapno -\newcount\secno \secno=0 -\newcount\subsecno \subsecno=0 -\newcount\subsubsecno \subsubsecno=0 - -% This counter is funny since it counts through charcodes of letters A, B, ... -\newcount\appendixno \appendixno = `\@ -% -% \def\appendixletter{\char\the\appendixno} -% We do the following ugly conditional instead of the above simple -% construct for the sake of pdftex, which needs the actual -% letter in the expansion, not just typeset. -% -\def\appendixletter{% - \ifnum\appendixno=`A A% - \else\ifnum\appendixno=`B B% - \else\ifnum\appendixno=`C C% - \else\ifnum\appendixno=`D D% - \else\ifnum\appendixno=`E E% - \else\ifnum\appendixno=`F F% - \else\ifnum\appendixno=`G G% - \else\ifnum\appendixno=`H H% - \else\ifnum\appendixno=`I I% - \else\ifnum\appendixno=`J J% - \else\ifnum\appendixno=`K K% - \else\ifnum\appendixno=`L L% - \else\ifnum\appendixno=`M M% - \else\ifnum\appendixno=`N N% - \else\ifnum\appendixno=`O O% - \else\ifnum\appendixno=`P P% - \else\ifnum\appendixno=`Q Q% - \else\ifnum\appendixno=`R R% - \else\ifnum\appendixno=`S S% - \else\ifnum\appendixno=`T T% - \else\ifnum\appendixno=`U U% - \else\ifnum\appendixno=`V V% - \else\ifnum\appendixno=`W W% - \else\ifnum\appendixno=`X X% - \else\ifnum\appendixno=`Y Y% - \else\ifnum\appendixno=`Z Z% - % The \the is necessary, despite appearances, because \appendixletter is - % expanded while writing the .toc file. \char\appendixno is not - % expandable, thus it is written literally, thus all appendixes come out - % with the same letter (or @) in the toc without it. - \else\char\the\appendixno - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} - -% Each @chapter defines this as the name of the chapter. -% page headings and footings can use it. @section does likewise. -% However, they are not reliable, because we don't use marks. -\def\thischapter{} -\def\thissection{} - -\newcount\absseclevel % used to calculate proper heading level -\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count - -% @raisesections: treat @section as chapter, @subsection as section, etc. -\def\raisesections{\global\advance\secbase by -1} -\let\up=\raisesections % original BFox name - -% @lowersections: treat @chapter as section, @section as subsection, etc. -\def\lowersections{\global\advance\secbase by 1} -\let\down=\lowersections % original BFox name - -% we only have subsub. -\chardef\maxseclevel = 3 -% -% A numbered section within an unnumbered changes to unnumbered too. -% To achive this, remember the "biggest" unnum. sec. we are currently in: -\chardef\unmlevel = \maxseclevel -% -% Trace whether the current chapter is an appendix or not: -% \chapheadtype is "N" or "A", unnumbered chapters are ignored. -\def\chapheadtype{N} - -% Choose a heading macro -% #1 is heading type -% #2 is heading level -% #3 is text for heading -\def\genhead#1#2#3{% - % Compute the abs. sec. level: - \absseclevel=#2 - \advance\absseclevel by \secbase - % Make sure \absseclevel doesn't fall outside the range: - \ifnum \absseclevel < 0 - \absseclevel = 0 - \else - \ifnum \absseclevel > 3 - \absseclevel = 3 - \fi - \fi - % The heading type: - \def\headtype{#1}% - \if \headtype U% - \ifnum \absseclevel < \unmlevel - \chardef\unmlevel = \absseclevel - \fi - \else - % Check for appendix sections: - \ifnum \absseclevel = 0 - \edef\chapheadtype{\headtype}% - \else - \if \headtype A\if \chapheadtype N% - \errmessage{@appendix... within a non-appendix chapter}% - \fi\fi - \fi - % Check for numbered within unnumbered: - \ifnum \absseclevel > \unmlevel - \def\headtype{U}% - \else - \chardef\unmlevel = 3 - \fi - \fi - % Now print the heading: - \if \headtype U% - \ifcase\absseclevel - \unnumberedzzz{#3}% - \or \unnumberedseczzz{#3}% - \or \unnumberedsubseczzz{#3}% - \or \unnumberedsubsubseczzz{#3}% - \fi - \else - \if \headtype A% - \ifcase\absseclevel - \appendixzzz{#3}% - \or \appendixsectionzzz{#3}% - \or \appendixsubseczzz{#3}% - \or \appendixsubsubseczzz{#3}% - \fi - \else - \ifcase\absseclevel - \chapterzzz{#3}% - \or \seczzz{#3}% - \or \numberedsubseczzz{#3}% - \or \numberedsubsubseczzz{#3}% - \fi - \fi - \fi - \suppressfirstparagraphindent -} - -% an interface: -\def\numhead{\genhead N} -\def\apphead{\genhead A} -\def\unnmhead{\genhead U} - -% @chapter, @appendix, @unnumbered. Increment top-level counter, reset -% all lower-level sectioning counters to zero. -% -% Also set \chaplevelprefix, which we prepend to @float sequence numbers -% (e.g., figures), q.v. By default (before any chapter), that is empty. -\let\chaplevelprefix = \empty -% -\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz -\def\chapterzzz#1{% - % section resetting is \global in case the chapter is in a group, such - % as an @include file. - \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 - \global\advance\chapno by 1 - % - % Used for \float. - \gdef\chaplevelprefix{\the\chapno.}% - \resetallfloatnos - % - \message{\putwordChapter\space \the\chapno}% - % - % Write the actual heading. - \chapmacro{#1}{Ynumbered}{\the\chapno}% - % - % So @section and the like are numbered underneath this chapter. - \global\let\section = \numberedsec - \global\let\subsection = \numberedsubsec - \global\let\subsubsection = \numberedsubsubsec -} - -\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz -\def\appendixzzz#1{% - \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 - \global\advance\appendixno by 1 - \gdef\chaplevelprefix{\appendixletter.}% - \resetallfloatnos - % - \def\appendixnum{\putwordAppendix\space \appendixletter}% - \message{\appendixnum}% - % - \chapmacro{#1}{Yappendix}{\appendixletter}% - % - \global\let\section = \appendixsec - \global\let\subsection = \appendixsubsec - \global\let\subsubsection = \appendixsubsubsec -} - -\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz -\def\unnumberedzzz#1{% - \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 - \global\advance\unnumberedno by 1 - % - % Since an unnumbered has no number, no prefix for figures. - \global\let\chaplevelprefix = \empty - \resetallfloatnos - % - % This used to be simply \message{#1}, but TeX fully expands the - % argument to \message. Therefore, if #1 contained @-commands, TeX - % expanded them. For example, in `@unnumbered The @cite{Book}', TeX - % expanded @cite (which turns out to cause errors because \cite is meant - % to be executed, not expanded). - % - % Anyway, we don't want the fully-expanded definition of @cite to appear - % as a result of the \message, we just want `@cite' itself. We use - % \the to achieve this: TeX expands \the only once, - % simply yielding the contents of . (We also do this for - % the toc entries.) - \toks0 = {#1}% - \message{(\the\toks0)}% - % - \chapmacro{#1}{Ynothing}{\the\unnumberedno}% - % - \global\let\section = \unnumberedsec - \global\let\subsection = \unnumberedsubsec - \global\let\subsubsection = \unnumberedsubsubsec -} - -% @centerchap is like @unnumbered, but the heading is centered. -\outer\parseargdef\centerchap{% - % Well, we could do the following in a group, but that would break - % an assumption that \chapmacro is called at the outermost level. - % Thus we are safer this way: --kasal, 24feb04 - \let\centerparametersmaybe = \centerparameters - \unnmhead0{#1}% - \let\centerparametersmaybe = \relax -} - -% @top is like @unnumbered. -\let\top\unnumbered - -% Sections. -\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz -\def\seczzz#1{% - \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 - \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% -} - -\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz -\def\appendixsectionzzz#1{% - \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 - \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% -} -\let\appendixsec\appendixsection - -\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz -\def\unnumberedseczzz#1{% - \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 - \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% -} - -% Subsections. -\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz -\def\numberedsubseczzz#1{% - \global\subsubsecno=0 \global\advance\subsecno by 1 - \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% -} - -\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz -\def\appendixsubseczzz#1{% - \global\subsubsecno=0 \global\advance\subsecno by 1 - \sectionheading{#1}{subsec}{Yappendix}% - {\appendixletter.\the\secno.\the\subsecno}% -} - -\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz -\def\unnumberedsubseczzz#1{% - \global\subsubsecno=0 \global\advance\subsecno by 1 - \sectionheading{#1}{subsec}{Ynothing}% - {\the\unnumberedno.\the\secno.\the\subsecno}% -} - -% Subsubsections. -\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz -\def\numberedsubsubseczzz#1{% - \global\advance\subsubsecno by 1 - \sectionheading{#1}{subsubsec}{Ynumbered}% - {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% -} - -\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz -\def\appendixsubsubseczzz#1{% - \global\advance\subsubsecno by 1 - \sectionheading{#1}{subsubsec}{Yappendix}% - {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% -} - -\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz -\def\unnumberedsubsubseczzz#1{% - \global\advance\subsubsecno by 1 - \sectionheading{#1}{subsubsec}{Ynothing}% - {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% -} - -% These macros control what the section commands do, according -% to what kind of chapter we are in (ordinary, appendix, or unnumbered). -% Define them by default for a numbered chapter. -\let\section = \numberedsec -\let\subsection = \numberedsubsec -\let\subsubsection = \numberedsubsubsec - -% Define @majorheading, @heading and @subheading - -% NOTE on use of \vbox for chapter headings, section headings, and such: -% 1) We use \vbox rather than the earlier \line to permit -% overlong headings to fold. -% 2) \hyphenpenalty is set to 10000 because hyphenation in a -% heading is obnoxious; this forbids it. -% 3) Likewise, headings look best if no \parindent is used, and -% if justification is not attempted. Hence \raggedright. - - -\def\majorheading{% - {\advance\chapheadingskip by 10pt \chapbreak }% - \parsearg\chapheadingzzz -} - -\def\chapheading{\chapbreak \parsearg\chapheadingzzz} -\def\chapheadingzzz#1{% - {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}% - \bigskip \par\penalty 200\relax - \suppressfirstparagraphindent -} - -% @heading, @subheading, @subsubheading. -\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} - \suppressfirstparagraphindent} -\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} - \suppressfirstparagraphindent} -\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} - \suppressfirstparagraphindent} - -% These macros generate a chapter, section, etc. heading only -% (including whitespace, linebreaking, etc. around it), -% given all the information in convenient, parsed form. - -%%% Args are the skip and penalty (usually negative) -\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} - -%%% Define plain chapter starts, and page on/off switching for it -% Parameter controlling skip before chapter headings (if needed) - -\newskip\chapheadingskip - -\def\chapbreak{\dobreak \chapheadingskip {-4000}} -\def\chappager{\par\vfill\supereject} -\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} - -\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} - -\def\CHAPPAGoff{% -\global\let\contentsalignmacro = \chappager -\global\let\pchapsepmacro=\chapbreak -\global\let\pagealignmacro=\chappager} - -\def\CHAPPAGon{% -\global\let\contentsalignmacro = \chappager -\global\let\pchapsepmacro=\chappager -\global\let\pagealignmacro=\chappager -\global\def\HEADINGSon{\HEADINGSsingle}} - -\def\CHAPPAGodd{% -\global\let\contentsalignmacro = \chapoddpage -\global\let\pchapsepmacro=\chapoddpage -\global\let\pagealignmacro=\chapoddpage -\global\def\HEADINGSon{\HEADINGSdouble}} - -\CHAPPAGon - -% Chapter opening. -% -% #1 is the text, #2 is the section type (Ynumbered, Ynothing, -% Yappendix, Yomitfromtoc), #3 the chapter number. -% -% To test against our argument. -\def\Ynothingkeyword{Ynothing} -\def\Yomitfromtockeyword{Yomitfromtoc} -\def\Yappendixkeyword{Yappendix} -% -\def\chapmacro#1#2#3{% - \pchapsepmacro - {% - \chapfonts \rm - % - % Have to define \thissection before calling \donoderef, because the - % xref code eventually uses it. On the other hand, it has to be called - % after \pchapsepmacro, or the headline will change too soon. - \gdef\thissection{#1}% - \gdef\thischaptername{#1}% - % - % Only insert the separating space if we have a chapter/appendix - % number, and don't print the unnumbered ``number''. - \def\temptype{#2}% - \ifx\temptype\Ynothingkeyword - \setbox0 = \hbox{}% - \def\toctype{unnchap}% - \gdef\thischapternum{}% - \gdef\thischapter{#1}% - \else\ifx\temptype\Yomitfromtockeyword - \setbox0 = \hbox{}% contents like unnumbered, but no toc entry - \def\toctype{omit}% - \gdef\thischapternum{}% - \gdef\thischapter{}% - \else\ifx\temptype\Yappendixkeyword - \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% - \def\toctype{app}% - \xdef\thischapternum{\appendixletter}% - % We don't substitute the actual chapter name into \thischapter - % because we don't want its macros evaluated now. And we don't - % use \thissection because that changes with each section. - % - \xdef\thischapter{\putwordAppendix{} \appendixletter: - \noexpand\thischaptername}% - \else - \setbox0 = \hbox{#3\enspace}% - \def\toctype{numchap}% - \xdef\thischapternum{\the\chapno}% - \xdef\thischapter{\putwordChapter{} \the\chapno: - \noexpand\thischaptername}% - \fi\fi\fi - % - % Write the toc entry for this chapter. Must come before the - % \donoderef, because we include the current node name in the toc - % entry, and \donoderef resets it to empty. - \writetocentry{\toctype}{#1}{#3}% - % - % For pdftex, we have to write out the node definition (aka, make - % the pdfdest) after any page break, but before the actual text has - % been typeset. If the destination for the pdf outline is after the - % text, then jumping from the outline may wind up with the text not - % being visible, for instance under high magnification. - \donoderef{#2}% - % - % Typeset the actual heading. - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent=\wd0 \centerparametersmaybe - \unhbox0 #1\par}% - }% - \nobreak\bigskip % no page break after a chapter title - \nobreak -} - -% @centerchap -- centered and unnumbered. -\let\centerparametersmaybe = \relax -\def\centerparameters{% - \advance\rightskip by 3\rightskip - \leftskip = \rightskip - \parfillskip = 0pt -} - - -% I don't think this chapter style is supported any more, so I'm not -% updating it with the new noderef stuff. We'll see. --karl, 11aug03. -% -\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} -% -\def\unnchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\nobreak -} -\def\chfopen #1#2{\chapoddpage {\chapfonts -\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% -\par\penalty 5000 % -} -\def\centerchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt - \hfill {\rm #1}\hfill}}\bigskip \par\nobreak -} -\def\CHAPFopen{% - \global\let\chapmacro=\chfopen - \global\let\centerchapmacro=\centerchfopen} - - -% Section titles. These macros combine the section number parts and -% call the generic \sectionheading to do the printing. -% -\newskip\secheadingskip -\def\secheadingbreak{\dobreak \secheadingskip{-1000}} - -% Subsection titles. -\newskip\subsecheadingskip -\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} - -% Subsubsection titles. -\def\subsubsecheadingskip{\subsecheadingskip} -\def\subsubsecheadingbreak{\subsecheadingbreak} - - -% Print any size, any type, section title. -% -% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is -% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the -% section number. -% -\def\sectionheading#1#2#3#4{% - {% - % Switch to the right set of fonts. - \csname #2fonts\endcsname \rm - % - % Insert space above the heading. - \csname #2headingbreak\endcsname - % - % Only insert the space after the number if we have a section number. - \def\sectionlevel{#2}% - \def\temptype{#3}% - % - \ifx\temptype\Ynothingkeyword - \setbox0 = \hbox{}% - \def\toctype{unn}% - \gdef\thissection{#1}% - \else\ifx\temptype\Yomitfromtockeyword - % for @headings -- no section number, don't include in toc, - % and don't redefine \thissection. - \setbox0 = \hbox{}% - \def\toctype{omit}% - \let\sectionlevel=\empty - \else\ifx\temptype\Yappendixkeyword - \setbox0 = \hbox{#4\enspace}% - \def\toctype{app}% - \gdef\thissection{#1}% - \else - \setbox0 = \hbox{#4\enspace}% - \def\toctype{num}% - \gdef\thissection{#1}% - \fi\fi\fi - % - % Write the toc entry (before \donoderef). See comments in \chapmacro. - \writetocentry{\toctype\sectionlevel}{#1}{#4}% - % - % Write the node reference (= pdf destination for pdftex). - % Again, see comments in \chapmacro. - \donoderef{#3}% - % - % Interline glue will be inserted when the vbox is completed. - % That glue will be a valid breakpoint for the page, since it'll be - % preceded by a whatsit (usually from the \donoderef, or from the - % \writetocentry if there was no node). We don't want to allow that - % break, since then the whatsits could end up on page n while the - % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. - \nobreak - % - % Output the actual section heading. - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent=\wd0 % zero if no section number - \unhbox0 #1}% - }% - % Add extra space after the heading -- half of whatever came above it. - % Don't allow stretch, though. - \kern .5 \csname #2headingskip\endcsname - % - % Do not let the kern be a potential breakpoint, as it would be if it - % was followed by glue. - \nobreak - % - % We'll almost certainly start a paragraph next, so don't let that - % glue accumulate. (Not a breakpoint because it's preceded by a - % discardable item.) - \vskip-\parskip - % - % This is purely so the last item on the list is a known \penalty > - % 10000. This is so \startdefun can avoid allowing breakpoints after - % section headings. Otherwise, it would insert a valid breakpoint between: - % - % @section sec-whatever - % @deffn def-whatever - \penalty 10001 -} - - -\message{toc,} -% Table of contents. -\newwrite\tocfile - -% Write an entry to the toc file, opening it if necessary. -% Called from @chapter, etc. -% -% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} -% We append the current node name (if any) and page number as additional -% arguments for the \{chap,sec,...}entry macros which will eventually -% read this. The node name is used in the pdf outlines as the -% destination to jump to. -% -% We open the .toc file for writing here instead of at @setfilename (or -% any other fixed time) so that @contents can be anywhere in the document. -% But if #1 is `omit', then we don't do anything. This is used for the -% table of contents chapter openings themselves. -% -\newif\iftocfileopened -\def\omitkeyword{omit}% -% -\def\writetocentry#1#2#3{% - \edef\writetoctype{#1}% - \ifx\writetoctype\omitkeyword \else - \iftocfileopened\else - \immediate\openout\tocfile = \jobname.toc - \global\tocfileopenedtrue - \fi - % - \iflinks - {\atdummies - \edef\temp{% - \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% - \temp - }% - \fi - \fi - % - % Tell \shipout to create a pdf destination on each page, if we're - % writing pdf. These are used in the table of contents. We can't - % just write one on every page because the title pages are numbered - % 1 and 2 (the page numbers aren't printed), and so are the first - % two pages of the document. Thus, we'd have two destinations named - % `1', and two named `2'. - \ifpdf \global\pdfmakepagedesttrue \fi -} - - -% These characters do not print properly in the Computer Modern roman -% fonts, so we must take special care. This is more or less redundant -% with the Texinfo input format setup at the end of this file. -% -\def\activecatcodes{% - \catcode`\"=\active - \catcode`\$=\active - \catcode`\<=\active - \catcode`\>=\active - \catcode`\\=\active - \catcode`\^=\active - \catcode`\_=\active - \catcode`\|=\active - \catcode`\~=\active -} - - -% Read the toc file, which is essentially Texinfo input. -\def\readtocfile{% - \setupdatafile - \activecatcodes - \input \jobname.toc -} - -\newskip\contentsrightmargin \contentsrightmargin=1in -\newcount\savepageno -\newcount\lastnegativepageno \lastnegativepageno = -1 - -% Prepare to read what we've written to \tocfile. -% -\def\startcontents#1{% - % If @setchapternewpage on, and @headings double, the contents should - % start on an odd page, unlike chapters. Thus, we maintain - % \contentsalignmacro in parallel with \pagealignmacro. - % From: Torbjorn Granlund - \contentsalignmacro - \immediate\closeout\tocfile - % - % Don't need to put `Contents' or `Short Contents' in the headline. - % It is abundantly clear what they are. - \def\thischapter{}% - \chapmacro{#1}{Yomitfromtoc}{}% - % - \savepageno = \pageno - \begingroup % Set up to handle contents files properly. - \raggedbottom % Worry more about breakpoints than the bottom. - \advance\hsize by -\contentsrightmargin % Don't use the full line length. - % - % Roman numerals for page numbers. - \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi -} - - -% Normal (long) toc. -\def\contents{% - \startcontents{\putwordTOC}% - \openin 1 \jobname.toc - \ifeof 1 \else - \readtocfile - \fi - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \ifeof 1 \else - \pdfmakeoutlines - \fi - \closein 1 - \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno -} - -% And just the chapters. -\def\summarycontents{% - \startcontents{\putwordShortTOC}% - % - \let\numchapentry = \shortchapentry - \let\appentry = \shortchapentry - \let\unnchapentry = \shortunnchapentry - % We want a true roman here for the page numbers. - \secfonts - \let\rm=\shortcontrm \let\bf=\shortcontbf - \let\sl=\shortcontsl \let\tt=\shortconttt - \rm - \hyphenpenalty = 10000 - \advance\baselineskip by 1pt % Open it up a little. - \def\numsecentry##1##2##3##4{} - \let\appsecentry = \numsecentry - \let\unnsecentry = \numsecentry - \let\numsubsecentry = \numsecentry - \let\appsubsecentry = \numsecentry - \let\unnsubsecentry = \numsecentry - \let\numsubsubsecentry = \numsecentry - \let\appsubsubsecentry = \numsecentry - \let\unnsubsubsecentry = \numsecentry - \openin 1 \jobname.toc - \ifeof 1 \else - \readtocfile - \fi - \closein 1 - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno -} -\let\shortcontents = \summarycontents - -% Typeset the label for a chapter or appendix for the short contents. -% The arg is, e.g., `A' for an appendix, or `3' for a chapter. -% -\def\shortchaplabel#1{% - % This space should be enough, since a single number is .5em, and the - % widest letter (M) is 1em, at least in the Computer Modern fonts. - % But use \hss just in case. - % (This space doesn't include the extra space that gets added after - % the label; that gets put in by \shortchapentry above.) - % - % We'd like to right-justify chapter numbers, but that looks strange - % with appendix letters. And right-justifying numbers and - % left-justifying letters looks strange when there is less than 10 - % chapters. Have to read the whole toc once to know how many chapters - % there are before deciding ... - \hbox to 1em{#1\hss}% -} - -% These macros generate individual entries in the table of contents. -% The first argument is the chapter or section name. -% The last argument is the page number. -% The arguments in between are the chapter number, section number, ... - -% Chapters, in the main contents. -\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} -% -% Chapters, in the short toc. -% See comments in \dochapentry re vbox and related settings. -\def\shortchapentry#1#2#3#4{% - \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% -} - -% Appendices, in the main contents. -% Need the word Appendix, and a fixed-size box. -% -\def\appendixbox#1{% - % We use M since it's probably the widest letter. - \setbox0 = \hbox{\putwordAppendix{} M}% - \hbox to \wd0{\putwordAppendix{} #1\hss}} -% -\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} - -% Unnumbered chapters. -\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} -\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} - -% Sections. -\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} -\let\appsecentry=\numsecentry -\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} - -% Subsections. -\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} -\let\appsubsecentry=\numsubsecentry -\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} - -% And subsubsections. -\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} -\let\appsubsubsecentry=\numsubsubsecentry -\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} - -% This parameter controls the indentation of the various levels. -% Same as \defaultparindent. -\newdimen\tocindent \tocindent = 15pt - -% Now for the actual typesetting. In all these, #1 is the text and #2 is the -% page number. -% -% If the toc has to be broken over pages, we want it to be at chapters -% if at all possible; hence the \penalty. -\def\dochapentry#1#2{% - \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip - \begingroup - \chapentryfonts - \tocentry{#1}{\dopageno\bgroup#2\egroup}% - \endgroup - \nobreak\vskip .25\baselineskip plus.1\baselineskip -} - -\def\dosecentry#1#2{\begingroup - \secentryfonts \leftskip=\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -\def\dosubsecentry#1#2{\begingroup - \subsecentryfonts \leftskip=2\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -\def\dosubsubsecentry#1#2{\begingroup - \subsubsecentryfonts \leftskip=3\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -% We use the same \entry macro as for the index entries. -\let\tocentry = \entry - -% Space between chapter (or whatever) number and the title. -\def\labelspace{\hskip1em \relax} - -\def\dopageno#1{{\rm #1}} -\def\doshortpageno#1{{\rm #1}} - -\def\chapentryfonts{\secfonts \rm} -\def\secentryfonts{\textfonts} -\def\subsecentryfonts{\textfonts} -\def\subsubsecentryfonts{\textfonts} - - -\message{environments,} -% @foo ... @end foo. - -% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. -% -% Since these characters are used in examples, it should be an even number of -% \tt widths. Each \tt character is 1en, so two makes it 1em. -% -\def\point{$\star$} -\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} -\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} -\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} -\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} - -% The @error{} command. -% Adapted from the TeXbook's \boxit. -% -\newbox\errorbox -% -{\tentt \global\dimen0 = 3em}% Width of the box. -\dimen2 = .55pt % Thickness of rules -% The text. (`r' is open on the right, `e' somewhat less so on the left.) -\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt} -% -\setbox\errorbox=\hbox to \dimen0{\hfil - \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. - \advance\hsize by -2\dimen2 % Rules. - \vbox{% - \hrule height\dimen2 - \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. - \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. - \kern3pt\vrule width\dimen2}% Space to right. - \hrule height\dimen2} - \hfil} -% -\def\error{\leavevmode\lower.7ex\copy\errorbox} - -% @tex ... @end tex escapes into raw Tex temporarily. -% One exception: @ is still an escape character, so that @end tex works. -% But \@ or @@ will get a plain tex @ character. - -\envdef\tex{% - \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 - \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 - \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie - \catcode `\%=14 - \catcode `\+=\other - \catcode `\"=\other - \catcode `\|=\other - \catcode `\<=\other - \catcode `\>=\other - \escapechar=`\\ - % - \let\b=\ptexb - \let\bullet=\ptexbullet - \let\c=\ptexc - \let\,=\ptexcomma - \let\.=\ptexdot - \let\dots=\ptexdots - \let\equiv=\ptexequiv - \let\!=\ptexexclam - \let\i=\ptexi - \let\indent=\ptexindent - \let\noindent=\ptexnoindent - \let\{=\ptexlbrace - \let\+=\tabalign - \let\}=\ptexrbrace - \let\/=\ptexslash - \let\*=\ptexstar - \let\t=\ptext - \let\frenchspacing=\plainfrenchspacing - % - \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% - \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% - \def\@{@}% -} -% There is no need to define \Etex. - -% Define @lisp ... @end lisp. -% @lisp environment forms a group so it can rebind things, -% including the definition of @end lisp (which normally is erroneous). - -% Amount to narrow the margins by for @lisp. -\newskip\lispnarrowing \lispnarrowing=0.4in - -% This is the definition that ^^M gets inside @lisp, @example, and other -% such environments. \null is better than a space, since it doesn't -% have any width. -\def\lisppar{\null\endgraf} - -% This space is always present above and below environments. -\newskip\envskipamount \envskipamount = 0pt - -% Make spacing and below environment symmetrical. We use \parskip here -% to help in doing that, since in @example-like environments \parskip -% is reset to zero; thus the \afterenvbreak inserts no space -- but the -% start of the next paragraph will insert \parskip. -% -\def\aboveenvbreak{{% - % =10000 instead of <10000 because of a special case in \itemzzz and - % \sectionheading, q.v. - \ifnum \lastpenalty=10000 \else - \advance\envskipamount by \parskip - \endgraf - \ifdim\lastskip<\envskipamount - \removelastskip - % it's not a good place to break if the last penalty was \nobreak - % or better ... - \ifnum\lastpenalty<10000 \penalty-50 \fi - \vskip\envskipamount - \fi - \fi -}} - -\let\afterenvbreak = \aboveenvbreak - -% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will -% also clear it, so that its embedded environments do the narrowing again. -\let\nonarrowing=\relax - -% @cartouche ... @end cartouche: draw rectangle w/rounded corners around -% environment contents. -\font\circle=lcircle10 -\newdimen\circthick -\newdimen\cartouter\newdimen\cartinner -\newskip\normbskip\newskip\normpskip\newskip\normlskip -\circthick=\fontdimen8\circle -% -\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth -\def\ctr{{\hskip 6pt\circle\char'010}} -\def\cbl{{\circle\char'012\hskip -6pt}} -\def\cbr{{\hskip 6pt\circle\char'011}} -\def\carttop{\hbox to \cartouter{\hskip\lskip - \ctl\leaders\hrule height\circthick\hfil\ctr - \hskip\rskip}} -\def\cartbot{\hbox to \cartouter{\hskip\lskip - \cbl\leaders\hrule height\circthick\hfil\cbr - \hskip\rskip}} -% -\newskip\lskip\newskip\rskip - -\envdef\cartouche{% - \ifhmode\par\fi % can't be in the midst of a paragraph. - \startsavinginserts - \lskip=\leftskip \rskip=\rightskip - \leftskip=0pt\rightskip=0pt % we want these *outside*. - \cartinner=\hsize \advance\cartinner by-\lskip - \advance\cartinner by-\rskip - \cartouter=\hsize - \advance\cartouter by 18.4pt % allow for 3pt kerns on either - % side, and for 6pt waste from - % each corner char, and rule thickness - \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip - % Flag to tell @lisp, etc., not to narrow margin. - \let\nonarrowing = t% - \vbox\bgroup - \baselineskip=0pt\parskip=0pt\lineskip=0pt - \carttop - \hbox\bgroup - \hskip\lskip - \vrule\kern3pt - \vbox\bgroup - \kern3pt - \hsize=\cartinner - \baselineskip=\normbskip - \lineskip=\normlskip - \parskip=\normpskip - \vskip -\parskip - \comment % For explanation, see the end of \def\group. -} -\def\Ecartouche{% - \ifhmode\par\fi - \kern3pt - \egroup - \kern3pt\vrule - \hskip\rskip - \egroup - \cartbot - \egroup - \checkinserts -} - - -% This macro is called at the beginning of all the @example variants, -% inside a group. -\def\nonfillstart{% - \aboveenvbreak - \hfuzz = 12pt % Don't be fussy - \sepspaces % Make spaces be word-separators rather than space tokens. - \let\par = \lisppar % don't ignore blank lines - \obeylines % each line of input is a line of output - \parskip = 0pt - \parindent = 0pt - \emergencystretch = 0pt % don't try to avoid overfull boxes - \ifx\nonarrowing\relax - \advance \leftskip by \lispnarrowing - \exdentamount=\lispnarrowing - \else - \let\nonarrowing = \relax - \fi - \let\exdent=\nofillexdent -} - -% If you want all examples etc. small: @set dispenvsize small. -% If you want even small examples the full size: @set dispenvsize nosmall. -% This affects the following displayed environments: -% @example, @display, @format, @lisp -% -\def\smallword{small} -\def\nosmallword{nosmall} -\let\SETdispenvsize\relax -\def\setnormaldispenv{% - \ifx\SETdispenvsize\smallword - \smallexamplefonts \rm - \fi -} -\def\setsmalldispenv{% - \ifx\SETdispenvsize\nosmallword - \else - \smallexamplefonts \rm - \fi -} - -% We often define two environments, @foo and @smallfoo. -% Let's do it by one command: -\def\makedispenv #1#2{ - \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2} - \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2} - \expandafter\let\csname E#1\endcsname \afterenvbreak - \expandafter\let\csname Esmall#1\endcsname \afterenvbreak -} - -% Define two synonyms: -\def\maketwodispenvs #1#2#3{ - \makedispenv{#1}{#3} - \makedispenv{#2}{#3} -} - -% @lisp: indented, narrowed, typewriter font; @example: same as @lisp. -% -% @smallexample and @smalllisp: use smaller fonts. -% Originally contributed by Pavel at xerox. -% -\maketwodispenvs {lisp}{example}{% - \nonfillstart - \tt\quoteexpand - \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return -} -% @display/@smalldisplay: same as @lisp except keep current font. -% -\makedispenv {display}{% - \nonfillstart - \gobble -} - -% @format/@smallformat: same as @display except don't narrow margins. -% -\makedispenv{format}{% - \let\nonarrowing = t% - \nonfillstart - \gobble -} - -% @flushleft: same as @format, but doesn't obey \SETdispenvsize. -\envdef\flushleft{% - \let\nonarrowing = t% - \nonfillstart - \gobble -} -\let\Eflushleft = \afterenvbreak - -% @flushright. -% -\envdef\flushright{% - \let\nonarrowing = t% - \nonfillstart - \advance\leftskip by 0pt plus 1fill - \gobble -} -\let\Eflushright = \afterenvbreak - - -% @quotation does normal linebreaking (hence we can't use \nonfillstart) -% and narrows the margins. We keep \parskip nonzero in general, since -% we're doing normal filling. So, when using \aboveenvbreak and -% \afterenvbreak, temporarily make \parskip 0. -% -\envdef\quotation{% - {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip - \parindent=0pt - % - % @cartouche defines \nonarrowing to inhibit narrowing at next level down. - \ifx\nonarrowing\relax - \advance\leftskip by \lispnarrowing - \advance\rightskip by \lispnarrowing - \exdentamount = \lispnarrowing - \else - \let\nonarrowing = \relax - \fi - \parsearg\quotationlabel -} - -% We have retained a nonzero parskip for the environment, since we're -% doing normal filling. -% -\def\Equotation{% - \par - \ifx\quotationauthor\undefined\else - % indent a bit. - \leftline{\kern 2\leftskip \sl ---\quotationauthor}% - \fi - {\parskip=0pt \afterenvbreak}% -} - -% If we're given an argument, typeset it in bold with a colon after. -\def\quotationlabel#1{% - \def\temp{#1}% - \ifx\temp\empty \else - {\bf #1: }% - \fi -} - - -% LaTeX-like @verbatim... at end verbatim and @verb{...} -% If we want to allow any as delimiter, -% we need the curly braces so that makeinfo sees the @verb command, eg: -% `@verbx...x' would look like the '@verbx' command. --janneke at gnu.org -% -% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. -% -% [Knuth] p.344; only we need to do the other characters Texinfo sets -% active too. Otherwise, they get lost as the first character on a -% verbatim line. -\def\dospecials{% - \do\ \do\\\do\{\do\}\do\$\do\&% - \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% - \do\<\do\>\do\|\do\@\do+\do\"% -} -% -% [Knuth] p. 380 -\def\uncatcodespecials{% - \def\do##1{\catcode`##1=\other}\dospecials} -% -% [Knuth] pp. 380,381,391 -% Disable Spanish ligatures ?` and !` of \tt font -\begingroup - \catcode`\`=\active\gdef`{\relax\lq} -\endgroup -% -% Setup for the @verb command. -% -% Eight spaces for a tab -\begingroup - \catcode`\^^I=\active - \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} -\endgroup -% -\def\setupverb{% - \tt % easiest (and conventionally used) font for verbatim - \def\par{\leavevmode\endgraf}% - \catcode`\`=\active - \tabeightspaces - % Respect line breaks, - % print special symbols as themselves, and - % make each space count - % must do in this order: - \obeylines \uncatcodespecials \sepspaces -} - -% Setup for the @verbatim environment -% -% Real tab expansion -\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount -% -\def\starttabbox{\setbox0=\hbox\bgroup} - -% Allow an option to not replace quotes with a regular directed right -% quote/apostrophe (char 0x27), but instead use the undirected quote -% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it -% the default, but it works for pasting with more pdf viewers (at least -% evince), the lilypond developers report. xpdf does work with the -% regular 0x27. -% -\def\codequoteright{% - \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax - '% - \else - \char'15 - \fi -} -% -% and a similar option for the left quote char vs. a grave accent. -% Modern fonts display ASCII 0x60 as a grave accent, so some people like -% the code environments to do likewise. -% -\def\codequoteleft{% - \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax - `% - \else - \char'22 - \fi -} -% -\begingroup - \catcode`\^^I=\active - \gdef\tabexpand{% - \catcode`\^^I=\active - \def^^I{\leavevmode\egroup - \dimen0=\wd0 % the width so far, or since the previous tab - \divide\dimen0 by\tabw - \multiply\dimen0 by\tabw % compute previous multiple of \tabw - \advance\dimen0 by\tabw % advance to next multiple of \tabw - \wd0=\dimen0 \box0 \starttabbox - }% - } - \catcode`\'=\active - \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}% - % - \catcode`\`=\active - \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}% - % - \gdef\quoteexpand{\rquoteexpand \lquoteexpand}% -\endgroup - -% start the verbatim environment. -\def\setupverbatim{% - \let\nonarrowing = t% - \nonfillstart - % Easiest (and conventionally used) font for verbatim - \tt - \def\par{\leavevmode\egroup\box0\endgraf}% - \catcode`\`=\active - \tabexpand - \quoteexpand - % Respect line breaks, - % print special symbols as themselves, and - % make each space count - % must do in this order: - \obeylines \uncatcodespecials \sepspaces - \everypar{\starttabbox}% -} - -% Do the @verb magic: verbatim text is quoted by unique -% delimiter characters. Before first delimiter expect a -% right brace, after last delimiter expect closing brace: -% -% \def\doverb'{'#1'}'{#1} -% -% [Knuth] p. 382; only eat outer {} -\begingroup - \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other - \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] -\endgroup -% -\def\verb{\begingroup\setupverb\doverb} -% -% -% Do the @verbatim magic: define the macro \doverbatim so that -% the (first) argument ends when '@end verbatim' is reached, ie: -% -% \def\doverbatim#1 at end verbatim{#1} -% -% For Texinfo it's a lot easier than for LaTeX, -% because texinfo's \verbatim doesn't stop at '\end{verbatim}': -% we need not redefine '\', '{' and '}'. -% -% Inspired by LaTeX's verbatim command set [latex.ltx] -% -\begingroup - \catcode`\ =\active - \obeylines % - % ignore everything up to the first ^^M, that's the newline at the end - % of the @verbatim input line itself. Otherwise we get an extra blank - % line in the output. - \xdef\doverbatim#1^^M#2 at end verbatim{#2\noexpand\end\gobble verbatim}% - % We really want {...\end verbatim} in the body of the macro, but - % without the active space; thus we have to use \xdef and \gobble. -\endgroup -% -\envdef\verbatim{% - \setupverbatim\doverbatim -} -\let\Everbatim = \afterenvbreak - - -% @verbatiminclude FILE - insert text of file in verbatim environment. -% -\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} -% -\def\doverbatiminclude#1{% - {% - \makevalueexpandable - \setupverbatim - \input #1 - \afterenvbreak - }% -} - -% @copying ... @end copying. -% Save the text away for @insertcopying later. -% -% We save the uninterpreted tokens, rather than creating a box. -% Saving the text in a box would be much easier, but then all the -% typesetting commands (@smallbook, font changes, etc.) have to be done -% beforehand -- and a) we want @copying to be done first in the source -% file; b) letting users define the frontmatter in as flexible order as -% possible is very desirable. -% -\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} -\def\docopying#1 at end copying{\endgroup\def\copyingtext{#1}} -% -\def\insertcopying{% - \begingroup - \parindent = 0pt % paragraph indentation looks wrong on title page - \scanexp\copyingtext - \endgroup -} - -\message{defuns,} -% @defun etc. - -\newskip\defbodyindent \defbodyindent=.4in -\newskip\defargsindent \defargsindent=50pt -\newskip\deflastargmargin \deflastargmargin=18pt - -% Start the processing of @deffn: -\def\startdefun{% - \ifnum\lastpenalty<10000 - \medbreak - \else - % If there are two @def commands in a row, we'll have a \nobreak, - % which is there to keep the function description together with its - % header. But if there's nothing but headers, we need to allow a - % break somewhere. Check specifically for penalty 10002, inserted - % by \defargscommonending, instead of 10000, since the sectioning - % commands also insert a nobreak penalty, and we don't want to allow - % a break between a section heading and a defun. - % - \ifnum\lastpenalty=10002 \penalty2000 \fi - % - % Similarly, after a section heading, do not allow a break. - % But do insert the glue. - \medskip % preceded by discardable penalty, so not a breakpoint - \fi - % - \parindent=0in - \advance\leftskip by \defbodyindent - \exdentamount=\defbodyindent -} - -\def\dodefunx#1{% - % First, check whether we are in the right environment: - \checkenv#1% - % - % As above, allow line break if we have multiple x headers in a row. - % It's not a great place, though. - \ifnum\lastpenalty=10002 \penalty3000 \fi - % - % And now, it's time to reuse the body of the original defun: - \expandafter\gobbledefun#1% -} -\def\gobbledefun#1\startdefun{} - -% \printdefunline \deffnheader{text} -% -\def\printdefunline#1#2{% - \begingroup - % call \deffnheader: - #1#2 \endheader - % common ending: - \interlinepenalty = 10000 - \advance\rightskip by 0pt plus 1fil - \endgraf - \nobreak\vskip -\parskip - \penalty 10002 % signal to \startdefun and \dodefunx - % Some of the @defun-type tags do not enable magic parentheses, - % rendering the following check redundant. But we don't optimize. - \checkparencounts - \endgroup -} - -\def\Edefun{\endgraf\medbreak} - -% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; -% the only thing remainnig is to define \deffnheader. -% -\def\makedefun#1{% - \expandafter\let\csname E#1\endcsname = \Edefun - \edef\temp{\noexpand\domakedefun - \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% - \temp -} - -% \domakedefun \deffn \deffnx \deffnheader -% -% Define \deffn and \deffnx, without parameters. -% \deffnheader has to be defined explicitly. -% -\def\domakedefun#1#2#3{% - \envdef#1{% - \startdefun - \parseargusing\activeparens{\printdefunline#3}% - }% - \def#2{\dodefunx#1}% - \def#3% -} - -%%% Untyped functions: - -% @deffn category name args -\makedefun{deffn}{\deffngeneral{}} - -% @deffn category class name args -\makedefun{defop}#1 {\defopon{#1\ \putwordon}} - -% \defopon {category on}class name args -\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } - -% \deffngeneral {subind}category name args -% -\def\deffngeneral#1#2 #3 #4\endheader{% - % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. - \dosubind{fn}{\code{#3}}{#1}% - \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% -} - -%%% Typed functions: - -% @deftypefn category type name args -\makedefun{deftypefn}{\deftypefngeneral{}} - -% @deftypeop category class type name args -\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} - -% \deftypeopon {category on}class type name args -\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } - -% \deftypefngeneral {subind}category type name args -% -\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% - \dosubind{fn}{\code{#4}}{#1}% - \defname{#2}{#3}{#4}\defunargs{#5\unskip}% -} - -%%% Typed variables: - -% @deftypevr category type var args -\makedefun{deftypevr}{\deftypecvgeneral{}} - -% @deftypecv category class type var args -\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} - -% \deftypecvof {category of}class type var args -\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } - -% \deftypecvgeneral {subind}category type var args -% -\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% - \dosubind{vr}{\code{#4}}{#1}% - \defname{#2}{#3}{#4}\defunargs{#5\unskip}% -} - -%%% Untyped variables: - -% @defvr category var args -\makedefun{defvr}#1 {\deftypevrheader{#1} {} } - -% @defcv category class var args -\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} - -% \defcvof {category of}class var args -\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } - -%%% Type: -% @deftp category name args -\makedefun{deftp}#1 #2 #3\endheader{% - \doind{tp}{\code{#2}}% - \defname{#1}{}{#2}\defunargs{#3\unskip}% -} - -% Remaining @defun-like shortcuts: -\makedefun{defun}{\deffnheader{\putwordDeffunc} } -\makedefun{defmac}{\deffnheader{\putwordDefmac} } -\makedefun{defspec}{\deffnheader{\putwordDefspec} } -\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } -\makedefun{defvar}{\defvrheader{\putwordDefvar} } -\makedefun{defopt}{\defvrheader{\putwordDefopt} } -\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } -\makedefun{defmethod}{\defopon\putwordMethodon} -\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} -\makedefun{defivar}{\defcvof\putwordInstanceVariableof} -\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} - -% \defname, which formats the name of the @def (not the args). -% #1 is the category, such as "Function". -% #2 is the return type, if any. -% #3 is the function name. -% -% We are followed by (but not passed) the arguments, if any. -% -\def\defname#1#2#3{% - % Get the values of \leftskip and \rightskip as they were outside the @def... - \advance\leftskip by -\defbodyindent - % - % How we'll format the type name. Putting it in brackets helps - % distinguish it from the body text that may end up on the next line - % just below it. - \def\temp{#1}% - \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} - % - % Figure out line sizes for the paragraph shape. - % The first line needs space for \box0; but if \rightskip is nonzero, - % we need only space for the part of \box0 which exceeds it: - \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip - % The continuations: - \dimen2=\hsize \advance\dimen2 by -\defargsindent - % (plain.tex says that \dimen1 should be used only as global.) - \parshape 2 0in \dimen0 \defargsindent \dimen2 - % - % Put the type name to the right margin. - \noindent - \hbox to 0pt{% - \hfil\box0 \kern-\hsize - % \hsize has to be shortened this way: - \kern\leftskip - % Intentionally do not respect \rightskip, since we need the space. - }% - % - % Allow all lines to be underfull without complaint: - \tolerance=10000 \hbadness=10000 - \exdentamount=\defbodyindent - {% - % defun fonts. We use typewriter by default (used to be bold) because: - % . we're printing identifiers, they should be in tt in principle. - % . in languages with many accents, such as Czech or French, it's - % common to leave accents off identifiers. The result looks ok in - % tt, but exceedingly strange in rm. - % . we don't want -- and --- to be treated as ligatures. - % . this still does not fix the ?` and !` ligatures, but so far no - % one has made identifiers using them :). - \df \tt - \def\temp{#2}% return value type - \ifx\temp\empty\else \tclose{\temp} \fi - #3% output function name - }% - {\rm\enskip}% hskip 0.5 em of \tenrm - % - \boldbrax - % arguments will be output next, if any. -} - -% Print arguments in slanted roman (not ttsl), inconsistently with using -% tt for the name. This is because literal text is sometimes needed in -% the argument list (groff manual), and ttsl and tt are not very -% distinguishable. Prevent hyphenation at `-' chars. -% -\def\defunargs#1{% - % use sl by default (not ttsl), - % tt for the names. - \df \sl \hyphenchar\font=0 - % - % On the other hand, if an argument has two dashes (for instance), we - % want a way to get ttsl. Let's try @var for that. - \let\var=\ttslanted - #1% - \sl\hyphenchar\font=45 -} - -% We want ()&[] to print specially on the defun line. -% -\def\activeparens{% - \catcode`\(=\active \catcode`\)=\active - \catcode`\[=\active \catcode`\]=\active - \catcode`\&=\active -} - -% Make control sequences which act like normal parenthesis chars. -\let\lparen = ( \let\rparen = ) - -% Be sure that we always have a definition for `(', etc. For example, -% if the fn name has parens in it, \boldbrax will not be in effect yet, -% so TeX would otherwise complain about undefined control sequence. -{ - \activeparens - \global\let(=\lparen \global\let)=\rparen - \global\let[=\lbrack \global\let]=\rbrack - \global\let& = \& - - \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} - \gdef\magicamp{\let&=\amprm} -} - -\newcount\parencount - -% If we encounter &foo, then turn on ()-hacking afterwards -\newif\ifampseen -\def\amprm#1 {\ampseentrue{\bf\ }} - -\def\parenfont{% - \ifampseen - % At the first level, print parens in roman, - % otherwise use the default font. - \ifnum \parencount=1 \rm \fi - \else - % The \sf parens (in \boldbrax) actually are a little bolder than - % the contained text. This is especially needed for [ and ] . - \sf - \fi -} -\def\infirstlevel#1{% - \ifampseen - \ifnum\parencount=1 - #1% - \fi - \fi -} -\def\bfafterword#1 {#1 \bf} - -\def\opnr{% - \global\advance\parencount by 1 - {\parenfont(}% - \infirstlevel \bfafterword -} -\def\clnr{% - {\parenfont)}% - \infirstlevel \sl - \global\advance\parencount by -1 -} - -\newcount\brackcount -\def\lbrb{% - \global\advance\brackcount by 1 - {\bf[}% -} -\def\rbrb{% - {\bf]}% - \global\advance\brackcount by -1 -} - -\def\checkparencounts{% - \ifnum\parencount=0 \else \badparencount \fi - \ifnum\brackcount=0 \else \badbrackcount \fi -} -\def\badparencount{% - \errmessage{Unbalanced parentheses in @def}% - \global\parencount=0 -} -\def\badbrackcount{% - \errmessage{Unbalanced square braces in @def}% - \global\brackcount=0 -} - - -\message{macros,} -% @macro. - -% To do this right we need a feature of e-TeX, \scantokens, -% which we arrange to emulate with a temporary file in ordinary TeX. -\ifx\eTeXversion\undefined - \newwrite\macscribble - \def\scantokens#1{% - \toks0={#1}% - \immediate\openout\macscribble=\jobname.tmp - \immediate\write\macscribble{\the\toks0}% - \immediate\closeout\macscribble - \input \jobname.tmp - } -\fi - -\def\scanmacro#1{% - \begingroup - \newlinechar`\^^M - \let\xeatspaces\eatspaces - % Undo catcode changes of \startcontents and \doprintindex - % When called from @insertcopying or (short)caption, we need active - % backslash to get it printed correctly. Previously, we had - % \catcode`\\=\other instead. We'll see whether a problem appears - % with macro expansion. --kasal, 19aug04 - \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ - % ... and \example - \spaceisspace - % - % Append \endinput to make sure that TeX does not see the ending newline. - % I've verified that it is necessary both for e-TeX and for ordinary TeX - % --kasal, 29nov03 - \scantokens{#1\endinput}% - \endgroup -} - -\def\scanexp#1{% - \edef\temp{\noexpand\scanmacro{#1}}% - \temp -} - -\newcount\paramno % Count of parameters -\newtoks\macname % Macro name -\newif\ifrecursive % Is it recursive? - -% List of all defined macros in the form -% \definedummyword\macro1\definedummyword\macro2... -% Currently is also contains all @aliases; the list can be split -% if there is a need. -\def\macrolist{} - -% Add the macro to \macrolist -\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} -\def\addtomacrolistxxx#1{% - \toks0 = \expandafter{\macrolist\definedummyword#1}% - \xdef\macrolist{\the\toks0}% -} - -% Utility routines. -% This does \let #1 = #2, with \csnames; that is, -% \let \csname#1\endcsname = \csname#2\endcsname -% (except of course we have to play expansion games). -% -\def\cslet#1#2{% - \expandafter\let - \csname#1\expandafter\endcsname - \csname#2\endcsname -} - -% Trim leading and trailing spaces off a string. -% Concepts from aro-bend problem 15 (see CTAN). -{\catcode`\@=11 -\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} -\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} -\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} -\def\unbrace#1{#1} -\unbrace{\gdef\trim@@@ #1 } #2@{#1} -} - -% Trim a single trailing ^^M off a string. -{\catcode`\^^M=\other \catcode`\Q=3% -\gdef\eatcr #1{\eatcra #1Q^^MQ}% -\gdef\eatcra#1^^MQ{\eatcrb#1Q}% -\gdef\eatcrb#1Q#2Q{#1}% -} - -% Macro bodies are absorbed as an argument in a context where -% all characters are catcode 10, 11 or 12, except \ which is active -% (as in normal texinfo). It is necessary to change the definition of \. - -% It's necessary to have hard CRs when the macro is executed. This is -% done by making ^^M (\endlinechar) catcode 12 when reading the macro -% body, and then making it the \newlinechar in \scanmacro. - -\def\scanctxt{% - \catcode`\"=\other - \catcode`\+=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\@=\other - \catcode`\^=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\~=\other -} - -\def\scanargctxt{% - \scanctxt - \catcode`\\=\other - \catcode`\^^M=\other -} - -\def\macrobodyctxt{% - \scanctxt - \catcode`\{=\other - \catcode`\}=\other - \catcode`\^^M=\other - \usembodybackslash -} - -\def\macroargctxt{% - \scanctxt - \catcode`\\=\other -} - -% \mbodybackslash is the definition of \ in @macro bodies. -% It maps \foo\ => \csname macarg.foo\endcsname => #N -% where N is the macro parameter number. -% We define \csname macarg.\endcsname to be \realbackslash, so -% \\ in macro replacement text gets you a backslash. - -{\catcode`@=0 @catcode`@\=@active - @gdef at usembodybackslash{@let\=@mbodybackslash} - @gdef at mbodybackslash#1\{@csname macarg.#1 at endcsname} -} -\expandafter\def\csname macarg.\endcsname{\realbackslash} - -\def\macro{\recursivefalse\parsearg\macroxxx} -\def\rmacro{\recursivetrue\parsearg\macroxxx} - -\def\macroxxx#1{% - \getargs{#1}% now \macname is the macname and \argl the arglist - \ifx\argl\empty % no arguments - \paramno=0% - \else - \expandafter\parsemargdef \argl;% - \fi - \if1\csname ismacro.\the\macname\endcsname - \message{Warning: redefining \the\macname}% - \else - \expandafter\ifx\csname \the\macname\endcsname \relax - \else \errmessage{Macro name \the\macname\space already defined}\fi - \global\cslet{macsave.\the\macname}{\the\macname}% - \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% - \addtomacrolist{\the\macname}% - \fi - \begingroup \macrobodyctxt - \ifrecursive \expandafter\parsermacbody - \else \expandafter\parsemacbody - \fi} - -\parseargdef\unmacro{% - \if1\csname ismacro.#1\endcsname - \global\cslet{#1}{macsave.#1}% - \global\expandafter\let \csname ismacro.#1\endcsname=0% - % Remove the macro name from \macrolist: - \begingroup - \expandafter\let\csname#1\endcsname \relax - \let\definedummyword\unmacrodo - \xdef\macrolist{\macrolist}% - \endgroup - \else - \errmessage{Macro #1 not defined}% - \fi -} - -% Called by \do from \dounmacro on each macro. The idea is to omit any -% macro definitions that have been changed to \relax. -% -\def\unmacrodo#1{% - \ifx #1\relax - % remove this - \else - \noexpand\definedummyword \noexpand#1% - \fi -} - -% This makes use of the obscure feature that if the last token of a -% is #, then the preceding argument is delimited by -% an opening brace, and that opening brace is not consumed. -\def\getargs#1{\getargsxxx#1{}} -\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} -\def\getmacname #1 #2\relax{\macname={#1}} -\def\getmacargs#1{\def\argl{#1}} - -% Parse the optional {params} list. Set up \paramno and \paramlist -% so \defmacro knows what to do. Define \macarg.blah for each blah -% in the params list, to be ##N where N is the position in that list. -% That gets used by \mbodybackslash (above). - -% We need to get `macro parameter char #' into several definitions. -% The technique used is stolen from LaTeX: let \hash be something -% unexpandable, insert that wherever you need a #, and then redefine -% it to # just before using the token list produced. -% -% The same technique is used to protect \eatspaces till just before -% the macro is used. - -\def\parsemargdef#1;{\paramno=0\def\paramlist{}% - \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} -\def\parsemargdefxxx#1,{% - \if#1;\let\next=\relax - \else \let\next=\parsemargdefxxx - \advance\paramno by 1% - \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname - {\xeatspaces{\hash\the\paramno}}% - \edef\paramlist{\paramlist\hash\the\paramno,}% - \fi\next} - -% These two commands read recursive and nonrecursive macro bodies. -% (They're different since rec and nonrec macros end differently.) - -\long\def\parsemacbody#1 at end macro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% -\long\def\parsermacbody#1 at end rmacro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% - -% This defines the macro itself. There are six cases: recursive and -% nonrecursive macros of zero, one, and many arguments. -% Much magic with \expandafter here. -% \xdef is used so that macro definitions will survive the file -% they're defined in; @include reads the file inside a group. -\def\defmacro{% - \let\hash=##% convert placeholders to macro parameter chars - \ifrecursive - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\scanmacro{\temp}}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup\noexpand\scanmacro{\temp}}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{\egroup\noexpand\scanmacro{\temp}}% - \fi - \else - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \expandafter\noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \fi - \fi} - -\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} - -% \braceorline decides whether the next nonwhitespace character is a -% {. If so it reads up to the closing }, if not, it reads the whole -% line. Whatever was read is then fed to the next control sequence -% as an argument (by \parsebrace or \parsearg) -\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} -\def\braceorlinexxx{% - \ifx\nchar\bgroup\else - \expandafter\parsearg - \fi \macnamexxx} - - -% @alias. -% We need some trickery to remove the optional spaces around the equal -% sign. Just make them active and then expand them all to nothing. -\def\alias{\parseargusing\obeyspaces\aliasxxx} -\def\aliasxxx #1{\aliasyyy#1\relax} -\def\aliasyyy #1=#2\relax{% - {% - \expandafter\let\obeyedspace=\empty - \addtomacrolist{#1}% - \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% - }% - \next -} - - -\message{cross references,} - -\newwrite\auxfile - -\newif\ifhavexrefs % True if xref values are known. -\newif\ifwarnedxrefs % True if we warned once that they aren't known. - -% @inforef is relatively simple. -\def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, - node \samp{\ignorespaces#1{}}} - -% @node's only job in TeX is to define \lastnode, which is used in -% cross-references. The @node line might or might not have commas, and -% might or might not have spaces before the first comma, like: -% @node foo , bar , ... -% We don't want such trailing spaces in the node name. -% -\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} -% -% also remove a trailing comma, in case of something like this: -% @node Help-Cross, , , Cross-refs -\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} -\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} - -\let\nwnode=\node -\let\lastnode=\empty - -% Write a cross-reference definition for the current node. #1 is the -% type (Ynumbered, Yappendix, Ynothing). -% -\def\donoderef#1{% - \ifx\lastnode\empty\else - \setref{\lastnode}{#1}% - \global\let\lastnode=\empty - \fi -} - -% @anchor{NAME} -- define xref target at arbitrary point. -% -\newcount\savesfregister -% -\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} -\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} -\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} - -% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an -% anchor), which consists of three parts: -% 1) NAME-title - the current sectioning name taken from \thissection, -% or the anchor name. -% 2) NAME-snt - section number and type, passed as the SNT arg, or -% empty for anchors. -% 3) NAME-pg - the page number. -% -% This is called from \donoderef, \anchor, and \dofloat. In the case of -% floats, there is an additional part, which is not written here: -% 4) NAME-lof - the text as it should appear in a @listoffloats. -% -\def\setref#1#2{% - \pdfmkdest{#1}% - \iflinks - {% - \atdummies % preserve commands, but don't expand them - \edef\writexrdef##1##2{% - \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef - ##1}{##2}}% these are parameters of \writexrdef - }% - \toks0 = \expandafter{\thissection}% - \immediate \writexrdef{title}{\the\toks0 }% - \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. - \writexrdef{pg}{\folio}% will be written later, during \shipout - }% - \fi -} - -% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is -% the node name, #2 the name of the Info cross-reference, #3 the printed -% node name, #4 the name of the Info file, #5 the name of the printed -% manual. All but the node name can be omitted. -% -\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} -\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} -\def\ref#1{\xrefX[#1,,,,,,,]} -\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup - \unsepspaces - \def\printedmanual{\ignorespaces #5}% - \def\printedrefname{\ignorespaces #3}% - \setbox1=\hbox{\printedmanual\unskip}% - \setbox0=\hbox{\printedrefname\unskip}% - \ifdim \wd0 = 0pt - % No printed node name was explicitly given. - \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax - % Use the node name inside the square brackets. - \def\printedrefname{\ignorespaces #1}% - \else - % Use the actual chapter/section title appear inside - % the square brackets. Use the real section title if we have it. - \ifdim \wd1 > 0pt - % It is in another manual, so we don't have it. - \def\printedrefname{\ignorespaces #1}% - \else - \ifhavexrefs - % We know the real title if we have the xref values. - \def\printedrefname{\refx{#1-title}{}}% - \else - % Otherwise just copy the Info node name. - \def\printedrefname{\ignorespaces #1}% - \fi% - \fi - \fi - \fi - % - % Make link in pdf output. - \ifpdf - \leavevmode - \getfilename{#4}% - {\turnoffactive - % See comments at \activebackslashdouble. - {\activebackslashdouble \xdef\pdfxrefdest{#1}% - \backslashparens\pdfxrefdest}% - % - \ifnum\filenamelength>0 - \startlink attr{/Border [0 0 0]}% - goto file{\the\filename.pdf} name{\pdfxrefdest}% - \else - \startlink attr{/Border [0 0 0]}% - goto name{\pdfmkpgn{\pdfxrefdest}}% - \fi - }% - \linkcolor - \fi - % - % Float references are printed completely differently: "Figure 1.2" - % instead of "[somenode], p.3". We distinguish them by the - % LABEL-title being set to a magic string. - {% - % Have to otherify everything special to allow the \csname to - % include an _ in the xref name, etc. - \indexnofonts - \turnoffactive - \expandafter\global\expandafter\let\expandafter\Xthisreftitle - \csname XR#1-title\endcsname - }% - \iffloat\Xthisreftitle - % If the user specified the print name (third arg) to the ref, - % print it instead of our usual "Figure 1.2". - \ifdim\wd0 = 0pt - \refx{#1-snt}{}% - \else - \printedrefname - \fi - % - % if the user also gave the printed manual name (fifth arg), append - % "in MANUALNAME". - \ifdim \wd1 > 0pt - \space \putwordin{} \cite{\printedmanual}% - \fi - \else - % node/anchor (non-float) references. - % - % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not - % insert empty discretionaries after hyphens, which means that it will - % not find a line break at a hyphen in a node names. Since some manuals - % are best written with fairly long node names, containing hyphens, this - % is a loss. Therefore, we give the text of the node name again, so it - % is as if TeX is seeing it for the first time. - \ifdim \wd1 > 0pt - \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}% - \else - % _ (for example) has to be the character _ for the purposes of the - % control sequence corresponding to the node, but it has to expand - % into the usual \leavevmode...\vrule stuff for purposes of - % printing. So we \turnoffactive for the \refx-snt, back on for the - % printing, back off for the \refx-pg. - {\turnoffactive - % Only output a following space if the -snt ref is nonempty; for - % @unnumbered and @anchor, it won't be. - \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% - \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi - }% - % output the `[mynode]' via a macro so it can be overridden. - \xrefprintnodename\printedrefname - % - % But we always want a comma and a space: - ,\space - % - % output the `page 3'. - \turnoffactive \putwordpage\tie\refx{#1-pg}{}% - \fi - \fi - \endlink -\endgroup} - -% This macro is called from \xrefX for the `[nodename]' part of xref -% output. It's a separate macro only so it can be changed more easily, -% since square brackets don't work well in some documents. Particularly -% one that Bob is working on :). -% -\def\xrefprintnodename#1{[#1]} - -% Things referred to by \setref. -% -\def\Ynothing{} -\def\Yomitfromtoc{} -\def\Ynumbered{% - \ifnum\secno=0 - \putwordChapter at tie \the\chapno - \else \ifnum\subsecno=0 - \putwordSection at tie \the\chapno.\the\secno - \else \ifnum\subsubsecno=0 - \putwordSection at tie \the\chapno.\the\secno.\the\subsecno - \else - \putwordSection at tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno - \fi\fi\fi -} -\def\Yappendix{% - \ifnum\secno=0 - \putwordAppendix at tie @char\the\appendixno{}% - \else \ifnum\subsecno=0 - \putwordSection at tie @char\the\appendixno.\the\secno - \else \ifnum\subsubsecno=0 - \putwordSection at tie @char\the\appendixno.\the\secno.\the\subsecno - \else - \putwordSection at tie - @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno - \fi\fi\fi -} - -% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. -% If its value is nonempty, SUFFIX is output afterward. -% -\def\refx#1#2{% - {% - \indexnofonts - \otherbackslash - \expandafter\global\expandafter\let\expandafter\thisrefX - \csname XR#1\endcsname - }% - \ifx\thisrefX\relax - % If not defined, say something at least. - \angleleft un\-de\-fined\angleright - \iflinks - \ifhavexrefs - \message{\linenumber Undefined cross reference `#1'.}% - \else - \ifwarnedxrefs\else - \global\warnedxrefstrue - \message{Cross reference values unknown; you must run TeX again.}% - \fi - \fi - \fi - \else - % It's defined, so just use it. - \thisrefX - \fi - #2% Output the suffix in any case. -} - -% This is the macro invoked by entries in the aux file. Usually it's -% just a \def (we prepend XR to the control sequence name to avoid -% collisions). But if this is a float type, we have more work to do. -% -\def\xrdef#1#2{% - \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value. - % - % Was that xref control sequence that we just defined for a float? - \expandafter\iffloat\csname XR#1\endcsname - % it was a float, and we have the (safe) float type in \iffloattype. - \expandafter\let\expandafter\floatlist - \csname floatlist\iffloattype\endcsname - % - % Is this the first time we've seen this float type? - \expandafter\ifx\floatlist\relax - \toks0 = {\do}% yes, so just \do - \else - % had it before, so preserve previous elements in list. - \toks0 = \expandafter{\floatlist\do}% - \fi - % - % Remember this xref in the control sequence \floatlistFLOATTYPE, - % for later use in \listoffloats. - \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}% - \fi -} - -% Read the last existing aux file, if any. No error if none exists. -% -\def\tryauxfile{% - \openin 1 \jobname.aux - \ifeof 1 \else - \readdatafile{aux}% - \global\havexrefstrue - \fi - \closein 1 -} - -\def\setupdatafile{% - \catcode`\^^@=\other - \catcode`\^^A=\other - \catcode`\^^B=\other - \catcode`\^^C=\other - \catcode`\^^D=\other - \catcode`\^^E=\other - \catcode`\^^F=\other - \catcode`\^^G=\other - \catcode`\^^H=\other - \catcode`\^^K=\other - \catcode`\^^L=\other - \catcode`\^^N=\other - \catcode`\^^P=\other - \catcode`\^^Q=\other - \catcode`\^^R=\other - \catcode`\^^S=\other - \catcode`\^^T=\other - \catcode`\^^U=\other - \catcode`\^^V=\other - \catcode`\^^W=\other - \catcode`\^^X=\other - \catcode`\^^Z=\other - \catcode`\^^[=\other - \catcode`\^^\=\other - \catcode`\^^]=\other - \catcode`\^^^=\other - \catcode`\^^_=\other - % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. - % in xref tags, i.e., node names. But since ^^e4 notation isn't - % supported in the main text, it doesn't seem desirable. Furthermore, - % that is not enough: for node names that actually contain a ^ - % character, we would end up writing a line like this: 'xrdef {'hat - % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first - % argument, and \hat is not an expandable control sequence. It could - % all be worked out, but why? Either we support ^^ or we don't. - % - % The other change necessary for this was to define \auxhat: - % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter - % and then to call \auxhat in \setq. - % - \catcode`\^=\other - % - % Special characters. Should be turned off anyway, but... - \catcode`\~=\other - \catcode`\[=\other - \catcode`\]=\other - \catcode`\"=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\$=\other - \catcode`\#=\other - \catcode`\&=\other - \catcode`\%=\other - \catcode`+=\other % avoid \+ for paranoia even though we've turned it off - % - % This is to support \ in node names and titles, since the \ - % characters end up in a \csname. It's easier than - % leaving it active and making its active definition an actual \ - % character. What I don't understand is why it works in the *value* - % of the xrdef. Seems like it should be a catcode12 \, and that - % should not typeset properly. But it works, so I'm moving on for - % now. --karl, 15jan04. - \catcode`\\=\other - % - % Make the characters 128-255 be printing characters. - {% - \count1=128 - \def\loop{% - \catcode\count1=\other - \advance\count1 by 1 - \ifnum \count1<256 \loop \fi - }% - }% - % - % @ is our escape character in .aux files, and we need braces. - \catcode`\{=1 - \catcode`\}=2 - \catcode`\@=0 -} - -\def\readdatafile#1{% -\begingroup - \setupdatafile - \input\jobname.#1 -\endgroup} - -\message{insertions,} -% including footnotes. - -\newcount \footnoteno - -% The trailing space in the following definition for supereject is -% vital for proper filling; pages come out unaligned when you do a -% pagealignmacro call if that space before the closing brace is -% removed. (Generally, numeric constants should always be followed by a -% space to prevent strange expansion errors.) -\def\supereject{\par\penalty -20000\footnoteno =0 } - -% @footnotestyle is meaningful for info output only. -\let\footnotestyle=\comment - -{\catcode `\@=11 -% -% Auto-number footnotes. Otherwise like plain. -\gdef\footnote{% - \let\indent=\ptexindent - \let\noindent=\ptexnoindent - \global\advance\footnoteno by \@ne - \edef\thisfootno{$^{\the\footnoteno}$}% - % - % In case the footnote comes at the end of a sentence, preserve the - % extra spacing after we do the footnote number. - \let\@sf\empty - \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi - % - % Remove inadvertent blank space before typesetting the footnote number. - \unskip - \thisfootno\@sf - \dofootnote -}% - -% Don't bother with the trickery in plain.tex to not require the -% footnote text as a parameter. Our footnotes don't need to be so general. -% -% Oh yes, they do; otherwise, @ifset (and anything else that uses -% \parseargline) fails inside footnotes because the tokens are fixed when -% the footnote is read. --karl, 16nov96. -% -\gdef\dofootnote{% - \insert\footins\bgroup - % We want to typeset this text as a normal paragraph, even if the - % footnote reference occurs in (for example) a display environment. - % So reset some parameters. - \hsize=\pagewidth - \interlinepenalty\interfootnotelinepenalty - \splittopskip\ht\strutbox % top baseline for broken footnotes - \splitmaxdepth\dp\strutbox - \floatingpenalty\@MM - \leftskip\z at skip - \rightskip\z at skip - \spaceskip\z at skip - \xspaceskip\z at skip - \parindent\defaultparindent - % - \smallfonts \rm - % - % Because we use hanging indentation in footnotes, a @noindent appears - % to exdent this text, so make it be a no-op. makeinfo does not use - % hanging indentation so @noindent can still be needed within footnote - % text after an @example or the like (not that this is good style). - \let\noindent = \relax - % - % Hang the footnote text off the number. Use \everypar in case the - % footnote extends for more than one paragraph. - \everypar = {\hang}% - \textindent{\thisfootno}% - % - % Don't crash into the line above the footnote text. Since this - % expands into a box, it must come within the paragraph, lest it - % provide a place where TeX can split the footnote. - \footstrut - \futurelet\next\fo at t -} -}%end \catcode `\@=11 - -% In case a @footnote appears in a vbox, save the footnote text and create -% the real \insert just after the vbox finished. Otherwise, the insertion -% would be lost. -% Similarily, if a @footnote appears inside an alignment, save the footnote -% text to a box and make the \insert when a row of the table is finished. -% And the same can be done for other insert classes. --kasal, 16nov03. - -% Replace the \insert primitive by a cheating macro. -% Deeper inside, just make sure that the saved insertions are not spilled -% out prematurely. -% -\def\startsavinginserts{% - \ifx \insert\ptexinsert - \let\insert\saveinsert - \else - \let\checkinserts\relax - \fi -} - -% This \insert replacement works for both \insert\footins{foo} and -% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. -% -\def\saveinsert#1{% - \edef\next{\noexpand\savetobox \makeSAVEname#1}% - \afterassignment\next - % swallow the left brace - \let\temp = -} -\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} -\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} - -\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} - -\def\placesaveins#1{% - \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname - {\box#1}% -} - -% eat @SAVE -- beware, all of them have catcode \other: -{ - \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) - \gdef\gobblesave @SAVE{} -} - -% initialization: -\def\newsaveins #1{% - \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% - \next -} -\def\newsaveinsX #1{% - \csname newbox\endcsname #1% - \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts - \checksaveins #1}% -} - -% initialize: -\let\checkinserts\empty -\newsaveins\footins -\newsaveins\margin - - -% @image. We use the macros from epsf.tex to support this. -% If epsf.tex is not installed and @image is used, we complain. -% -% Check for and read epsf.tex up front. If we read it only at @image -% time, we might be inside a group, and then its definitions would get -% undone and the next image would fail. -\openin 1 = epsf.tex -\ifeof 1 \else - % Do not bother showing banner with epsf.tex v2.7k (available in - % doc/epsf.tex and on ctan). - \def\epsfannounce{\toks0 = }% - \input epsf.tex -\fi -\closein 1 -% -% We will only complain once about lack of epsf.tex. -\newif\ifwarnednoepsf -\newhelp\noepsfhelp{epsf.tex must be installed for images to - work. It is also included in the Texinfo distribution, or you can get - it from ftp://tug.org/tex/epsf.tex.} -% -\def\image#1{% - \ifx\epsfbox\undefined - \ifwarnednoepsf \else - \errhelp = \noepsfhelp - \errmessage{epsf.tex not found, images will be ignored}% - \global\warnednoepsftrue - \fi - \else - \imagexxx #1,,,,,\finish - \fi -} -% -% Arguments to @image: -% #1 is (mandatory) image filename; we tack on .eps extension. -% #2 is (optional) width, #3 is (optional) height. -% #4 is (ignored optional) html alt text. -% #5 is (ignored optional) extension. -% #6 is just the usual extra ignored arg for parsing this stuff. -\newif\ifimagevmode -\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup - \catcode`\^^M = 5 % in case we're inside an example - \normalturnoffactive % allow _ et al. in names - % If the image is by itself, center it. - \ifvmode - \imagevmodetrue - \nobreak\bigskip - % Usually we'll have text after the image which will insert - % \parskip glue, so insert it here too to equalize the space - % above and below. - \nobreak\vskip\parskip - \nobreak - \line\bgroup - \fi - % - % Output the image. - \ifpdf - \dopdfimage{#1}{#2}{#3}% - \else - % \epsfbox itself resets \epsf?size at each figure. - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi - \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi - \epsfbox{#1.eps}% - \fi - % - \ifimagevmode \egroup \bigbreak \fi % space after the image -\endgroup} - - -% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, -% etc. We don't actually implement floating yet, we always include the -% float "here". But it seemed the best name for the future. -% -\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} - -% There may be a space before second and/or third parameter; delete it. -\def\eatcommaspace#1, {#1,} - -% #1 is the optional FLOATTYPE, the text label for this float, typically -% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, -% this float will not be numbered and cannot be referred to. -% -% #2 is the optional xref label. Also must be present for the float to -% be referable. -% -% #3 is the optional positioning argument; for now, it is ignored. It -% will somehow specify the positions allowed to float to (here, top, bottom). -% -% We keep a separate counter for each FLOATTYPE, which we reset at each -% chapter-level command. -\let\resetallfloatnos=\empty -% -\def\dofloat#1,#2,#3,#4\finish{% - \let\thiscaption=\empty - \let\thisshortcaption=\empty - % - % don't lose footnotes inside @float. - % - % BEWARE: when the floats start float, we have to issue warning whenever an - % insert appears inside a float which could possibly float. --kasal, 26may04 - % - \startsavinginserts - % - % We can't be used inside a paragraph. - \par - % - \vtop\bgroup - \def\floattype{#1}% - \def\floatlabel{#2}% - \def\floatloc{#3}% we do nothing with this yet. - % - \ifx\floattype\empty - \let\safefloattype=\empty - \else - {% - % the floattype might have accents or other special characters, - % but we need to use it in a control sequence name. - \indexnofonts - \turnoffactive - \xdef\safefloattype{\floattype}% - }% - \fi - % - % If label is given but no type, we handle that as the empty type. - \ifx\floatlabel\empty \else - % We want each FLOATTYPE to be numbered separately (Figure 1, - % Table 1, Figure 2, ...). (And if no label, no number.) - % - \expandafter\getfloatno\csname\safefloattype floatno\endcsname - \global\advance\floatno by 1 - % - {% - % This magic value for \thissection is output by \setref as the - % XREFLABEL-title value. \xrefX uses it to distinguish float - % labels (which have a completely different output format) from - % node and anchor labels. And \xrdef uses it to construct the - % lists of floats. - % - \edef\thissection{\floatmagic=\safefloattype}% - \setref{\floatlabel}{Yfloat}% - }% - \fi - % - % start with \parskip glue, I guess. - \vskip\parskip - % - % Don't suppress indentation if a float happens to start a section. - \restorefirstparagraphindent -} - -% we have these possibilities: -% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap -% @float Foo,lbl & no caption: Foo 1.1 -% @float Foo & @caption{Cap}: Foo: Cap -% @float Foo & no caption: Foo -% @float ,lbl & Caption{Cap}: 1.1: Cap -% @float ,lbl & no caption: 1.1 -% @float & @caption{Cap}: Cap -% @float & no caption: -% -\def\Efloat{% - \let\floatident = \empty - % - % In all cases, if we have a float type, it comes first. - \ifx\floattype\empty \else \def\floatident{\floattype}\fi - % - % If we have an xref label, the number comes next. - \ifx\floatlabel\empty \else - \ifx\floattype\empty \else % if also had float type, need tie first. - \appendtomacro\floatident{\tie}% - \fi - % the number. - \appendtomacro\floatident{\chaplevelprefix\the\floatno}% - \fi - % - % Start the printed caption with what we've constructed in - % \floatident, but keep it separate; we need \floatident again. - \let\captionline = \floatident - % - \ifx\thiscaption\empty \else - \ifx\floatident\empty \else - \appendtomacro\captionline{: }% had ident, so need a colon between - \fi - % - % caption text. - \appendtomacro\captionline{\scanexp\thiscaption}% - \fi - % - % If we have anything to print, print it, with space before. - % Eventually this needs to become an \insert. - \ifx\captionline\empty \else - \vskip.5\parskip - \captionline - % - % Space below caption. - \vskip\parskip - \fi - % - % If have an xref label, write the list of floats info. Do this - % after the caption, to avoid chance of it being a breakpoint. - \ifx\floatlabel\empty \else - % Write the text that goes in the lof to the aux file as - % \floatlabel-lof. Besides \floatident, we include the short - % caption if specified, else the full caption if specified, else nothing. - {% - \atdummies - % - % since we read the caption text in the macro world, where ^^M - % is turned into a normal character, we have to scan it back, so - % we don't write the literal three characters "^^M" into the aux file. - \scanexp{% - \xdef\noexpand\gtemp{% - \ifx\thisshortcaption\empty - \thiscaption - \else - \thisshortcaption - \fi - }% - }% - \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident - \ifx\gtemp\empty \else : \gtemp \fi}}% - }% - \fi - \egroup % end of \vtop - % - % place the captured inserts - % - % BEWARE: when the floats start floating, we have to issue warning - % whenever an insert appears inside a float which could possibly - % float. --kasal, 26may04 - % - \checkinserts -} - -% Append the tokens #2 to the definition of macro #1, not expanding either. -% -\def\appendtomacro#1#2{% - \expandafter\def\expandafter#1\expandafter{#1#2}% -} - -% @caption, @shortcaption -% -\def\caption{\docaption\thiscaption} -\def\shortcaption{\docaption\thisshortcaption} -\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} -\def\defcaption#1#2{\egroup \def#1{#2}} - -% The parameter is the control sequence identifying the counter we are -% going to use. Create it if it doesn't exist and assign it to \floatno. -\def\getfloatno#1{% - \ifx#1\relax - % Haven't seen this figure type before. - \csname newcount\endcsname #1% - % - % Remember to reset this floatno at the next chap. - \expandafter\gdef\expandafter\resetallfloatnos - \expandafter{\resetallfloatnos #1=0 }% - \fi - \let\floatno#1% -} - -% \setref calls this to get the XREFLABEL-snt value. We want an @xref -% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we -% first read the @float command. -% -\def\Yfloat{\floattype at tie \chaplevelprefix\the\floatno}% - -% Magic string used for the XREFLABEL-title value, so \xrefX can -% distinguish floats from other xref types. -\def\floatmagic{!!float!!} - -% #1 is the control sequence we are passed; we expand into a conditional -% which is true if #1 represents a float ref. That is, the magic -% \thissection value which we \setref above. -% -\def\iffloat#1{\expandafter\doiffloat#1==\finish} -% -% #1 is (maybe) the \floatmagic string. If so, #2 will be the -% (safe) float type for this float. We set \iffloattype to #2. -% -\def\doiffloat#1=#2=#3\finish{% - \def\temp{#1}% - \def\iffloattype{#2}% - \ifx\temp\floatmagic -} - -% @listoffloats FLOATTYPE - print a list of floats like a table of contents. -% -\parseargdef\listoffloats{% - \def\floattype{#1}% floattype - {% - % the floattype might have accents or other special characters, - % but we need to use it in a control sequence name. - \indexnofonts - \turnoffactive - \xdef\safefloattype{\floattype}% - }% - % - % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. - \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax - \ifhavexrefs - % if the user said @listoffloats foo but never @float foo. - \message{\linenumber No `\safefloattype' floats to list.}% - \fi - \else - \begingroup - \leftskip=\tocindent % indent these entries like a toc - \let\do=\listoffloatsdo - \csname floatlist\safefloattype\endcsname - \endgroup - \fi -} - -% This is called on each entry in a list of floats. We're passed the -% xref label, in the form LABEL-title, which is how we save it in the -% aux file. We strip off the -title and look up \XRLABEL-lof, which -% has the text we're supposed to typeset here. -% -% Figures without xref labels will not be included in the list (since -% they won't appear in the aux file). -% -\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} -\def\listoffloatsdoentry#1-title\finish{{% - % Can't fully expand XR#1-lof because it can contain anything. Just - % pass the control sequence. On the other hand, XR#1-pg is just the - % page number, and we want to fully expand that so we can get a link - % in pdf output. - \toksA = \expandafter{\csname XR#1-lof\endcsname}% - % - % use the same \entry macro we use to generate the TOC and index. - \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% - \writeentry -}} - -\message{localization,} -% and i18n. - -% @documentlanguage is usually given very early, just after -% @setfilename. If done too late, it may not override everything -% properly. Single argument is the language abbreviation. -% It would be nice if we could set up a hyphenation file here. -% -\parseargdef\documentlanguage{% - \tex % read txi-??.tex file in plain TeX. - % Read the file if it exists. - \openin 1 txi-#1.tex - \ifeof 1 - \errhelp = \nolanghelp - \errmessage{Cannot read language file txi-#1.tex}% - \else - \input txi-#1.tex - \fi - \closein 1 - \endgroup -} -\newhelp\nolanghelp{The given language definition file cannot be found or -is empty. Maybe you need to install it? In the current directory -should work if nowhere else does.} - - -% @documentencoding should change something in TeX eventually, most -% likely, but for now just recognize it. -\let\documentencoding = \comment - - -% Page size parameters. -% -\newdimen\defaultparindent \defaultparindent = 15pt - -\chapheadingskip = 15pt plus 4pt minus 2pt -\secheadingskip = 12pt plus 3pt minus 2pt -\subsecheadingskip = 9pt plus 2pt minus 2pt - -% Prevent underfull vbox error messages. -\vbadness = 10000 - -% Don't be so finicky about underfull hboxes, either. -\hbadness = 2000 - -% Following George Bush, just get rid of widows and orphans. -\widowpenalty=10000 -\clubpenalty=10000 - -% Use TeX 3.0's \emergencystretch to help line breaking, but if we're -% using an old version of TeX, don't do anything. We want the amount of -% stretch added to depend on the line length, hence the dependence on -% \hsize. We call this whenever the paper size is set. -% -\def\setemergencystretch{% - \ifx\emergencystretch\thisisundefined - % Allow us to assign to \emergencystretch anyway. - \def\emergencystretch{\dimen0}% - \else - \emergencystretch = .15\hsize - \fi -} - -% Parameters in order: 1) textheight; 2) textwidth; -% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; -% 7) physical page height; 8) physical page width. -% -% We also call \setleading{\textleading}, so the caller should define -% \textleading. The caller should also set \parskip. -% -\def\internalpagesizes#1#2#3#4#5#6#7#8{% - \voffset = #3\relax - \topskip = #6\relax - \splittopskip = \topskip - % - \vsize = #1\relax - \advance\vsize by \topskip - \outervsize = \vsize - \advance\outervsize by 2\topandbottommargin - \pageheight = \vsize - % - \hsize = #2\relax - \outerhsize = \hsize - \advance\outerhsize by 0.5in - \pagewidth = \hsize - % - \normaloffset = #4\relax - \bindingoffset = #5\relax - % - \ifpdf - \pdfpageheight #7\relax - \pdfpagewidth #8\relax - \fi - % - \setleading{\textleading} - % - \parindent = \defaultparindent - \setemergencystretch -} - -% @letterpaper (the default). -\def\letterpaper{{\globaldefs = 1 - \parskip = 3pt plus 2pt minus 1pt - \textleading = 13.2pt - % - % If page is nothing but text, make it come out even. - \internalpagesizes{46\baselineskip}{6in}% - {\voffset}{.25in}% - {\bindingoffset}{36pt}% - {11in}{8.5in}% -}} - -% Use @smallbook to reset parameters for 7x9.25 trim size. -\def\smallbook{{\globaldefs = 1 - \parskip = 2pt plus 1pt - \textleading = 12pt - % - \internalpagesizes{7.5in}{5in}% - {\voffset}{.25in}% - {\bindingoffset}{16pt}% - {9.25in}{7in}% - % - \lispnarrowing = 0.3in - \tolerance = 700 - \hfuzz = 1pt - \contentsrightmargin = 0pt - \defbodyindent = .5cm -}} - -% Use @smallerbook to reset parameters for 6x9 trim size. -% (Just testing, parameters still in flux.) -\def\smallerbook{{\globaldefs = 1 - \parskip = 1.5pt plus 1pt - \textleading = 12pt - % - \internalpagesizes{7.4in}{4.8in}% - {-.2in}{-.4in}% - {0pt}{14pt}% - {9in}{6in}% - % - \lispnarrowing = 0.25in - \tolerance = 700 - \hfuzz = 1pt - \contentsrightmargin = 0pt - \defbodyindent = .4cm -}} - -% Use @afourpaper to print on European A4 paper. -\def\afourpaper{{\globaldefs = 1 - \parskip = 3pt plus 2pt minus 1pt - \textleading = 13.2pt - % - % Double-side printing via postscript on Laserjet 4050 - % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. - % To change the settings for a different printer or situation, adjust - % \normaloffset until the front-side and back-side texts align. Then - % do the same for \bindingoffset. You can set these for testing in - % your texinfo source file like this: - % @tex - % \global\normaloffset = -6mm - % \global\bindingoffset = 10mm - % @end tex - \internalpagesizes{51\baselineskip}{160mm} - {\voffset}{\hoffset}% - {\bindingoffset}{44pt}% - {297mm}{210mm}% - % - \tolerance = 700 - \hfuzz = 1pt - \contentsrightmargin = 0pt - \defbodyindent = 5mm -}} - -% Use @afivepaper to print on European A5 paper. -% From romildo at urano.iceb.ufop.br, 2 July 2000. -% He also recommends making @example and @lisp be small. -\def\afivepaper{{\globaldefs = 1 - \parskip = 2pt plus 1pt minus 0.1pt - \textleading = 12.5pt - % - \internalpagesizes{160mm}{120mm}% - {\voffset}{\hoffset}% - {\bindingoffset}{8pt}% - {210mm}{148mm}% - % - \lispnarrowing = 0.2in - \tolerance = 800 - \hfuzz = 1.2pt - \contentsrightmargin = 0pt - \defbodyindent = 2mm - \tableindent = 12mm -}} - -% A specific text layout, 24x15cm overall, intended for A4 paper. -\def\afourlatex{{\globaldefs = 1 - \afourpaper - \internalpagesizes{237mm}{150mm}% - {\voffset}{4.6mm}% - {\bindingoffset}{7mm}% - {297mm}{210mm}% - % - % Must explicitly reset to 0 because we call \afourpaper. - \globaldefs = 0 -}} - -% Use @afourwide to print on A4 paper in landscape format. -\def\afourwide{{\globaldefs = 1 - \afourpaper - \internalpagesizes{241mm}{165mm}% - {\voffset}{-2.95mm}% - {\bindingoffset}{7mm}% - {297mm}{210mm}% - \globaldefs = 0 -}} - -% @pagesizes TEXTHEIGHT[,TEXTWIDTH] -% Perhaps we should allow setting the margins, \topskip, \parskip, -% and/or leading, also. Or perhaps we should compute them somehow. -% -\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} -\def\pagesizesyyy#1,#2,#3\finish{{% - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi - \globaldefs = 1 - % - \parskip = 3pt plus 2pt minus 1pt - \setleading{\textleading}% - % - \dimen0 = #1 - \advance\dimen0 by \voffset - % - \dimen2 = \hsize - \advance\dimen2 by \normaloffset - % - \internalpagesizes{#1}{\hsize}% - {\voffset}{\normaloffset}% - {\bindingoffset}{44pt}% - {\dimen0}{\dimen2}% -}} - -% Set default to letter. -% -\letterpaper - - -\message{and turning on texinfo input format.} - -% Define macros to output various characters with catcode for normal text. -\catcode`\"=\other -\catcode`\~=\other -\catcode`\^=\other -\catcode`\_=\other -\catcode`\|=\other -\catcode`\<=\other -\catcode`\>=\other -\catcode`\+=\other -\catcode`\$=\other -\def\normaldoublequote{"} -\def\normaltilde{~} -\def\normalcaret{^} -\def\normalunderscore{_} -\def\normalverticalbar{|} -\def\normalless{<} -\def\normalgreater{>} -\def\normalplus{+} -\def\normaldollar{$}%$ font-lock fix - -% This macro is used to make a character print one way in \tt -% (where it can probably be output as-is), and another way in other fonts, -% where something hairier probably needs to be done. -% -% #1 is what to print if we are indeed using \tt; #2 is what to print -% otherwise. Since all the Computer Modern typewriter fonts have zero -% interword stretch (and shrink), and it is reasonable to expect all -% typewriter fonts to have this, we can check that font parameter. -% -\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} - -% Same as above, but check for italic font. Actually this also catches -% non-italic slanted fonts since it is impossible to distinguish them from -% italic fonts. But since this is only used by $ and it uses \sl anyway -% this is not a problem. -\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} - -% Turn off all special characters except @ -% (and those which the user can use as if they were ordinary). -% Most of these we simply print from the \tt font, but for some, we can -% use math or other variants that look better in normal text. - -\catcode`\"=\active -\def\activedoublequote{{\tt\char34}} -\let"=\activedoublequote -\catcode`\~=\active -\def~{{\tt\char126}} -\chardef\hat=`\^ -\catcode`\^=\active -\def^{{\tt \hat}} - -\catcode`\_=\active -\def_{\ifusingtt\normalunderscore\_} -\let\realunder=_ -% Subroutine for the previous macro. -\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } - -\catcode`\|=\active -\def|{{\tt\char124}} -\chardef \less=`\< -\catcode`\<=\active -\def<{{\tt \less}} -\chardef \gtr=`\> -\catcode`\>=\active -\def>{{\tt \gtr}} -\catcode`\+=\active -\def+{{\tt \char 43}} -\catcode`\$=\active -\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix - -% If a .fmt file is being used, characters that might appear in a file -% name cannot be active until we have parsed the command line. -% So turn them off again, and have \everyjob (or @setfilename) turn them on. -% \otherifyactive is called near the end of this file. -\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} - -% Used sometimes to turn off (effectively) the active characters even after -% parsing them. -\def\turnoffactive{% - \normalturnoffactive - \otherbackslash -} - -\catcode`\@=0 - -% \backslashcurfont outputs one backslash character in current font, -% as in \char`\\. -\global\chardef\backslashcurfont=`\\ -\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work - -% \realbackslash is an actual character `\' with catcode other, and -% \doublebackslash is two of them (for the pdf outlines). -{\catcode`\\=\other @gdef at realbackslash{\} @gdef at doublebackslash{\\}} - -% In texinfo, backslash is an active character; it prints the backslash -% in fixed width font. -\catcode`\\=\active - at def@normalbackslash{{@tt at backslashcurfont}} -% On startup, @fixbackslash assigns: -% @let \ = @normalbackslash - -% \rawbackslash defines an active \ to do \backslashcurfont. -% \otherbackslash defines an active \ to be a literal `\' character with -% catcode other. - at gdef@rawbackslash{@let\=@backslashcurfont} - at gdef@otherbackslash{@let\=@realbackslash} - -% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of -% the literal character `\'. -% - at def@normalturnoffactive{% - @let\=@normalbackslash - @let"=@normaldoublequote - @let~=@normaltilde - @let^=@normalcaret - @let_=@normalunderscore - @let|=@normalverticalbar - @let<=@normalless - @let>=@normalgreater - @let+=@normalplus - @let$=@normaldollar %$ font-lock fix - @unsepspaces -} - -% Make _ and + \other characters, temporarily. -% This is canceled by @fixbackslash. - at otherifyactive - -% If a .fmt file is being used, we don't want the `\input texinfo' to show up. -% That is what \eatinput is for; after that, the `\' should revert to printing -% a backslash. -% - at gdef@eatinput input texinfo{@fixbackslash} - at global@let\ = @eatinput - -% On the other hand, perhaps the file did not have a `\input texinfo'. Then -% the first `\' in the file would cause an error. This macro tries to fix -% that, assuming it is called before the first `\' could plausibly occur. -% Also turn back on active characters that might appear in the input -% file name, in case not using a pre-dumped format. -% - at gdef@fixbackslash{% - @ifx\@eatinput @let\ = @normalbackslash @fi - @catcode`+=@active - @catcode`@_=@active -} - -% Say @foo, not \foo, in error messages. - at escapechar = `@@ - -% These look ok in all fonts, so just make them not special. - at catcode`@& = @other - at catcode`@# = @other - at catcode`@% = @other - - - at c Local variables: - at c eval: (add-hook 'write-file-hooks 'time-stamp) - at c page-delimiter: "^\\\\message" - at c time-stamp-start: "def\\\\texinfoversion{" - at c time-stamp-format: "%:y-%02m-%02d.%02H" - at c time-stamp-end: "}" - at c End: - - at c vim:sw=2: - - at ignore - arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 - at end ignore diff --git a/install-sh b/install-sh deleted file mode 100755 index 6781b98..0000000 --- a/install-sh +++ /dev/null @@ -1,520 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2009-04-28.21; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names starting with `-'. - case $src in - -*) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - -*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test -z "$d" && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/missing b/missing deleted file mode 100755 index 894e786..0000000 --- a/missing +++ /dev/null @@ -1,360 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. - -scriptversion=2005-06-08.21 - -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. - -# 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; either version 2, or (at your option) -# any later version. - -# 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; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - -case "$1" in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - -esac - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). -case "$1" in - lex|yacc) - # Not GNU programs, they don't have --version. - ;; - - tar) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case "$1" in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case "$firstarg" in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case "$firstarg" in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/mkinstalldirs b/mkinstalldirs deleted file mode 100755 index ef7e16f..0000000 --- a/mkinstalldirs +++ /dev/null @@ -1,161 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy - -scriptversion=2006-05-11.19 - -# Original author: Noah Friedman -# Created: 1993-05-16 -# Public domain. -# -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' -IFS=" "" $nl" -errstatus=0 -dirmode= - -usage="\ -Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... - -Create each directory DIR (with mode MODE, if specified), including all -leading file name components. - -Report bugs to ." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" - exit $? - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --version) - echo "$0 $scriptversion" - exit $? - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and -# mkdir -p a/c at the same time, both will detect that a is missing, -# one will create a, then the other will try to create a and die with -# a "File exists" error. This is a problem when calling mkinstalldirs -# from a parallel make. We use --version in the probe to restrict -# ourselves to GNU mkdir, which is thread-safe. -case $dirmode in - '') - if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - test -d ./-p && rmdir ./-p - test -d ./--version && rmdir ./--version - fi - ;; - *) - if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && - test ! -d ./--version; then - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - else - # Clean up after NextStep and OpenStep mkdir. - for d in ./-m ./-p ./--version "./$dirmode"; - do - test -d $d && rmdir $d - done - fi - ;; -esac - -for file -do - case $file in - /*) pathcomp=/ ;; - *) pathcomp= ;; - esac - oIFS=$IFS - IFS=/ - set fnord $file - shift - IFS=$oIFS - - for d - do - test "x$d" = x && continue - - pathcomp=$pathcomp$d - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr= - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi - fi - fi - - pathcomp=$pathcomp/ - done -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: -- 1.8.4.rc3 From cvs at cvs.gnupg.org Mon Sep 23 09:25:21 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 23 Sep 2013 09:25:21 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-265-g4552437 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 4552437bb3c5ff96a889fd31e4bc504b2a12fac7 (commit) from 925d4fb3e8f2df3c5566ec6b5df7620a3d3504e5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4552437bb3c5ff96a889fd31e4bc504b2a12fac7 Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 ec: Use mpi_mulm instead of mpi_powm. * mpi/ec.c (ec_pow2): New. (ec_powm): Remove call to mpi_abs. (dup_point_weierstrass, dup_point_twistededwards) (add_points_weierstrass, add_points_twistededwards) (_gcry_mpi_ec_curve_point): Use ec_pow2. Signed-off-by: Werner Koch diff --git a/mpi/ec.c b/mpi/ec.c index 730f766..e52facd 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -367,9 +367,22 @@ ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e, mpi_ec_t ctx) { mpi_powm (w, b, e, ctx->p); - _gcry_mpi_abs (w); + /* _gcry_mpi_abs (w); */ } + +/* Shortcut for + ec_powm (B, B, mpi_const (MPI_C_TWO), ctx); + for easier optimization. */ +static void +ec_pow2 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx) +{ + /* Using mpi_mul is slightly faster (at least on amd64). */ + /* mpi_powm (w, b, mpi_const (MPI_C_TWO), ctx->p); */ + mpi_mulm (w, b, b, ctx->p); +} + + static void ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx) { @@ -803,7 +816,7 @@ dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) /* L1 = 3(X - Z^2)(X + Z^2) */ /* T1: used for Z^2. */ /* T2: used for the right term. */ - ec_powm (t1, point->z, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (t1, point->z, ctx); ec_subm (l1, point->x, t1, ctx); ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx); ec_addm (t2, point->x, t1, ctx); @@ -813,7 +826,7 @@ dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) { /* L1 = 3X^2 + aZ^4 */ /* T1: used for aZ^4. */ - ec_powm (l1, point->x, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (l1, point->x, ctx); ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx); ec_powm (t1, point->z, mpi_const (MPI_C_FOUR), ctx); ec_mulm (t1, t1, ctx->a, ctx); @@ -825,19 +838,19 @@ dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) /* L2 = 4XY^2 */ /* T2: used for Y2; required later. */ - ec_powm (t2, point->y, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (t2, point->y, ctx); ec_mulm (l2, t2, point->x, ctx); ec_mulm (l2, l2, mpi_const (MPI_C_FOUR), ctx); /* X3 = L1^2 - 2L2 */ /* T1: used for L2^2. */ - ec_powm (x3, l1, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (x3, l1, ctx); ec_mulm (t1, l2, mpi_const (MPI_C_TWO), ctx); ec_subm (x3, x3, t1, ctx); /* L3 = 8Y^4 */ /* T2: taken from above. */ - ec_powm (t2, t2, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (t2, t2, ctx); ec_mulm (l3, t2, mpi_const (MPI_C_EIGHT), ctx); /* Y3 = L1(L2 - X3) - L3 */ @@ -892,12 +905,12 @@ dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) /* B = (X_1 + Y_1)^2 */ ec_addm (B, X1, Y1, ctx); - ec_powm (B, B, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (B, B, ctx); /* C = X_1^2 */ /* D = Y_1^2 */ - ec_powm (C, X1, mpi_const (MPI_C_TWO), ctx); - ec_powm (D, Y1, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (C, X1, ctx); + ec_pow2 (D, Y1, ctx); /* E = aC */ ec_mulm (E, ctx->a, C, ctx); @@ -906,7 +919,7 @@ dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) ec_addm (F, E, D, ctx); /* H = Z_1^2 */ - ec_powm (H, Z1, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (H, Z1, ctx); /* J = F - 2H */ ec_mulm (J, H, mpi_const (MPI_C_TWO), ctx); @@ -1016,14 +1029,14 @@ add_points_weierstrass (mpi_point_t result, mpi_set (l1, x1); else { - ec_powm (l1, z2, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (l1, z2, ctx); ec_mulm (l1, l1, x1, ctx); } if (z1_is_one) mpi_set (l2, x2); else { - ec_powm (l2, z1, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (l2, z1, ctx); ec_mulm (l2, l2, x2, ctx); } /* l3 = l1 - l2 */ @@ -1062,8 +1075,8 @@ add_points_weierstrass (mpi_point_t result, ec_mulm (z3, z1, z2, ctx); ec_mulm (z3, z3, l3, ctx); /* x3 = l6^2 - l7 l3^2 */ - ec_powm (t1, l6, mpi_const (MPI_C_TWO), ctx); - ec_powm (t2, l3, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (t1, l6, ctx); + ec_pow2 (t2, l3, ctx); ec_mulm (t2, t2, l7, ctx); ec_subm (x3, t1, t2, ctx); /* l9 = l7 l3^2 - 2 x3 */ @@ -1146,7 +1159,7 @@ add_points_twistededwards (mpi_point_t result, ec_mulm (A, Z1, Z2, ctx); /* B = A^2 */ - ec_powm (B, A, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (B, A, ctx); /* C = X1 ? X2 */ ec_mulm (C, X1, X2, ctx); @@ -1369,8 +1382,8 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) case MPI_EC_TWISTEDEDWARDS: { /* a ? x^2 + y^2 - 1 - b ? x^2 ? y^2 == 0 */ - ec_powm (x, x, mpi_const (MPI_C_TWO), ctx); - ec_powm (y, y, mpi_const (MPI_C_TWO), ctx); + ec_pow2 (x, x, ctx); + ec_pow2 (y, y, ctx); ec_mulm (w, ctx->a, x, ctx); ec_addm (w, w, y, ctx); ec_subm (w, w, mpi_const (MPI_C_ONE), ctx); diff --git a/mpi/mpi-add.c b/mpi/mpi-add.c index 98abc56..5f7ad3f 100644 --- a/mpi/mpi-add.c +++ b/mpi/mpi-add.c @@ -224,12 +224,12 @@ void gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) { gcry_mpi_add(w, u, v); - _gcry_mpi_fdiv_r( w, w, m ); + _gcry_mpi_mod (w, w, m); } void gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) { gcry_mpi_sub(w, u, v); - _gcry_mpi_fdiv_r( w, w, m ); + _gcry_mpi_mod (w, w, m); } diff --git a/mpi/mpi-mul.c b/mpi/mpi-mul.c index 9aefd21..ec6aea0 100644 --- a/mpi/mpi-mul.c +++ b/mpi/mpi-mul.c @@ -205,8 +205,8 @@ gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) void -gcry_mpi_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) +gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) { - gcry_mpi_mul(w, u, v); - _gcry_mpi_fdiv_r( w, w, m ); + gcry_mpi_mul (w, u, v); + _gcry_mpi_mod (w, w, m); } ----------------------------------------------------------------------- Summary of changes: mpi/ec.c | 47 ++++++++++++++++++++++++++++++----------------- mpi/mpi-add.c | 4 ++-- mpi/mpi-mul.c | 6 +++--- 3 files changed, 35 insertions(+), 22 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From wk at gnupg.org Mon Sep 23 14:22:42 2013 From: wk at gnupg.org (Werner Koch) Date: Mon, 23 Sep 2013 14:22:42 +0200 Subject: commit logs In-Reply-To: (Dmitry Eremin-Solenikov's message of "Fri, 20 Sep 2013 20:46:08 +0400") References: <87r4ckua5a.fsf@vigenere.g10code.de> <523B2856.8040304@iki.fi> <87zjr7pux1.fsf@vigenere.g10code.de> Message-ID: <87a9j3n2wd.fsf@vigenere.g10code.de> On Fri, 20 Sep 2013 18:46, dbaryshkov at gmail.com said: > What about having read-only gcrypt-commits ML with Reply-To: header set to > gcrypt-devel ML ? We used to to this for some years but it has the disadvantage that readers of gcrypt-devel only see the reply and not the original (mail (ie. the commit log). Let's try to send it directly to this list (actually using a procmail based forwarding). Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Mon Sep 23 14:20:18 2013 From: wk at gnupg.org (Werner Koch) Date: Mon, 23 Sep 2013 14:20:18 +0200 Subject: [PATCH 1/2] Drop automake-installed files In-Reply-To: <1379880151-5636-1-git-send-email-dbaryshkov@gmail.com> (Dmitry Eremin-Solenikov's message of "Mon, 23 Sep 2013 00:02:30 +0400") References: <1379880151-5636-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <87eh8fn30d.fsf@vigenere.g10code.de> On Sun, 22 Sep 2013 22:02, dbaryshkov at gmail.com said: > Automake 1.13 and 1.14 add another script - test-driver. Moreover they Newer automake versions are not backward compatible and thus are not supported. The configuration files (config.guess et al.) are considered part of Libgcrypt proper and thus need to stay in the repo. It is important to have a the build system under out control (as far as this is possible) and thus we need to track those file. Run autogen.sh with something like AUTOMAKE_SUFFIX="-1.11" ./autogen.sh and version 1.11 of automake will be used (needs to installed of course). Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Mon Sep 23 22:56:56 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 23 Sep 2013 22:56:56 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-266-gd5f9146 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via d5f91466695c5736f441c9bf1998436184a4bf61 (commit) from 4552437bb3c5ff96a889fd31e4bc504b2a12fac7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d5f91466695c5736f441c9bf1998436184a4bf61 Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 pk: Add algo id GCRY_PK_ECC and deprecate ECDSA and ECDH. * src/gcrypt.h.in (GCRY_PK_ECC): New. * cipher/pubkey.c (map_algo): New. (spec_from_algo, gcry_pk_get_param, _gcry_pk_selftest): Use it. * cipher/ecc.c (selftests_ecdsa): Report using GCRY_PK_ECC. (run_selftests): Simplify. (ecdh_names, ecdsa_names): Merge into a new ecc_names. (_gcry_pubkey_spec_ecdh, _gcry_pubkey_spec_ecdsa): Merge into new _gcry_pubkey_spec_ecc. -- The algo ids are actually a relict from Libgcrypt's former life as GnuPG's crypto code. They don't make much sense anymore and are often not needed. This patch requires some changes to the GnuPG 2.1 code (which has still not been released). For example the secret key transfer between gpg and gpg-agent (gpg --export and gpg --import). Fortunately this will also require to add usage flags to the secret key storage of gpg-agent which is is something we should have done a long time ago. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 678805d..1e84cbe 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,9 @@ Noteworthy changes in version 1.6.0 (unreleased) * Added support for negative numbers to gcry_mpi_print, gcry_mpi_aprint and gcry_mpi_scan. + * The algorithm ids GCRY_PK_ECDSA and GCRY_PK_ECDH are now + deprecated. Use GCRY_PK_ECC instead. + * Interface changes relative to the 1.5.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gcry_ac_* REMOVED. @@ -103,6 +106,7 @@ Noteworthy changes in version 1.6.0 (unreleased) GCRY_MD_STRIBOG256 NEW. GCRY_MD_STRIBOG512 NEW. GCRYCTL_DISABLE_ALGO CHANGED: Not anymore thread-safe. + GCRY_PK_ECC NEW. Noteworthy changes in version 1.5.0 (2011-06-29) diff --git a/cipher/ecc.c b/cipher/ecc.c index 2161b64..d31b4be 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1965,7 +1965,7 @@ selftests_ecdsa (selftest_report_func_t report) failed: if (report) - report ("pubkey", GCRY_PK_ECDSA, what, errtxt); + report ("pubkey", GCRY_PK_ECC, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } @@ -1974,72 +1974,38 @@ selftests_ecdsa (selftest_report_func_t report) static gpg_err_code_t run_selftests (int algo, int extended, selftest_report_func_t report) { - gpg_err_code_t ec; - (void)extended; - switch (algo) - { - case GCRY_PK_ECDSA: - ec = selftests_ecdsa (report); - break; - default: - ec = GPG_ERR_PUBKEY_ALGO; - break; + if (algo != GCRY_PK_ECC) + return GPG_ERR_PUBKEY_ALGO; - } - return ec; + return selftests_ecdsa (report); } -static const char *ecdsa_names[] = +static const char *ecc_names[] = { - "ecdsa", - "eddsa", "ecc", - NULL, - }; -static const char *ecdh_names[] = - { + "ecdsa", "ecdh", - "ecc", - NULL, - }; - -gcry_pk_spec_t _gcry_pubkey_spec_ecdsa = - { - GCRY_PK_ECDSA, { 0, 0 }, - GCRY_PK_USAGE_SIGN, - "ECDSA", ecdsa_names, - "pabgnq", "pabgnqd", "", "rs", "pabgnq", - ecc_generate, - ecc_check_secret_key, - NULL, + "eddsa", NULL, - ecc_sign, - ecc_verify, - ecc_get_nbits, - run_selftests, - compute_keygrip, - _gcry_ecc_get_param, - _gcry_ecc_get_curve, - _gcry_ecc_get_param_sexp }; -gcry_pk_spec_t _gcry_pubkey_spec_ecdh = +gcry_pk_spec_t _gcry_pubkey_spec_ecc = { - GCRY_PK_ECDH, { 0, 0 }, - GCRY_PK_USAGE_ENCR, - "ECDH", ecdh_names, - "pabgnq", "pabgnqd", "se", "", "pabgnq", + GCRY_PK_ECC, { 0, 0 }, + (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR), + "ECC", ecc_names, + "pabgnq", "pabgnqd", "sw", "rs", "pabgnq", ecc_generate, ecc_check_secret_key, ecc_encrypt_raw, ecc_decrypt_raw, - NULL, - NULL, + ecc_sign, + ecc_verify, ecc_get_nbits, run_selftests, compute_keygrip, diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 99b9ba8..4738c29 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -38,8 +38,7 @@ static gcry_pk_spec_t *pubkey_list[] = { #if USE_ECC - &_gcry_pubkey_spec_ecdsa, - &_gcry_pubkey_spec_ecdh, + &_gcry_pubkey_spec_ecc, #endif #if USE_RSA &_gcry_pubkey_spec_rsa, @@ -55,6 +54,21 @@ static gcry_pk_spec_t *pubkey_list[] = }; +static int +map_algo (int algo) +{ + switch (algo) + { + case GCRY_PK_ECDSA: + case GCRY_PK_ECDH: + return GCRY_PK_ECC; + default: + return algo; + } +} + + + /* Return the spec structure for the public key algorithm ALGO. For an unknown algorithm NULL is returned. */ static gcry_pk_spec_t * @@ -63,6 +77,8 @@ spec_from_algo (int algo) int idx; gcry_pk_spec_t *spec; + algo = map_algo (algo); + for (idx = 0; (spec = pubkey_list[idx]); idx++) if (algo == spec->algo) return spec; @@ -2156,7 +2172,9 @@ gcry_pk_get_param (int algo, const char *name) gcry_sexp_t result = NULL; gcry_pk_spec_t *spec = NULL; - if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH) + algo = map_algo (algo); + + if (algo != GCRY_PK_ECC) return NULL; spec = spec_from_name ("ecc"); @@ -2334,13 +2352,17 @@ gpg_error_t _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report) { gcry_err_code_t ec; - gcry_pk_spec_t *spec = spec_from_algo (algo); + gcry_pk_spec_t *spec; + algo = map_algo (algo); + spec = spec_from_algo (algo); if (spec && spec->selftest) ec = spec->selftest (algo, extended, report); else { ec = GPG_ERR_PUBKEY_ALGO; + /* Fixme: We need to change the report fucntion to allow passing + of an encryption mode (e.g. pkcs1, ecdsa, or ecdh). */ if (report) report ("pubkey", algo, "module", spec && !spec->flags.disabled? diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 4c1485c..5d1be8d 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -2124,9 +2124,10 @@ The point representing the public key @math{Q = dG}. The private key @math{d} @end table -All point values are encoded in standard format; Libgcrypt does -currently only support uncompressed points, thus the first byte needs to -be @code{0x04}. +All point values are encoded in standard format; Libgcrypt does in +general only support uncompressed points, thus the first byte needs to +be @code{0x04}. However ``EdDSA'' describes its own compression +scheme which is used by default. The public key is similar with "private-key" replaced by "public-key" and no @var{d-mpi}. @@ -2200,6 +2201,10 @@ for signing. Use RSA-OAEP padding for encryption. @item pss Use RSA-PSS padding for signing. + at item eddsa +Use the EdDSA scheme instead of ECDSA. + at item rfc6979 +For DSA and ECDSA use a deterministic scheme for the k parameter. @item no-blinding Do not use a technique called `blinding', which is used by default in order to prevent leaking of secret information. Blinding is only @@ -2680,11 +2685,11 @@ are allowed. When specifying Q all values of N in the range 512 to 15680 are valid as long as they are multiples of 8. @item transient-key -This is only meaningful for RSA, DSA, ECDSA, and ECDH keys. This is a flag +This is only meaningful for RSA, DSA, and ECC keys. This is a flag with no value. If given the key is created using a faster and a -somewhat less secure random number generator. This flag may be used for -keys which are only used for a short time or per-message and do not require full -cryptographic strength. +somewhat less secure random number generator. This flag may be used +for keys which are only used for a short time or per-message and do +not require full cryptographic strength. @item domain This is only meaningful for DLP algorithms. If specified keys are diff --git a/src/cipher.h b/src/cipher.h index e3a2fe0..ea7a141 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -240,8 +240,7 @@ extern gcry_pk_spec_t _gcry_pubkey_spec_rsa; extern gcry_pk_spec_t _gcry_pubkey_spec_elg; extern gcry_pk_spec_t _gcry_pubkey_spec_elg_e; extern gcry_pk_spec_t _gcry_pubkey_spec_dsa; -extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa; -extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh; +extern gcry_pk_spec_t _gcry_pubkey_spec_ecc; #endif /*G10_CIPHER_H*/ diff --git a/src/fips.c b/src/fips.c index e45baba..11b2caa 100644 --- a/src/fips.c +++ b/src/fips.c @@ -546,7 +546,7 @@ run_pubkey_selftests (int extended) { GCRY_PK_RSA, GCRY_PK_DSA, - /* GCRY_PK_ECDSA is not enabled in fips mode. */ + /* GCRY_PK_ECC is not enabled in fips mode. */ 0 }; int idx; diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 3634c24..62c9721 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -978,9 +978,10 @@ enum gcry_pk_algos GCRY_PK_RSA_S = 3, /* (deprecated) */ GCRY_PK_ELG_E = 16, GCRY_PK_DSA = 17, + GCRY_PK_ECC = 18, /* Generic ECC. */ GCRY_PK_ELG = 20, - GCRY_PK_ECDSA = 301, - GCRY_PK_ECDH = 302 + GCRY_PK_ECDSA = 301, /* (deprecated: use 18). */ + GCRY_PK_ECDH = 302 /* (deprecated: use 18). */ }; /* Flags describing usage capabilities of a PK algorithm. */ ----------------------------------------------------------------------- Summary of changes: NEWS | 4 +++ cipher/ecc.c | 62 ++++++++++++------------------------------------------ cipher/pubkey.c | 30 +++++++++++++++++++++++--- doc/gcrypt.texi | 19 ++++++++++------ src/cipher.h | 3 +- src/fips.c | 2 +- src/gcrypt.h.in | 5 ++- 7 files changed, 61 insertions(+), 64 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Tue Sep 24 15:16:14 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 24 Sep 2013 15:16:14 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-267-gdf013c9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via df013c9820709421ef9550158ac5df0060d73379 (commit) from d5f91466695c5736f441c9bf1998436184a4bf61 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit df013c9820709421ef9550158ac5df0060d73379 Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 ecc: Allow the use of an uncompressed public key. * cipher/ecc.c (eddsa_encodepoint): Factor most code out to ... (eddsa_encode_x_y): new fucntion. (eddsa_decodepoint): Allow use of an uncompressed public key. * tests/t-ed25519.c (N_TESTS): Adjust. * tests/t-ed25519.inp: Add test 1025. diff --git a/cipher/ecc.c b/cipher/ecc.c index d31b4be..82d5bba 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -606,24 +606,17 @@ eddsa_encodempi (gcry_mpi_t mpi, unsigned int minlen, } -/* Encode POINT using the EdDSA scheme. X and Y are scratch variables - supplied by the caller and CTX is the usual context. MINLEN is the - required length in bytes for the result. On success 0 is returned - an a malloced buffer with the encoded point is stored at R_BUFFER; - the length of this buffer is stored at R_BUFLEN. */ +/* Encode (X,Y) using the EdDSA scheme. MINLEN is the required length + in bytes for the result. On success 0 is returned and a malloced + buffer with the encoded point is stored at R_BUFFER; the length of + this buffer is stored at R_BUFLEN. */ static gpg_err_code_t -eddsa_encodepoint (mpi_point_t point, unsigned int minlen, mpi_ec_t ctx, - gcry_mpi_t x, gcry_mpi_t y, - unsigned char **r_buffer, unsigned int *r_buflen) +eddsa_encode_x_y (gcry_mpi_t x, gcry_mpi_t y, unsigned int minlen, + unsigned char **r_buffer, unsigned int *r_buflen) { unsigned char *rawmpi; unsigned int rawmpilen; - if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) - { - log_error ("eddsa_encodepoint: Failed to get affine coordinates\n"); - return GPG_ERR_INTERNAL; - } rawmpi = _gcry_mpi_get_buffer (y, minlen, &rawmpilen, NULL); if (!rawmpi) return gpg_err_code_from_syserror (); @@ -635,12 +628,30 @@ eddsa_encodepoint (mpi_point_t point, unsigned int minlen, mpi_ec_t ctx, return 0; } +/* Encode POINT using the EdDSA scheme. X and Y are scratch variables + supplied by the caller and CTX is the usual context. MINLEN is the + required length in bytes for the result. On success 0 is returned + and a malloced buffer with the encoded point is stored at R_BUFFER; + the length of this buffer is stored at R_BUFLEN. */ +static gpg_err_code_t +eddsa_encodepoint (mpi_point_t point, unsigned int minlen, mpi_ec_t ctx, + gcry_mpi_t x, gcry_mpi_t y, + unsigned char **r_buffer, unsigned int *r_buflen) +{ + if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) + { + log_error ("eddsa_encodepoint: Failed to get affine coordinates\n"); + return GPG_ERR_INTERNAL; + } + return eddsa_encode_x_y (x, y, minlen, r_buffer, r_buflen); +} + /* Decode the EdDSA style encoded PK and set it into RESULT. LEN is the expected length in bytes of the encoded key and CTX the usual curve context. If R_ENCPK is not NULL, the encoded PK is stored at - that address; this is a new copy to be release by the caller. In - contrast to the supplied PK, this is not an MPI and thus guarnteed + that address; this is a new copy to be released by the caller. In + contrast to the supplied PK, this is not an MPI and thus guarnateed to be properly padded. R_ENCPKLEN received the length of that encoded key. */ static gpg_err_code_t @@ -648,6 +659,7 @@ eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx, mpi_point_t result, unsigned char **r_encpk, unsigned int *r_encpklen) { + gpg_err_code_t rc; unsigned char *rawmpi; unsigned int rawmpilen; gcry_mpi_t yy, t, x, p1, p2, p3; @@ -655,12 +667,50 @@ eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx, if (mpi_is_opaque (pk)) { - const void *buf; + const unsigned char *buf; buf = gcry_mpi_get_opaque (pk, &rawmpilen); if (!buf) return GPG_ERR_INV_OBJ; rawmpilen = (rawmpilen + 7)/8; + + /* First check whether the public key has been given in standard + uncompressed format. No need to recover x in this case. + Detection is easy: The size of the buffer will be odd and the + first byte be 0x04. */ + if (rawmpilen > 1 && buf[0] == 0x04 && (rawmpilen%2)) + { + gcry_mpi_t y; + + rc = gcry_mpi_scan (&x, GCRYMPI_FMT_STD, + buf+1, (rawmpilen-1)/2, NULL); + if (rc) + return rc; + rc = gcry_mpi_scan (&y, GCRYMPI_FMT_STD, + buf+1+(rawmpilen-1)/2, (rawmpilen-1)/2, NULL); + if (rc) + { + mpi_free (x); + return rc; + } + + if (r_encpk) + { + rc = eddsa_encode_x_y (x, y, len, r_encpk, r_encpklen); + if (rc) + { + mpi_free (x); + mpi_free (y); + return rc; + } + } + mpi_snatch (result->x, x); + mpi_snatch (result->y, y); + mpi_set_ui (result->z, 1); + return 0; + } + + /* EdDSA compressed point. */ rawmpi = gcry_malloc (rawmpilen? rawmpilen:1); if (!rawmpi) return gpg_err_code_from_syserror (); @@ -669,6 +719,9 @@ eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx, } else { + /* Note: Without using an opaque MPI it is not reliable possible + to find out whether the public key has been given in + uncompressed format. Thus we expect EdDSA format here. */ rawmpi = _gcry_mpi_get_buffer (pk, len, &rawmpilen, NULL); if (!rawmpi) return gpg_err_code_from_syserror (); diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c index f816fda..0a6ae14 100644 --- a/tests/t-ed25519.c +++ b/tests/t-ed25519.c @@ -32,7 +32,7 @@ #include "stopwatch.h" #define PGM "t-ed25519" -#define N_TESTS 1024 +#define N_TESTS 1025 #define my_isascii(c) (!((c) & 0x80)) #define digitp(p) (*(p) >= '0' && *(p) <= '9') @@ -460,7 +460,9 @@ check_ed25519 (void) xfree (sig); if (ntests != N_TESTS) - fail ("did %d tests but expected %s", ntests, N_TESTS); + fail ("did %d tests but expected %d", ntests, N_TESTS); + else if ((ntests % 256)) + show_note ("%d tests done\n", ntests); fclose (fp); xfree (fname); diff --git a/tests/t-ed25519.inp b/tests/t-ed25519.inp index 5da0d6e..61387c4 100644 --- a/tests/t-ed25519.inp +++ b/tests/t-ed25519.inp @@ -2,13 +2,14 @@ # This has been taken from # http://ed25519.cr.yp.to/python/sign.input # which distributed them as public domain. -# For our use converted using this schript: +# For our use converted using this script: # awk -F: 'BEGIN {n=1} { print "TST: " n; n++; \ # print "SK: " substr($1,0,64); print "PK: " $2;\ # print "MSG: " $3; print "SIG: " substr($4,0,128); print ""}' # # The PK appended to the SK and the MSG appended to the SIG have been -# stripped. +# stripped. A few additional tests have been added to the 1024 +# original tests. TST: 1 SK: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 @@ -6153,3 +6154,11 @@ SK: f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5 PK: 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e MSG: 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0 SIG: 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03 + +# Now an additional test with the data from test 1 but using an +# uncompressed public key. +TST: 1025 +SK: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 +PK: 0455d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7 +MSG: +SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 85 +++++++++++++++++++++++++++++++++++++++++--------- tests/t-ed25519.c | 6 ++- tests/t-ed25519.inp | 13 ++++++- 3 files changed, 84 insertions(+), 20 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From dbaryshkov at gmail.com Tue Sep 24 21:48:14 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Tue, 24 Sep 2013 23:48:14 +0400 Subject: Suspicious about sign_ecdsa Message-ID: Hello, While implementing GOST EC signatures, I stumbled upon sign_edsa() function. It contains two nested while() loops and a comment regarding inner (generate k, compute r loop) that is is a while and not do_while, because we don't want to recompute r. This made me extremely suspicious. It looks to me like a possible endless loop. If generated k makes r != 0, but s = 0, sign_ecdsa will loop forever, as code outside while (r != 0) loop does not contain any non-deterministic option. In my opinion, the code should look this way: while (s != 0) { do { k = generate(); r = calculate(k); } while (r != 0) s = calculate(r, k); } What is your opinion? -- With best wishes Dmitry From cvs at cvs.gnupg.org Wed Sep 25 09:35:44 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 25 Sep 2013 09:35:44 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-268-g1f5f445 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 1f5f4452e5bca105ec2197a4facbf9778e7dc31e (commit) from df013c9820709421ef9550158ac5df0060d73379 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1f5f4452e5bca105ec2197a4facbf9778e7dc31e Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 ecc: Fix highly unlikely endless loop in sign_ecdsa. * cipher/ecc.c (sign_ecdsa): Turn while-do into do-while loops. -- Reported-by: Dmitry Eremin-Solenikov Signed-off-by: Werner Koch diff --git a/cipher/ecc.c b/cipher/ecc.c index 82d5bba..0b89ec2 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -408,21 +408,16 @@ sign_ecdsa (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s, x = mpi_alloc (0); point_init (&I); - mpi_set_ui (s, 0); - mpi_set_ui (r, 0); - ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, skey->E.p, skey->E.a, skey->E.b); - while (!mpi_cmp_ui (s, 0)) /* s == 0 */ + /* Two loops to avoid R or S are zero. This is more of a joke than + a real demand because the probability of them being zero is less + than any hardware failure. Some specs however require it. */ + do { - while (!mpi_cmp_ui (r, 0)) /* r == 0 */ + do { - /* Note, that we are guaranteed to enter this loop at least - once because r has been intialized to 0. We can't use a - do_while because we want to keep the value of R even if S - has to be recomputed. */ - mpi_free (k); k = NULL; if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo) @@ -458,11 +453,14 @@ sign_ecdsa (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s, } mpi_mod (r, x, skey->E.n); /* r = x mod n */ } + while (!mpi_cmp_ui (r, 0)); + mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */ mpi_addm (sum, hash, dr, skey->E.n); /* sum = hash + (d*r) mod n */ mpi_invm (k_1, k, skey->E.n); /* k_1 = k^(-1) mod n */ mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */ } + while (!mpi_cmp_ui (s, 0)); if (DBG_CIPHER) { ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 18 ++++++++---------- 1 files changed, 8 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From wk at gnupg.org Wed Sep 25 09:02:36 2013 From: wk at gnupg.org (Werner Koch) Date: Wed, 25 Sep 2013 09:02:36 +0200 Subject: Suspicious about sign_ecdsa In-Reply-To: (Dmitry Eremin-Solenikov's message of "Tue, 24 Sep 2013 23:48:14 +0400") References: Message-ID: <87r4cdidtf.fsf@vigenere.g10code.de> On Tue, 24 Sep 2013 21:48, dbaryshkov at gmail.com said: > This made me extremely suspicious. It looks to me like a possible endless loop. > If generated k makes r != 0, but s = 0, sign_ecdsa will loop forever, as code > outside while (r != 0) loop does not contain any non-deterministic option. You are right. However, the case of either of them being zero is very unlikely, so that implementation may do it with out any check. Given the unlikeliness my comment about the need to keep R is also bogus. I just pushed the suggested fix to master. Backporting is not justified. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From gniibe at fsij.org Wed Sep 25 09:57:36 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Wed, 25 Sep 2013 16:57:36 +0900 Subject: Suspicious about sign_ecdsa In-Reply-To: <87r4cdidtf.fsf@vigenere.g10code.de> References: <87r4cdidtf.fsf@vigenere.g10code.de> Message-ID: <1380095856.3340.71.camel@cfw2.gniibe.org> Very minor thing. While I read the function (sign_ecdsa of ecc.c), I think that the error code of following part is not appropriate. if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx)) { if (DBG_CIPHER) log_debug ("ecc sign: Failed to get affine coordinates\n"); err = GPG_ERR_BAD_SIGNATURE; goto leave; } This error occurs only if we have coding error or the curve is invalid (... or hardware error). GPG_ERR_INTERNAL would be appropriate. -- From wk at gnupg.org Wed Sep 25 12:50:08 2013 From: wk at gnupg.org (Werner Koch) Date: Wed, 25 Sep 2013 12:50:08 +0200 Subject: Suspicious about sign_ecdsa In-Reply-To: <1380095856.3340.71.camel@cfw2.gniibe.org> (NIIBE Yutaka's message of "Wed, 25 Sep 2013 16:57:36 +0900") References: <87r4cdidtf.fsf@vigenere.g10code.de> <1380095856.3340.71.camel@cfw2.gniibe.org> Message-ID: <87fvsti3a7.fsf@vigenere.g10code.de> On Wed, 25 Sep 2013 09:57, gniibe at fsij.org said: > This error occurs only if we have coding error or the curve is > invalid (... or hardware error). > > GPG_ERR_INTERNAL would be appropriate. Right. Here we have no tainted data here. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Wed Sep 25 18:51:06 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Wed, 25 Sep 2013 20:51:06 +0400 Subject: Testing ECC signatures Message-ID: Hello, I'm currently looking at the ways to add tests for my ECC signatures algo. As far as I understand, gcrypt test suite does only the sign-verify test. However if both sign and verify contains errors, the test can result false positive result. What I would like to have is a way to check sign and/or verify functions separately. For verify I can add a list of valid and invalid signatures and check them one-by-one. I'm more struggling about verification of sign() function. DSA, ECDSA and gost signature algorithms use generated random value. I would like to pass a pre-defined "random-override" value (like it is done for several RSA padding modes). However I see no simple way to pass that further to ecc_sign (in my case) function. What would you suggest? Should I just wait till pubkey internal interface changes to move S-Exp processing directly to algorithms (if I understood correctly andthat is the way the code base currently moves)? -- With best wishes Dmitry From wk at gnupg.org Wed Sep 25 20:51:16 2013 From: wk at gnupg.org (Werner Koch) Date: Wed, 25 Sep 2013 20:51:16 +0200 Subject: Testing ECC signatures In-Reply-To: (Dmitry Eremin-Solenikov's message of "Wed, 25 Sep 2013 20:51:06 +0400") References: Message-ID: <87pprwg2fv.fsf@vigenere.g10code.de> On Wed, 25 Sep 2013 18:51, dbaryshkov at gmail.com said: > "random-override" value (like it is done for several RSA padding modes). > However I see no simple way to pass that further to ecc_sign (in my > case) function. For ECC I suggest to use the rfc6979 flag, which creates deterministic signatures. > interface changes to > move S-Exp processing directly to algorithms (if I understood > correctly andthat is > the way the code base currently moves)? Yes, that is what I am working on. In general I don't like the idea of having a feature to override random, because that could easily slip into the real code path. But sometimes these things are required for certification purposes. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Wed Sep 25 18:48:22 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 25 Sep 2013 18:48:22 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-273-g1c6660d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 1c6660debdbf1e4c3e80074c846a3e3097f214bb (commit) via 9b7c49971588edf6acfc74bfb797eb79d19cb350 (commit) via d6683d2a6065986a9198d2d2eaa02c005b68cea4 (commit) via 9a4447ccd1b90bcd701941e80a7f484a1825fcea (commit) via 64a7d347847d606eb5f4c156e24ba060271b8f6b (commit) from 1f5f4452e5bca105ec2197a4facbf9778e7dc31e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1c6660debdbf1e4c3e80074c846a3e3097f214bb Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 mpi: Change not yet used _gcry_mpi_set_opaque_copy. * mpi/mpiutil.c (_gcry_mpi_set_opaque_copy): Change prototype. (_gcry_mpi_get_opaque_copy): Take care of gcry_malloc failure. diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index 3855dc4..c9e6b31 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -283,13 +283,15 @@ gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits ) gcry_mpi_t -_gcry_mpi_set_opaque_copy (gcry_mpi_t a, void *p, unsigned int nbits) +_gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits) { void *d; unsigned int n; n = (nbits+7)/8; d = gcry_is_secure (p)? gcry_malloc_secure (n) : gcry_malloc (n); + if (!d) + return NULL; memcpy (d, p, n); return gcry_mpi_set_opaque (a, d, nbits); } @@ -318,7 +320,8 @@ _gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits) return NULL; n = (*nbits+7)/8; d = gcry_is_secure (s)? gcry_malloc_secure (n) : gcry_malloc (n); - memcpy (d, s, n); + if (d) + memcpy (d, s, n); return d; } diff --git a/src/mpi.h b/src/mpi.h index 279c485..780d5eb 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -135,7 +135,7 @@ void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b); gcry_mpi_t _gcry_mpi_new (unsigned int nbits); gcry_mpi_t _gcry_mpi_snew (unsigned int nbits); gcry_mpi_t _gcry_mpi_set_opaque_copy (gcry_mpi_t a, - void *p, unsigned int nbits); + const void *p, unsigned int nbits); void *_gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits); int _gcry_mpi_is_neg (gcry_mpi_t a); void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u); commit 9b7c49971588edf6acfc74bfb797eb79d19cb350 Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 sexp: Improve printing of data with a leading zero. * src/sexp.c (suitable_encoding): Detect leading zero byte. diff --git a/src/sexp.c b/src/sexp.c index 54d0c4a..6a2a9be 100644 --- a/src/sexp.c +++ b/src/sexp.c @@ -1725,6 +1725,8 @@ suitable_encoding (const unsigned char *buffer, size_t length) if (*buffer & 0x80) return 0; /* If the MSB is set we assume that buffer represents a negative number. */ + if (!*buffer) + return 0; /* Starting with a zero is pretty much a binary string. */ for (s=buffer; length; s++, length--) { commit d6683d2a6065986a9198d2d2eaa02c005b68cea4 Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 ecc: Allow the name "q at eddsa" to get/set the public key. * cipher/ecc-curves.c (_gcry_ecc_get_mpi): Support "q at eddsa". (_gcry_ecc_set_mpi): Support "q". * cipher/ecc.c (eddsa_encodepoint): Rename to ... (_gcry_ecc_eddsa_encodepoint): this and make global. Remove arg MINLEN and take from context. (eddsa_decodepoint): Rename to (_gcry_ecc_eddsa_decodepoint): this and make global. Remove arg LEN and take from context. (sign_eddsa, verify_eddsa): Take B from context. (ecc_sign, ecc_verify): Add hack to set DIALECT. (_gcry_pk_ecc_get_sexp): Use _gcry_ecc_compute_public. Handle EdDSA. * src/ec-context.h (mpi_ec_ctx_s): Add field NBITS. * mpi/ec.c (ec_p_init): Init NBITS. * tests/t-mpi-point.c (test_curve): Add Ed25519. (sample_ed25519_q): New. (context_param): Check new sample key. (hex2buffer, hex2mpiopa): New. (cmp_mpihex): Take care of opaque MPIs. Signed-off-by: Werner Koch diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h index 031994a..cdb1362 100644 --- a/cipher/ecc-common.h +++ b/cipher/ecc-common.h @@ -84,5 +84,15 @@ gcry_error_t _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value); mpi_point_t _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec); +/*-- ecc.c --*/ +gpg_err_code_t _gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ctx, + gcry_mpi_t x, gcry_mpi_t y, + unsigned char **r_buffer, + unsigned int *r_buflen); +gpg_err_code_t _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, + mpi_point_t result, + unsigned char **r_encpk, + unsigned int *r_encpklen); + #endif /*GCRY_ECC_COMMON_H*/ diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index e6a993f..7447340 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -812,6 +812,9 @@ _gcry_ecc_get_param_sexp (const char *name) gcry_mpi_t _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) { + if (!*name) + return NULL; + if (!strcmp (name, "p") && ec->p) return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p); if (!strcmp (name, "a") && ec->a) @@ -833,17 +836,35 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) if (!strcmp (name, "q.y") && ec->Q && ec->Q->y) return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y); - /* If a point has been requested, return it in standard encoding. */ + /* If the base point has been requested, return it in standard + encoding. */ if (!strcmp (name, "g") && ec->G) return _gcry_mpi_ec_ec2os (ec->G, ec); - if (!strcmp (name, "q")) + + /* If the public key has been requested, return it by default in + standard uncompressed encoding or if requested in other + encodings. */ + if (*name == 'q' && (!name[1] || name[1] == '@')) { /* If only the private key is given, compute the public key. */ if (!ec->Q) ec->Q = _gcry_ecc_compute_public (NULL, ec); - if (ec->Q) + if (!ec->Q) + return NULL; + + if (name[1] != '@') return _gcry_mpi_ec_ec2os (ec->Q, ec); + + if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_TWISTEDEDWARDS) + { + unsigned char *encpk; + unsigned int encpklen; + + if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, + &encpk, &encpklen)) + return gcry_mpi_set_opaque (NULL, encpk, encpklen*8); + } } return NULL; @@ -874,7 +895,11 @@ _gcry_ecc_get_point (const char *name, mpi_ec_t ec) gpg_err_code_t _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) { - if (!strcmp (name, "p")) + gpg_err_code_t rc = 0; + + if (!*name) + ; + else if (!strcmp (name, "p")) { mpi_free (ec->p); ec->p = mpi_copy (newvalue); @@ -896,15 +921,40 @@ _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) mpi_free (ec->n); ec->n = mpi_copy (newvalue); } + else if (*name == 'q' && (!name[1] || name[1] == '@')) + { + if (newvalue) + { + if (!ec->Q) + ec->Q = gcry_mpi_point_new (0); + if (ec->dialect == ECC_DIALECT_ED25519) + rc = _gcry_ecc_eddsa_decodepoint (newvalue, ec, ec->Q, NULL, NULL); + else + rc = _gcry_ecc_os2ec (ec->Q, newvalue); + } + if (rc || !newvalue) + { + gcry_mpi_point_release (ec->Q); + ec->Q = NULL; + } + /* Note: We assume that Q matches d and thus do not reset d. */ + } else if (!strcmp (name, "d")) { mpi_free (ec->d); ec->d = mpi_copy (newvalue); + if (ec->d) + { + /* We need to reset the public key because it may not + anymore match. */ + gcry_mpi_point_release (ec->Q); + ec->Q = NULL; + } } else - return GPG_ERR_UNKNOWN_NAME; + rc = GPG_ERR_UNKNOWN_NAME; - return 0; + return rc; } diff --git a/cipher/ecc.c b/cipher/ecc.c index 0b89ec2..abd501f 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -626,36 +626,47 @@ eddsa_encode_x_y (gcry_mpi_t x, gcry_mpi_t y, unsigned int minlen, return 0; } -/* Encode POINT using the EdDSA scheme. X and Y are scratch variables - supplied by the caller and CTX is the usual context. MINLEN is the - required length in bytes for the result. On success 0 is returned - and a malloced buffer with the encoded point is stored at R_BUFFER; - the length of this buffer is stored at R_BUFLEN. */ -static gpg_err_code_t -eddsa_encodepoint (mpi_point_t point, unsigned int minlen, mpi_ec_t ctx, - gcry_mpi_t x, gcry_mpi_t y, - unsigned char **r_buffer, unsigned int *r_buflen) +/* Encode POINT using the EdDSA scheme. X and Y are either scratch + variables supplied by the caller or NULL. CTX is the usual + context. On success 0 is returned and a malloced buffer with the + encoded point is stored at R_BUFFER; the length of this buffer is + stored at R_BUFLEN. */ +gpg_err_code_t +_gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ec, + gcry_mpi_t x_in, gcry_mpi_t y_in, + unsigned char **r_buffer, unsigned int *r_buflen) { - if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) + gpg_err_code_t rc; + gcry_mpi_t x, y; + + x = x_in? x_in : mpi_new (0); + y = y_in? y_in : mpi_new (0); + + if (_gcry_mpi_ec_get_affine (x, y, point, ec)) { log_error ("eddsa_encodepoint: Failed to get affine coordinates\n"); - return GPG_ERR_INTERNAL; + rc = GPG_ERR_INTERNAL; } - return eddsa_encode_x_y (x, y, minlen, r_buffer, r_buflen); + else + rc = eddsa_encode_x_y (x, y, ec->nbits/8, r_buffer, r_buflen); + + if (!x_in) + mpi_free (x); + if (!y_in) + mpi_free (y); + return rc; } -/* Decode the EdDSA style encoded PK and set it into RESULT. LEN is - the expected length in bytes of the encoded key and CTX the usual - curve context. If R_ENCPK is not NULL, the encoded PK is stored at - that address; this is a new copy to be released by the caller. In - contrast to the supplied PK, this is not an MPI and thus guarnateed - to be properly padded. R_ENCPKLEN received the length of that - encoded key. */ -static gpg_err_code_t -eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx, - mpi_point_t result, - unsigned char **r_encpk, unsigned int *r_encpklen) +/* Decode the EdDSA style encoded PK and set it into RESULT. CTX is + the usual curve context. If R_ENCPK is not NULL, the encoded PK is + stored at that address; this is a new copy to be released by the + caller. In contrast to the supplied PK, this is not an MPI and + thus guarnateed to be properly padded. R_ENCPKLEN received the + length of that encoded key. */ +gpg_err_code_t +_gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result, + unsigned char **r_encpk, unsigned int *r_encpklen) { gpg_err_code_t rc; unsigned char *rawmpi; @@ -694,7 +705,7 @@ eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx, if (r_encpk) { - rc = eddsa_encode_x_y (x, y, len, r_encpk, r_encpklen); + rc = eddsa_encode_x_y (x, y, ctx->nbits/8, r_encpk, r_encpklen); if (rc) { mpi_free (x); @@ -720,7 +731,7 @@ eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx, /* Note: Without using an opaque MPI it is not reliable possible to find out whether the public key has been given in uncompressed format. Thus we expect EdDSA format here. */ - rawmpi = _gcry_mpi_get_buffer (pk, len, &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL); if (!rawmpi) return gpg_err_code_from_syserror (); } @@ -896,7 +907,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, { int rc; mpi_ec_t ctx = NULL; - int b = 256/8; /* The only size we currently support. */ + int b; unsigned int tmp; unsigned char hash_d[64]; /* Fixme: malloc in secure memory */ unsigned char digest[64]; @@ -927,6 +938,10 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, r = mpi_new (0); ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, skey->E.p, skey->E.a, skey->E.b); + b = ctx->nbits/8; + if (b != 256/8) + return GPG_ERR_INTERNAL; /* We only support 256 bit. */ + /* Hash the secret key. We clear DIGEST so we can use it to left pad the key with zeroes for hashing. */ @@ -959,7 +974,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, parameter. */ if (pk) { - rc = eddsa_decodepoint (pk, b, ctx, &Q, &encpk, &encpklen); + rc = _gcry_ecc_eddsa_decodepoint (pk, ctx, &Q, &encpk, &encpklen); if (rc) goto leave; if (DBG_CIPHER) @@ -973,7 +988,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, else { _gcry_mpi_ec_mul_point (&Q, a, &skey->E.G, ctx); - rc = eddsa_encodepoint (&Q, b, ctx, x, y, &encpk, &encpklen); + rc = _gcry_ecc_eddsa_encodepoint (&Q, ctx, x, y, &encpk, &encpklen); if (rc) goto leave; if (DBG_CIPHER) @@ -1003,7 +1018,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, log_printpnt (" r", &I, ctx); /* Convert R into affine coordinates and apply encoding. */ - rc = eddsa_encodepoint (&I, b, ctx, x, y, &rawmpi, &rawmpilen); + rc = _gcry_ecc_eddsa_encodepoint (&I, ctx, x, y, &rawmpi, &rawmpilen); if (rc) goto leave; if (DBG_CIPHER) @@ -1067,7 +1082,7 @@ verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey, { int rc; mpi_ec_t ctx = NULL; - int b = 256/8; /* The only size we currently support. */ + int b; unsigned int tmp; mpi_point_struct Q; /* Public key. */ unsigned char *encpk = NULL; /* Encoded public key. */ @@ -1094,9 +1109,12 @@ verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey, ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, pkey->E.p, pkey->E.a, pkey->E.b); + b = ctx->nbits/8; + if (b != 256/8) + return GPG_ERR_INTERNAL; /* We only support 256 bit. */ /* Decode and check the public key. */ - rc = eddsa_decodepoint (pk, b, ctx, &Q, &encpk, &encpklen); + rc = _gcry_ecc_eddsa_decodepoint (pk, ctx, &Q, &encpk, &encpklen); if (rc) goto leave; if (!_gcry_mpi_ec_curve_point (&Q, ctx)) @@ -1170,7 +1188,7 @@ verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey, _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx); _gcry_mpi_neg (Ib.x, Ib.x); _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx); - rc = eddsa_encodepoint (&Ia, b, ctx, s, h, &tbuf, &tlen); + rc = _gcry_ecc_eddsa_encodepoint (&Ia, ctx, s, h, &tbuf, &tlen); if (rc) goto leave; if (tlen != rlen || memcmp (tbuf, rbuf, tlen)) @@ -1301,7 +1319,7 @@ ecc_generate (int algo, unsigned int nbits, unsigned long evalue, unsigned char *encpk; unsigned int encpklen; - rc = eddsa_encodepoint (&sk.Q, 256/8, ctx, x, y, &encpk, &encpklen); + rc = _gcry_ecc_eddsa_encodepoint (&sk.Q, ctx, x, y, &encpk, &encpklen); if (rc) return rc; public = mpi_new (0); @@ -1443,9 +1461,15 @@ ecc_sign (int algo, gcry_sexp_t *r_result, gcry_mpi_t data, gcry_mpi_t *skey, || !skey[6] ) return GPG_ERR_BAD_MPI; + /* FIXME: The setting of model and dialect are crude hacks. We will + fix that by moving the s-expression parsing from pubkey.c to + here. */ sk.E.model = ((flags & PUBKEY_FLAG_EDDSA) ? MPI_EC_TWISTEDEDWARDS : MPI_EC_WEIERSTRASS); + sk.E.dialect = ((flags & PUBKEY_FLAG_EDDSA) + ? ECC_DIALECT_ED25519 + : ECC_DIALECT_STANDARD); sk.E.p = skey[0]; sk.E.a = skey[1]; sk.E.b = skey[2]; @@ -1525,9 +1549,15 @@ ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, || !pkey[3] || !pkey[4] || !pkey[5] ) return GPG_ERR_BAD_MPI; + /* FIXME: The setting of model and dialect are crude hacks. We will + fix that by moving the s-expression parsing from pubkey.c to + here. */ pk.E.model = ((flags & PUBKEY_FLAG_EDDSA) ? MPI_EC_TWISTEDEDWARDS : MPI_EC_WEIERSTRASS); + pk.E.dialect = ((flags & PUBKEY_FLAG_EDDSA) + ? ECC_DIALECT_ED25519 + : ECC_DIALECT_STANDARD); pk.E.p = pkey[0]; pk.E.a = pkey[1]; pk.E.b = pkey[2]; @@ -1922,7 +1952,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) Low-level API helper functions. */ -/* This is the wroker function for gcry_pubkey_get_sexp for ECC +/* This is the worker function for gcry_pubkey_get_sexp for ECC algorithms. Note that the caller has already stored NULL at R_SEXP. */ gpg_err_code_t @@ -1940,10 +1970,7 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec) /* Compute the public point if it is missing. */ if (!ec->Q && ec->d) - { - ec->Q = gcry_mpi_point_new (0); - _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec); - } + ec->Q = _gcry_ecc_compute_public (NULL, ec); /* Encode G and Q. */ mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec); @@ -1957,7 +1984,23 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec) rc = GPG_ERR_BAD_CRYPT_CTX; goto leave; } - mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec); + + if (ec->dialect == ECC_DIALECT_ED25519) + { + unsigned char *encpk; + unsigned int encpklen; + + rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, + &encpk, &encpklen); + if (rc) + goto leave; + mpi_Q = gcry_mpi_set_opaque (NULL, encpk, encpklen*8); + encpk = NULL; + } + else + { + mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec); + } if (!mpi_Q) { rc = GPG_ERR_BROKEN_PUBKEY; diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 5d1be8d..0590a26 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -4182,10 +4182,16 @@ modified, it is suggested to pass @code{1} to @var{copy}, so that the function guarantees that a modifiable copy of the MPI is returned. If @code{0} is used for @var{copy}, this function may return a constant flagged MPI. In any case @code{gcry_mpi_release} needs to be called -to release the result. For valid names @ref{ecc_keyparam}. If a -point parameter is requested it is returned as an uncompressed encoded -point. If the public key @code{q} is requested but only the private -key @code{d} is available, @code{q} will be recomputed on the fly. +to release the result. For valid names @ref{ecc_keyparam}. If the +public key @code{q} is requested but only the private key @code{d} is +available, @code{q} will be recomputed on the fly. If a point +parameter is requested it is returned as an uncompressed +encoded point unless these special names are used: + at table @var + at item q@@eddsa +Return an EdDSA style compressed point. This is only supported for +Twisted Edwards curves. + at end table @end deftypefun @deftypefun gcry_mpi_point_t gcry_mpi_ec_get_point ( @ diff --git a/mpi/ec.c b/mpi/ec.c index 883d8f6..c6d0fc8 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -436,6 +436,10 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model, ctx->model = model; ctx->dialect = dialect; + if (dialect == ECC_DIALECT_ED25519) + ctx->nbits = 256; + else + ctx->nbits = mpi_get_nbits (p); ctx->p = mpi_copy (p); ctx->a = mpi_copy (a); if (b && model == MPI_EC_TWISTEDEDWARDS) diff --git a/src/ec-context.h b/src/ec-context.h index fdfbc0a..8dce7a7 100644 --- a/src/ec-context.h +++ b/src/ec-context.h @@ -27,6 +27,8 @@ struct mpi_ec_ctx_s enum ecc_dialects dialect; /* The ECC dialect used with the curve. */ + unsigned int nbits; /* Number of bits. */ + /* Domain parameters. Note that they may not all be set and if set the MPIs may be flaged as constant. */ gcry_mpi_t p; /* Prime specifying the field GF(p). */ diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 62c9721..5f49edc 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -726,7 +726,7 @@ void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); currently useless as no flags are allowed. */ void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); -/* Return true when the FLAG is set for A. */ +/* Return true if the FLAG is set for A. */ int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); /* Private function - do not use. */ diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 6683189..0641779 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -36,6 +36,14 @@ static int debug; static int error_count; +#define my_isascii(c) (!((c) & 0x80)) +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) #define xmalloc(a) gcry_xmalloc ((a)) #define xcalloc(a,b) gcry_xcalloc ((a),(b)) #define xfree(a) gcry_free ((a)) @@ -113,6 +121,15 @@ static struct "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" }, + { + "Ed25519", + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", + "-0x01", + "-0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4", + "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", + "0x6666666666666666666666666666666666666666666666666666666666666658" + }, { NULL, NULL, NULL, NULL, NULL } }; @@ -127,6 +144,20 @@ static const char sample_p256_q_y[] = "00E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; +/* A sample public key for Ed25519. */ +static const char sample_ed25519_q[] = + "04" + "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce" + "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7"; +static const char sample_ed25519_q_x[] = + "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce"; +static const char sample_ed25519_q_y[] = + "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7"; +static const char sample_ed25519_q_eddsa[] = + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; +static const char sample_ed25519_d[] = + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"; + static void show (const char *format, ...) @@ -241,7 +272,49 @@ hex2mpi (const char *string) err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); if (err) - die ("hex2mpi '%s' failed: %s\n", gpg_strerror (err)); + die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err)); + return val; +} + + +/* Convert STRING consisting of hex characters into its binary + representation and return it as an allocated buffer. The valid + length of the buffer is returned at R_LENGTH. The string is + delimited by end of string. The function returns NULL on + error. */ +static void * +hex2buffer (const char *string, size_t *r_length) +{ + const char *s; + unsigned char *buffer; + size_t length; + + buffer = xmalloc (strlen(string)/2+1); + length = 0; + for (s=string; *s; s +=2 ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + return NULL; /* Invalid hex digits. */ + ((unsigned char*)buffer)[length++] = xtoi_2 (s); + } + *r_length = length; + return buffer; +} + + +static gcry_mpi_t +hex2mpiopa (const char *string) +{ + char *buffer; + size_t buflen; + gcry_mpi_t val; + + buffer = hex2buffer (string, &buflen); + if (!buffer) + die ("hex2mpiopa '%s' failed: parser error\n", string); + val = gcry_mpi_set_opaque (NULL, buffer, buflen*8); + if (!buffer) + die ("hex2mpiopa '%s' failed: set_opaque error%s\n", string); return val; } @@ -253,7 +326,10 @@ cmp_mpihex (gcry_mpi_t a, const char *b) gcry_mpi_t bval; int res; - bval = hex2mpi (b); + if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + bval = hex2mpiopa (b); + else + bval = hex2mpi (b); res = gcry_mpi_cmp (a, bval); gcry_mpi_release (bval); return res; @@ -459,7 +535,7 @@ context_param (void) gpg_error_t err; int idx; gcry_ctx_t ctx = NULL; - gcry_mpi_t q; + gcry_mpi_t q, d; gcry_sexp_t keyparam; wherestr = "context_param"; @@ -492,13 +568,11 @@ context_param (void) continue; } - gcry_ctx_release (ctx); - - show ("checking sample public key\n"); + show ("checking sample public key (nistp256)\n"); q = hex2mpi (sample_p256_q); err = gcry_sexp_build (&keyparam, NULL, - "(public-key(ecdsa(curve %s)(q %m)))", + "(public-key(ecc(curve %s)(q %m)))", "NIST P-256", q); if (err) die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); @@ -511,18 +585,112 @@ context_param (void) /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ /* gpg_strerror (err)); */ + gcry_ctx_release (ctx); err = gcry_mpi_ec_new (&ctx, keyparam, NULL); if (err) - fail ("gcry_mpi_ec_new failed for sample public key: %s\n", + fail ("gcry_mpi_ec_new failed for sample public key (nistp256): %s\n", gpg_strerror (err)); else { gcry_sexp_t sexp; - get_and_cmp_mpi ("q", sample_p256_q, "NIST P-256", ctx); - get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "NIST P-256", + get_and_cmp_mpi ("q", sample_p256_q, "nistp256", ctx); + get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "nistp256", ctx); + /* Delete Q. */ + err = gcry_mpi_ec_set_mpi ("q", NULL, ctx); + if (err) + fail ("clearing Q for nistp256 failed: %s\n", gpg_strerror (err)); + if (gcry_mpi_ec_get_mpi ("q", ctx, 0)) + fail ("clearing Q for nistp256 did not work\n"); + + /* Set Q again. */ + q = hex2mpi (sample_p256_q); + err = gcry_mpi_ec_set_mpi ("q", q, ctx); + if (err) + fail ("setting Q for nistp256 failed: %s\n", gpg_strerror (err)); + get_and_cmp_mpi ("q", sample_p256_q, "nistp256(2)", ctx); + + /* Get as s-expression. */ + err = gcry_pubkey_get_sexp (&sexp, 0, ctx); + if (err) + fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); + else if (debug) + print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); + gcry_sexp_release (sexp); + + err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); + if (err) + fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", + gpg_strerror (err)); + else if (debug) + print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); + gcry_sexp_release (sexp); + + err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); + if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) + fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", + gpg_strerror (err)); + gcry_sexp_release (sexp); + } + + show ("checking sample public key (Ed25519)\n"); + q = hex2mpi (sample_ed25519_q); + gcry_sexp_release (keyparam); + err = gcry_sexp_build (&keyparam, NULL, + "(public-key(ecc(curve %s)(q %m)))", + "Ed25519", q); + if (err) + die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (q); + + /* We can't call gcry_pk_testkey because it is only implemented for + private keys. */ + /* err = gcry_pk_testkey (keyparam); */ + /* if (err) */ + /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ + /* gpg_strerror (err)); */ + + gcry_ctx_release (ctx); + err = gcry_mpi_ec_new (&ctx, keyparam, NULL); + if (err) + fail ("gcry_mpi_ec_new failed for sample public key: %s\n", + gpg_strerror (err)); + else + { + gcry_sexp_t sexp; + + get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519", ctx); + get_and_cmp_point ("q", sample_ed25519_q_x, sample_ed25519_q_y, + "Ed25519", ctx); + get_and_cmp_mpi ("q at eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx); + + /* Delete Q by setting d and the clearing d. The clearing is + required so that we can check whether Q has been cleared and + because further tests only expect a public key. */ + d = hex2mpi (sample_ed25519_d); + err = gcry_mpi_ec_set_mpi ("d", d, ctx); + if (err) + fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (d); + err = gcry_mpi_ec_set_mpi ("d", NULL, ctx); + if (err) + fail ("setting d for Ed25519 failed(2): %s\n", gpg_strerror (err)); + if (gcry_mpi_ec_get_mpi ("q", ctx, 0)) + fail ("setting d for Ed25519 did not reset Q\n"); + + /* Set Q again. We need to use an opaque MPI here because + sample_ed25519_q is in uncompressed format which can only be + auto-detected if passed opaque. */ + q = hex2mpiopa (sample_ed25519_q); + err = gcry_mpi_ec_set_mpi ("q", q, ctx); + if (err) + fail ("setting Q for Ed25519 failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (q); + get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(2)", ctx); + + /* Get as s-expression. */ err = gcry_pubkey_get_sexp (&sexp, 0, ctx); if (err) fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); @@ -544,9 +712,9 @@ context_param (void) gpg_strerror (err)); gcry_sexp_release (sexp); - gcry_ctx_release (ctx); } + gcry_ctx_release (ctx); gcry_sexp_release (keyparam); } @@ -730,7 +898,7 @@ basic_ec_math_simplified (void) print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); gcry_sexp_release (sexp); - /* Does get_sexp return the public key if after d has been deleted? */ + /* Does get_sexp return the public key after d has been deleted? */ err = gcry_mpi_ec_set_mpi ("d", NULL, ctx); if (err) die ("gcry_mpi_ec_set_mpi(d=NULL) failed\n"); commit 9a4447ccd1b90bcd701941e80a7f484a1825fcea Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 mpicalc: Add statement to compute the number of bits. * src/mpicalc.c (do_nbits): New. (main): Add statement 'b'. Signed-off-by: Werner Koch diff --git a/src/mpicalc.c b/src/mpicalc.c index 762d7c8..dd85227 100644 --- a/src/mpicalc.c +++ b/src/mpicalc.c @@ -238,6 +238,20 @@ do_rshift (void) } +static void +do_nbits (void) +{ + unsigned int n; + + if (stackidx < 1) + { + fputs ("stack underflow\n", stderr); + return; + } + n = mpi_get_nbits (stack[stackidx - 1]); + mpi_set_ui (stack[stackidx - 1], n); +} + static int my_getc (void) @@ -279,6 +293,7 @@ print_help (void) "i remove item [0] := [1] {-1}\n" "d dup item [-1] := [0] {+1}\n" "r reverse [0] := [1], [1] := [0] {0}\n" + "b # of bits [0] := nbits([0]) {0}\n" "c clear stack\n" "p print top item\n" "f print the stack\n" @@ -381,7 +396,7 @@ main (int argc, char **argv) do_add (); } break; - case '-': + case '-': if ((c = my_getc ()) == '-') do_dec (); else if (isdigit (c) || (c >= 'A' && c <= 'F')) @@ -454,6 +469,9 @@ main (int argc, char **argv) stack[stackidx-2] = tmp; } break; + case 'b': + do_nbits (); + break; case 'c': for (i = 0; i < stackidx; i++) { commit 64a7d347847d606eb5f4c156e24ba060271b8f6b Author: Werner Koch Date: Sat Sep 7 10:06:46 2013 +0200 ecc: Refactor low-level access functions. * mpi/ec.c (point_copy): Move to cipher/ecc-curves.c. (ec_get_reset): Rename to _gcry_mpi_ec_get_reset and make global. (_gcry_mpi_ec_get_mpi): Factor most code out to _gcry_ecc_get_mpi. (_gcry_mpi_ec_get_point): Factor most code out to _gcry_ecc_get_point. (_gcry_mpi_ec_set_mpi): Factor most code out to _gcry_ecc_set_mpi. (_gcry_mpi_ec_set_point): Factor most code out to _gcry_ecc_set_point. * cipher/ecc-curves.c (_gcry_ecc_get_mpi): New. (_gcry_ecc_get_point, _gcry_ecc_set_mpi, _gcry_ecc_set_point): New. * cipher/ecc-misc.c (_gcry_ecc_compute_public): New. Signed-off-by: Werner Koch diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h index e806059..031994a 100644 --- a/cipher/ecc-common.h +++ b/cipher/ecc-common.h @@ -82,5 +82,7 @@ const char *_gcry_ecc_dialect2str (enum ecc_dialects dialect); gcry_mpi_t _gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p); gcry_error_t _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value); +mpi_point_t _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec); + #endif /*GCRY_ECC_COMMON_H*/ diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index 49c0959..e6a993f 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -270,6 +270,23 @@ static const ecc_domain_parms_t domain_parms[] = +/* Return a copy of POINT. */ +static gcry_mpi_point_t +point_copy (gcry_mpi_point_t point) +{ + gcry_mpi_point_t newpoint; + + if (point) + { + newpoint = gcry_mpi_point_new (0); + point_set (newpoint, point); + } + else + newpoint = NULL; + return newpoint; +} + + /* Helper to scan a hex string. */ static gcry_mpi_t scanval (const char *string) @@ -787,3 +804,126 @@ _gcry_ecc_get_param_sexp (const char *name) return result; } + + +/* Return an MPI (or opaque MPI) described by NAME and the context EC. + If COPY is true a copy is returned, if not a const MPI may be + returned. In any case mpi_free must be used. */ +gcry_mpi_t +_gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) +{ + if (!strcmp (name, "p") && ec->p) + return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p); + if (!strcmp (name, "a") && ec->a) + return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a); + if (!strcmp (name, "b") && ec->b) + return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); + if (!strcmp (name, "n") && ec->n) + return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); + if (!strcmp (name, "d") && ec->d) + return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); + + /* Return a requested point coordinate. */ + if (!strcmp (name, "g.x") && ec->G && ec->G->x) + return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x); + if (!strcmp (name, "g.y") && ec->G && ec->G->y) + return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y); + if (!strcmp (name, "q.x") && ec->Q && ec->Q->x) + return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x); + if (!strcmp (name, "q.y") && ec->Q && ec->Q->y) + return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y); + + /* If a point has been requested, return it in standard encoding. */ + if (!strcmp (name, "g") && ec->G) + return _gcry_mpi_ec_ec2os (ec->G, ec); + if (!strcmp (name, "q")) + { + /* If only the private key is given, compute the public key. */ + if (!ec->Q) + ec->Q = _gcry_ecc_compute_public (NULL, ec); + + if (ec->Q) + return _gcry_mpi_ec_ec2os (ec->Q, ec); + } + + return NULL; +} + + +/* Return a point described by NAME and the context EC. */ +gcry_mpi_point_t +_gcry_ecc_get_point (const char *name, mpi_ec_t ec) +{ + if (!strcmp (name, "g") && ec->G) + return point_copy (ec->G); + if (!strcmp (name, "q")) + { + /* If only the private key is given, compute the public key. */ + if (!ec->Q) + ec->Q = _gcry_ecc_compute_public (NULL, ec); + + if (ec->Q) + return point_copy (ec->Q); + } + + return NULL; +} + + +/* Store the MPI NEWVALUE into the context EC under NAME. */ +gpg_err_code_t +_gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) +{ + if (!strcmp (name, "p")) + { + mpi_free (ec->p); + ec->p = mpi_copy (newvalue); + _gcry_mpi_ec_get_reset (ec); + } + else if (!strcmp (name, "a")) + { + mpi_free (ec->a); + ec->a = mpi_copy (newvalue); + _gcry_mpi_ec_get_reset (ec); + } + else if (!strcmp (name, "b")) + { + mpi_free (ec->b); + ec->b = mpi_copy (newvalue); + } + else if (!strcmp (name, "n")) + { + mpi_free (ec->n); + ec->n = mpi_copy (newvalue); + } + else if (!strcmp (name, "d")) + { + mpi_free (ec->d); + ec->d = mpi_copy (newvalue); + } + else + return GPG_ERR_UNKNOWN_NAME; + + return 0; +} + + +/* Store the point NEWVALUE into the context EC under NAME. */ +gpg_err_code_t +_gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec) +{ + if (!strcmp (name, "g")) + { + gcry_mpi_point_release (ec->G); + ec->G = point_copy (newvalue); + } + else if (!strcmp (name, "q")) + { + gcry_mpi_point_release (ec->Q); + ec->Q = point_copy (newvalue); + } + else + return GPG_ERR_UNKNOWN_NAME; + + return 0; +} diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index f8db81a..1dc0480 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -232,3 +232,24 @@ _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value) return 0; } + + +/* Compute the public key from the the context EC. Obviously a + requirement is that the secret key is available in EC. On success + Q is returned; on error NULL. If Q is NULL a newly allocated pint + is returned. */ +mpi_point_t +_gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec) +{ + if (!ec->d || !ec->G || !ec->p || !ec->a) + return NULL; + if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b) + return NULL; + + if (!Q) + Q = gcry_mpi_point_new (0); + if (!Q) + return NULL; + _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec); + return Q; +} diff --git a/mpi/ec.c b/mpi/ec.c index e52facd..883d8f6 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -132,23 +132,6 @@ point_set (mpi_point_t d, mpi_point_t s) } -/* Return a copy of POINT. */ -static gcry_mpi_point_t -point_copy (gcry_mpi_point_t point) -{ - gcry_mpi_point_t newpoint; - - if (point) - { - newpoint = gcry_mpi_point_new (0); - point_set (newpoint, point); - } - else - newpoint = NULL; - return newpoint; -} - - /* Set the projective coordinates from POINT into X, Y, and Z. If a coordinate is not required, X, Y, or Z may be passed as NULL. */ void @@ -396,8 +379,8 @@ ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx) /* Force recomputation of all helper variables. */ -static void -ec_get_reset (mpi_ec_t ec) +void +_gcry_mpi_ec_get_reset (mpi_ec_t ec) { ec->t.valid.a_is_pminus3 = 0; ec->t.valid.two_inv_p = 0; @@ -458,7 +441,7 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model, if (b && model == MPI_EC_TWISTEDEDWARDS) ctx->b = mpi_copy (b); - ec_get_reset (ctx); + _gcry_mpi_ec_get_reset (ctx); /* Allocate scratch variables. */ for (i=0; i< DIM(ctx->t.scratch); i++) @@ -590,44 +573,7 @@ _gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy) { mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); - if (!strcmp (name, "p") && ec->p) - return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p); - if (!strcmp (name, "a") && ec->a) - return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a); - if (!strcmp (name, "b") && ec->b) - return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); - if (!strcmp (name, "n") && ec->n) - return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); - if (!strcmp (name, "d") && ec->d) - return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); - - /* Return a requested point coordinate. */ - if (!strcmp (name, "g.x") && ec->G && ec->G->x) - return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x); - if (!strcmp (name, "g.y") && ec->G && ec->G->y) - return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y); - if (!strcmp (name, "q.x") && ec->Q && ec->Q->x) - return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x); - if (!strcmp (name, "q.y") && ec->Q && ec->Q->y) - return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y); - - /* If a point has been requested, return it in standard encoding. */ - if (!strcmp (name, "g") && ec->G) - return _gcry_mpi_ec_ec2os (ec->G, ec); - if (!strcmp (name, "q")) - { - /* If only the private key is given, compute the public key. */ - if (!ec->Q && ec->d && ec->G && ec->p && ec->a) - { - ec->Q = gcry_mpi_point_new (0); - _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec); - } - - if (ec->Q) - return _gcry_mpi_ec_ec2os (ec->Q, ec); - } - - return NULL; + return _gcry_ecc_get_mpi (name, ec, copy); } @@ -638,22 +584,7 @@ _gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy) (void)copy; /* Not used. */ - if (!strcmp (name, "g") && ec->G) - return point_copy (ec->G); - if (!strcmp (name, "q")) - { - /* If only the private key is given, compute the public key. */ - if (!ec->Q && ec->d && ec->G && ec->p && ec->a) - { - ec->Q = gcry_mpi_point_new (0); - _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec); - } - - if (ec->Q) - return point_copy (ec->Q); - } - - return NULL; + return _gcry_ecc_get_point (name, ec); } @@ -663,37 +594,7 @@ _gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue, { mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); - if (!strcmp (name, "p")) - { - mpi_free (ec->p); - ec->p = mpi_copy (newvalue); - ec_get_reset (ec); - } - else if (!strcmp (name, "a")) - { - mpi_free (ec->a); - ec->a = mpi_copy (newvalue); - ec_get_reset (ec); - } - else if (!strcmp (name, "b")) - { - mpi_free (ec->b); - ec->b = mpi_copy (newvalue); - } - else if (!strcmp (name, "n")) - { - mpi_free (ec->n); - ec->n = mpi_copy (newvalue); - } - else if (!strcmp (name, "d")) - { - mpi_free (ec->d); - ec->d = mpi_copy (newvalue); - } - else - return GPG_ERR_UNKNOWN_NAME; - - return 0; + return _gcry_ecc_set_mpi (name, newvalue, ec); } @@ -703,20 +604,7 @@ _gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue, { mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); - if (!strcmp (name, "g")) - { - gcry_mpi_point_release (ec->G); - ec->G = point_copy (newvalue); - } - else if (!strcmp (name, "q")) - { - gcry_mpi_point_release (ec->Q); - ec->Q = point_copy (newvalue); - } - else - return GPG_ERR_UNKNOWN_NAME; - - return 0; + return _gcry_ecc_set_point (name, newvalue, ec); } diff --git a/src/ec-context.h b/src/ec-context.h index f2ad19b..fdfbc0a 100644 --- a/src/ec-context.h +++ b/src/ec-context.h @@ -62,5 +62,20 @@ struct mpi_ec_ctx_s }; +/*-- mpi/ec.c --*/ +void _gcry_mpi_ec_get_reset (mpi_ec_t ec); + + +/*-- cipher/ecc-curves.c --*/ +gpg_err_code_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, + gcry_sexp_t keyparam, const char *curvename); + +gcry_mpi_t _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy); +gcry_mpi_point_t _gcry_ecc_get_point (const char *name, mpi_ec_t ec); +gpg_err_code_t _gcry_ecc_set_mpi (const char *name, + gcry_mpi_t newvalue, mpi_ec_t ec); +gpg_err_code_t _gcry_ecc_set_point (const char *name, + gcry_mpi_point_t newvalue, mpi_ec_t ec); + #endif /*GCRY_EC_CONTEXT_H*/ diff --git a/src/mpi.h b/src/mpi.h index 3466951..279c485 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -333,8 +333,6 @@ int _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx); gcry_mpi_t _gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ectx); -gpg_err_code_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, - gcry_sexp_t keyparam, const char *curvename); gcry_mpi_t _gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy); gcry_mpi_point_t _gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy); ----------------------------------------------------------------------- Summary of changes: cipher/ecc-common.h | 12 +++ cipher/ecc-curves.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++ cipher/ecc-misc.c | 21 ++++++ cipher/ecc.c | 121 ++++++++++++++++++++++---------- doc/gcrypt.texi | 14 +++- mpi/ec.c | 130 +++------------------------------- mpi/mpiutil.c | 7 ++- src/ec-context.h | 17 +++++ src/gcrypt.h.in | 2 +- src/mpi.h | 4 +- src/mpicalc.c | 20 +++++- src/sexp.c | 2 + tests/t-mpi-point.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++--- 13 files changed, 551 insertions(+), 181 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From dbaryshkov at gmail.com Wed Sep 25 22:44:22 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 26 Sep 2013 00:44:22 +0400 Subject: Testing ECC signatures In-Reply-To: <87pprwg2fv.fsf@vigenere.g10code.de> References: <87pprwg2fv.fsf@vigenere.g10code.de> Message-ID: <52434B26.1030704@gmail.com> On 25/09/13 22:51, Werner Koch wrote: > On Wed, 25 Sep 2013 18:51, dbaryshkov at gmail.com said: > >> "random-override" value (like it is done for several RSA padding modes). >> However I see no simple way to pass that further to ecc_sign (in my >> case) function. > > For ECC I suggest to use the rfc6979 flag, which creates deterministic > signatures. I should think about applicability of rfc6979 to GOST signature algorithms. >> interface changes to >> move S-Exp processing directly to algorithms (if I understood >> correctly andthat is >> the way the code base currently moves)? > > Yes, that is what I am working on. OK, I will just wait for the interface changes. I don't want to change internal pkey/ecc interfaces, if you are going to change that in observable future. > In general I don't like the idea of having a feature to override random, > because that could easily slip into the real code path. But sometimes > these things are required for certification purposes. Yes, I see your point. However adding such feature will make testing easier. -- With best wishes Dmitry From gniibe at fsij.org Thu Sep 26 02:21:39 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 26 Sep 2013 09:21:39 +0900 Subject: The value d (was: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-273-g1c6660d) In-Reply-To: References: Message-ID: <1380154899.3247.3.camel@cfw2.gniibe.org> I read "High-speed high-security signatures", by Daniel J. Bernstein, et al., and find the definition of ED25519 in the page 7 to page 8. Specifically: q = 2^255 - 19 l = 2^252 + 27742317777372353535851937790883648493 d = -121665/121666 (of element in Fq) B is the unique point (x, 4/5) of element in E where x is positive Edwards curve E: -x^2 + y^2 = 1 - d*x^2*y^2 > diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c > index 6683189..0641779 100644 > --- a/tests/t-mpi-point.c > +++ b/tests/t-mpi-point.c [...] > @@ -113,6 +121,15 @@ static struct > "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" > "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" > }, > + { > + "Ed25519", > + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", > + "-0x01", > + "-0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4", > + "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", > + "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", > + "0x6666666666666666666666666666666666666666666666666666666666666658" > + }, > { NULL, NULL, NULL, NULL, NULL } > }; > Here, 0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4 is: (121666^-1 mod q)*121665. (121666^-1) * 121665 mod q is: 0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A While it works for both, I think that shorter is better. We have same value in the constant variable domain_parms in cipher/ecc-curves.c. -- From cvs at cvs.gnupg.org Thu Sep 26 11:48:20 2013 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Thu, 26 Sep 2013 11:48:20 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-274-gdb60d82 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via db60d828137c4f3682ca4ca2a54fe3d96d3db5f9 (commit) from 1c6660debdbf1e4c3e80074c846a3e3097f214bb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit db60d828137c4f3682ca4ca2a54fe3d96d3db5f9 Author: Jussi Kivilinna Date: Sat Sep 21 13:54:38 2013 +0300 Make libgcrypt build with Clang on i386 * cipher/longlong.h [__i386__] (add_ssaaaa, sub_ddmmss) (umul_ppmm, udiv_qrnnd): Do not cast asm output to USItype. -- Clang defines __GNUC__ even when it's not GCC compatible. As result Clang enables GCC-only assembly code in mpi/longlong.h and fails to build. However, since changes to make libgcrypt build with Clang are smallish, and changes do not cause problems with GCC, patch just does them. Signed-off-by: Jussi Kivilinna diff --git a/mpi/longlong.h b/mpi/longlong.h index 773d1c7..4e315df 100644 --- a/mpi/longlong.h +++ b/mpi/longlong.h @@ -468,8 +468,8 @@ extern USItype __udiv_qrnnd (); #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addl %5,%1\n" \ "adcl %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -478,8 +478,8 @@ extern USItype __udiv_qrnnd (); #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subl %5,%1\n" \ "sbbl %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" ((sh)), \ + "=&r" ((sl)) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -487,15 +487,15 @@ extern USItype __udiv_qrnnd (); __CLOBBER_CC) #define umul_ppmm(w1, w0, u, v) \ __asm__ ("mull %3" \ - : "=a" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ + : "=a" ((w0)), \ + "=d" ((w1)) \ : "%0" ((USItype)(u)), \ "rm" ((USItype)(v)) \ __CLOBBER_CC) #define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divl %4" \ - : "=a" ((USItype)(q)), \ - "=d" ((USItype)(r)) \ + : "=a" ((q)), \ + "=d" ((r)) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "rm" ((USItype)(d)) \ ----------------------------------------------------------------------- Summary of changes: mpi/longlong.h | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From jussi.kivilinna at iki.fi Thu Sep 26 11:31:10 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 26 Sep 2013 12:31:10 +0300 Subject: [PATCH] Fix errors when building with Clang on PPC In-Reply-To: <1379625252-17756-1-git-send-email-dbaryshkov@gmail.com> References: <1379625252-17756-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <5243FEDE.5030403@iki.fi> On 20.09.2013 00:14, Dmitry Eremin-Solenikov wrote: > * mpi/longlong.h (add_ssaaaa, sub_ddmmss, count_leading_zeros, > umul_ppmm): Do not cast asm output to USItype. > I can push this one, if that's ok(?). -Jussi From jussi.kivilinna at iki.fi Thu Sep 26 11:54:06 2013 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 26 Sep 2013 12:54:06 +0300 Subject: [PATCH] Prevent tail call optimization with _gcry_burn_stack Message-ID: <20130926095406.21232.61952.stgit@localhost6.localdomain6> * src/g10lib.h (_gcry_burn_stack): Rename to __gcry_burn_stack. (__gcry_burn_stack_dummy): New. (_gcry_burn_stack): New macro. * src/misc.c (_gcry_burn_stack): Rename to __gcry_burn_stack. (__gcry_burn_stack_dummy): New. -- Tail call optimization can turn _gcry_burn_stack call in to tail jump. When this happens, stack pointer is restored to initial state of current function. This causes problem for _gcry_burn_stack because its callers do not count in current function stack depth. One solution is to prevent gcry_burn_stack being tail optimized by inserting dummy function call behind it. (Another would be to add memory barrier 'asm volatile("":::"memory")' behind every_gcry_burn_stack. This however requires GCC asm support from compiler.) Signed-off-by: Jussi Kivilinna --- src/g10lib.h | 6 +++++- src/misc.c | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/g10lib.h b/src/g10lib.h index 73ba683..9b342c3 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -250,7 +250,11 @@ int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE; /* Stack burning. */ -void _gcry_burn_stack (unsigned int bytes); +void __gcry_burn_stack_dummy (void); +void __gcry_burn_stack (unsigned int bytes); +#define _gcry_burn_stack(bytes) \ + do { __gcry_burn_stack (bytes); \ + __gcry_burn_stack_dummy (); } while(0) /* To avoid that a compiler optimizes certain memset calls away, these diff --git a/src/misc.c b/src/misc.c index a19e1e4..83a3a9e 100644 --- a/src/misc.c +++ b/src/misc.c @@ -363,7 +363,7 @@ _gcry_log_printmpi (const char *text, gcry_mpi_t mpi) void -_gcry_burn_stack (unsigned int bytes) +__gcry_burn_stack (unsigned int bytes) { #ifdef HAVE_VLA /* (bytes == 0 ? 1 : bytes) == (!bytes + bytes) */ @@ -382,6 +382,11 @@ _gcry_burn_stack (unsigned int bytes) } void +__gcry_burn_stack_dummy (void) +{ +} + +void _gcry_divide_by_zero (void) { gpg_err_set_errno (EDOM); From dbaryshkov at gmail.com Thu Sep 26 14:07:42 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 26 Sep 2013 16:07:42 +0400 Subject: [PATCH 2/3] Check that secret keys are valid while running basic pubkey tests In-Reply-To: <1380197263-750-1-git-send-email-dbaryshkov@gmail.com> References: <1380197263-750-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1380197263-750-2-git-send-email-dbaryshkov@gmail.com> * tests/basic.c (do_check_one_pubkey): call gcry_pk_testkey on passed secret keys. Signed-off-by: Dmitry Eremin-Solenikov --- tests/basic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/basic.c b/tests/basic.c index fd8ca0f..9ce684b 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -3719,6 +3719,11 @@ static void do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey, const unsigned char *grip, int algo, int flags) { + gcry_error_t rc; + + rc = gcry_pk_testkey (skey); + if (rc) + fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc)); if (flags & FLAG_SIGN) { if (algo == GCRY_PK_ECDSA) -- 1.8.4.rc3 From dbaryshkov at gmail.com Thu Sep 26 14:07:43 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 26 Sep 2013 16:07:43 +0400 Subject: [PATCH 3/3] Add support for GOST R 34.10-2001/-2012 signatures In-Reply-To: <1380197263-750-1-git-send-email-dbaryshkov@gmail.com> References: <1380197263-750-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1380197263-750-3-git-send-email-dbaryshkov@gmail.com> * src/cipher.h: define PUBKEY_FLAG_GOST * cipher/ecc-curves.c: add GOST2001-test and GOST2012-test curves defined in standards. Typical applications would use either those curves, or curves defined in RFC 4357 (will be added later). * cipher/ecc.c (sign_gost, verify_gost): New. (ecc_sign, ecc_verify): use sign_gost/verify_gost if PUBKEY_FLAG_GOST is set. (ecc_names): add "gost" for gost signatures. * cipher/pubkey.c (sexp_data_to_mpi): set PUBKEY_FLAG_GOST if gost flag is present in s-exp. * tests/benchmark.c (ecc_bench): also benchmark GOST signatures. * tests/basic.c (check_pubkey): add two public keys from GOST R 34.10-2012 standard. (check_pubkey_sign_ecdsa): add two data sets to check gost signatures. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/ecc-curves.c | 28 +++++++ cipher/ecc.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cipher/pubkey.c | 5 ++ src/cipher.h | 1 + tests/basic.c | 75 ++++++++++++++++++ tests/benchmark.c | 17 +++- 6 files changed, 343 insertions(+), 1 deletion(-) diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index 7447340..05fca05 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -263,6 +263,34 @@ static const ecc_domain_parms_t domain_parms[] = "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111" "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892" }, + { + "GOST2001-test", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0x8000000000000000000000000000000000000000000000000000000000000431", /* p */ + "0x0000000000000000000000000000000000000000000000000000000000000007", /* a */ + "0x5fbff498aa938ce739b8e022fbafef40563f6e6a3472fc2a514c0ce9dae23b7e", /* b */ + "0x8000000000000000000000000000000150fe8a1892976154c59cfc193accf5b3", /* q */ + + "0x0000000000000000000000000000000000000000000000000000000000000002", /* x */ + "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8", /* y */ + }, + + { + "GOST2012-test", 511, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" + "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373", /* p */ + "0x0000000000000000000000000000000000000000000000000000000000000007", /* a */ + "0x1cff0806a31116da29d8cfa54e57eb748bc5f377e49400fdd788b649eca1ac4" + "361834013b2ad7322480a89ca58e0cf74bc9e540c2add6897fad0a3084f302adc", /* b */ + "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" + "a82f2d7ecb1dbac719905c5eecc423f1d86e25edbe23c595d644aaf187e6e6df", /* q */ + + "0x24d19cc64572ee30f396bf6ebbfd7a6c5213b3b3d7057cc825f91093a68cd762" + "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a", /* x */ + "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2" + "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e", /* y */ + }, { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL } }; diff --git a/cipher/ecc.c b/cipher/ecc.c index abd501f..68a5a89 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -567,6 +567,203 @@ verify_ecdsa (gcry_mpi_t input, ECC_public_key *pkey, return err; } +/* Compute an GOST R 34.10-01/-12 signature. + * Return the signature struct (r,s) from the message hash. The caller + * must have allocated R and S. + */ +static gpg_err_code_t +sign_gost (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s) +{ + gpg_err_code_t err = 0; + gcry_mpi_t k, dr, sum, ke, x, e; + mpi_point_struct I; + gcry_mpi_t hash; + const void *abuf; + unsigned int abits, qbits; + mpi_ec_t ctx; + + if (DBG_CIPHER) + log_mpidump ("gost sign hash ", input ); + + qbits = mpi_get_nbits (skey->E.n); + + /* Convert the INPUT into an MPI if needed. */ + if (mpi_is_opaque (input)) + { + abuf = gcry_mpi_get_opaque (input, &abits); + err = gpg_err_code (gcry_mpi_scan (&hash, GCRYMPI_FMT_USG, + abuf, (abits+7)/8, NULL)); + if (err) + return err; + if (abits > qbits) + gcry_mpi_rshift (hash, hash, abits - qbits); + } + else + hash = input; + + + k = NULL; + dr = mpi_alloc (0); + sum = mpi_alloc (0); + ke = mpi_alloc (0); + e = mpi_alloc (0); + x = mpi_alloc (0); + point_init (&I); + + ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, + skey->E.p, skey->E.a, skey->E.b); + + mpi_mod (e, input, skey->E.n); /* e = hash mod n */ + + if (!mpi_cmp_ui (e, 0)) + mpi_set_ui (e, 1); + + /* Two loops to avoid R or S are zero. This is more of a joke than + a real demand because the probability of them being zero is less + than any hardware failure. Some specs however require it. */ + do + { + do + { + mpi_free (k); + k = _gcry_dsa_gen_k (skey->E.n, GCRY_STRONG_RANDOM); + + _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx); + if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx)) + { + if (DBG_CIPHER) + log_debug ("ecc sign: Failed to get affine coordinates\n"); + err = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + mpi_mod (r, x, skey->E.n); /* r = x mod n */ + } + while (!mpi_cmp_ui (r, 0)); + mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */ + mpi_mulm (ke, k, e, skey->E.n); /* ke = k*e mod n */ + mpi_addm (s, ke, dr, skey->E.n); /* sum = (k*e+ d*r) mod n */ + } + while (!mpi_cmp_ui (s, 0)); + + if (DBG_CIPHER) + { + log_mpidump ("gost sign result r ", r); + log_mpidump ("gost sign result s ", s); + } + + leave: + _gcry_mpi_ec_free (ctx); + point_free (&I); + mpi_free (x); + mpi_free (e); + mpi_free (ke); + mpi_free (sum); + mpi_free (dr); + mpi_free (k); + + if (hash != input) + mpi_free (hash); + + return err; +} + +/* Verify a GOST R 34.10-01/-12 signature. + * Check if R and S verifies INPUT. + */ +static gpg_err_code_t +verify_gost (gcry_mpi_t input, ECC_public_key *pkey, + gcry_mpi_t r, gcry_mpi_t s) +{ + gpg_err_code_t err = 0; + gcry_mpi_t e, x, z1, z2, v, rv, zero; + mpi_point_struct Q, Q1, Q2; + mpi_ec_t ctx; + + if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) ) + return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */ + if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) ) + return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */ + + x = mpi_alloc (0); + e = mpi_alloc (0); + z1 = mpi_alloc (0); + z2 = mpi_alloc (0); + v = mpi_alloc (0); + rv = mpi_alloc (0); + zero = mpi_alloc (0); + + point_init (&Q); + point_init (&Q1); + point_init (&Q2); + + ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, + pkey->E.p, pkey->E.a, pkey->E.b); + + mpi_mod (e, input, pkey->E.n); /* e = hash mod n */ + if (!mpi_cmp_ui (e, 0)) + mpi_set_ui (e, 1); + mpi_invm (v, e, pkey->E.n); /* v = e^(-1) (mod n) */ + mpi_mulm (z1, s, v, pkey->E.n); /* z1 = s*v (mod n) */ + mpi_mulm (rv, r, v, pkey->E.n); /* rv = s*v (mod n) */ + mpi_subm (z2, zero, rv, pkey->E.n); /* z2 = -r*v (mod n) */ + + _gcry_mpi_ec_mul_point (&Q1, z1, &pkey->E.G, ctx); +/* log_mpidump ("Q1.x", Q1.x); */ +/* log_mpidump ("Q1.y", Q1.y); */ +/* log_mpidump ("Q1.z", Q1.z); */ + _gcry_mpi_ec_mul_point (&Q2, z2, &pkey->Q, ctx); +/* log_mpidump ("Q2.x", Q2.x); */ +/* log_mpidump ("Q2.y", Q2.y); */ +/* log_mpidump ("Q2.z", Q2.z); */ + _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx); +/* log_mpidump (" Q.x", Q.x); */ +/* log_mpidump (" Q.y", Q.y); */ +/* log_mpidump (" Q.z", Q.z); */ + + if (!mpi_cmp_ui (Q.z, 0)) + { + if (DBG_CIPHER) + log_debug ("ecc verify: Rejected\n"); + err = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ctx)) + { + if (DBG_CIPHER) + log_debug ("ecc verify: Failed to get affine coordinates\n"); + err = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */ + if (mpi_cmp (x, r)) /* x != r */ + { + if (DBG_CIPHER) + { + log_mpidump (" x", x); + log_mpidump (" r", r); + log_mpidump (" s", s); + log_debug ("ecc verify: Not verified\n"); + } + err = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + if (DBG_CIPHER) + log_debug ("ecc verify: Accepted\n"); + + leave: + _gcry_mpi_ec_free (ctx); + point_free (&Q2); + point_free (&Q1); + point_free (&Q); + mpi_free (zero); + mpi_free (rv); + mpi_free (v); + mpi_free (z2); + mpi_free (z1); + mpi_free (x); + mpi_free (e); + return err; +} static void @@ -1511,6 +1708,13 @@ ecc_sign (int algo, gcry_sexp_t *r_result, gcry_mpi_t data, gcry_mpi_t *skey, rc = gcry_sexp_build (r_result, NULL, "(sig-val(eddsa(r%M)(s%M)))", r, s); } + else if ((flags & PUBKEY_FLAG_GOST)) + { + rc = sign_gost (data, &sk, r, s); + if (!rc) + rc = gcry_sexp_build (r_result, NULL, + "(sig-val(gost(r%M)(s%M)))", r, s); + } else { rc = sign_ecdsa (data, &sk, r, s, flags, hashalgo); @@ -1578,6 +1782,19 @@ ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, err = verify_eddsa (hash, &pk, data[0], data[1], hashalgo, pkey[5]); } + else if ((flags & PUBKEY_FLAG_GOST)) + { + point_init (&pk.Q); + err = _gcry_ecc_os2ec (&pk.Q, pkey[5]); + if (err) + { + point_free (&pk.E.G); + point_free (&pk.Q); + return err; + } + + err = verify_gost (hash, &pk, data[0], data[1]); + } else { point_init (&pk.Q); @@ -2085,6 +2302,7 @@ static const char *ecc_names[] = "ecdsa", "ecdh", "eddsa", + "gost", NULL, }; diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 4738c29..d247a67 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -1001,6 +1001,11 @@ sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi, ctx->encoding = PUBKEY_ENC_RAW; parsed_flags |= PUBKEY_FLAG_EDDSA; } + else if (n == 4 && !memcmp (s, "gost", 4)) + { + ctx->encoding = PUBKEY_ENC_RAW; + parsed_flags |= PUBKEY_FLAG_GOST; + } else if ( n == 3 && !memcmp (s, "raw", 3) && ctx->encoding == PUBKEY_ENC_UNKNOWN) { diff --git a/src/cipher.h b/src/cipher.h index ea7a141..fcd43a8 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -31,6 +31,7 @@ #define PUBKEY_FLAG_EDDSA (1 << 2) #define PUBKEY_FLAG_FIXEDLEN (1 << 3) #define PUBKEY_FLAG_LEGACYRESULT (1 << 4) +#define PUBKEY_FLAG_GOST (1 << 5) enum pk_operation { diff --git a/tests/basic.c b/tests/basic.c index 9ce684b..b664de5 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -3438,6 +3438,30 @@ check_pubkey_sign_ecdsa (int n, gcry_sexp_t skey, gcry_sexp_t pkey) /* */ "000102030405060708090A0B0C0D0E0F#))", 0 }, + { 256, + "(data (flags gost)\n" + " (value #00112233445566778899AABBCCDDEEFF" + /* */ "000102030405060708090A0B0C0D0E0F#))", + 0, + "(data (flags gost)\n" + " (value #80112233445566778899AABBCCDDEEFF" + /* */ "000102030405060708090A0B0C0D0E0F#))", + 0 + }, + { 512, + "(data (flags gost)\n" + " (value #00112233445566778899AABBCCDDEEFF" + /* */ "000102030405060708090A0B0C0D0E0F" + /* */ "000102030405060708090A0B0C0D0E0F" + /* */ "000102030405060708090A0B0C0D0E0F#))", + 0, + "(data (flags gost)\n" + " (value #80112233445566778899AABBCCDDEEFF" + /* */ "000102030405060708090A0B0C0D0E0F" + /* */ "000102030405060708090A0B0C0D0E0F" + /* */ "000102030405060708090A0B0C0D0E0F#))", + 0 + }, { 0, NULL } }; @@ -4023,6 +4047,57 @@ check_pubkey (void) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } + }, + { /* GOST R 34.10-2001/2012 test 256 bit. */ + GCRY_PK_ECDSA, FLAG_SIGN, + { + "(private-key\n" + " (ecc\n" + " (curve GOST2001-test)\n" + " (q #047F2B49E270DB6D90D8595BEC458B50C58585BA1D4E9B78" + " 8F6689DBD8E56FD80B26F1B489D6701DD185C8413A977B3C" + " BBAF64D1C593D26627DFFB101A87FF77DA#)\n" + " (d #7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE" + " 1D19CE9891EC3B28#)))\n", + + "(public-key\n" + " (ecc\n" + " (curve GOST2001-test)\n" + " (q #047F2B49E270DB6D90D8595BEC458B50C58585BA1D4E9B78" + " 8F6689DBD8E56FD80B26F1B489D6701DD185C8413A977B3C" + " BBAF64D1C593D26627DFFB101A87FF77DA#)))\n", + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } + }, + { /* GOST R 34.10-2012 test 512 bit. */ + GCRY_PK_ECDSA, FLAG_SIGN, + { + "(private-key\n" + " (ecc\n" + " (curve GOST2012-test)\n" + " (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1" + " 815B5C320C854621DD5A515856D13314AF69BC5B924C8B" + " 4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4" + " 0B0F5621DC3AC1B751CFA0E2634FA0503B3D52639F5D7F" + " B72AFD61EA199441D943FFE7F0C70A2759A3CDB84C114E" + " 1F9339FDF27F35ECA93677BEEC#)\n" + " (d #0BA6048AADAE241BA40936D47756D7C93091A0E851466970" + " 0EE7508E508B102072E8123B2200A0563322DAD2827E2714" + " A2636B7BFD18AADFC62967821FA18DD4#)))\n", + + "(public-key\n" + " (ecc\n" + " (curve GOST2001-test)\n" + " (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1" + " 815B5C320C854621DD5A515856D13314AF69BC5B924C8B" + " 4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4" + " 0B0F5621DC3AC1B751CFA0E2634FA0503B3D52639F5D7F" + " B72AFD61EA199441D943FFE7F0C70A2759A3CDB84C114E" + " 1F9339FDF27F35ECA93677BEEC#)))\n" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } } }; int i; diff --git a/tests/benchmark.c b/tests/benchmark.c index 5d1434a..ecda0d3 100644 --- a/tests/benchmark.c +++ b/tests/benchmark.c @@ -883,7 +883,8 @@ ecc_bench (int iterations, int print_header) { #if USE_ECC gpg_error_t err; - const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519" }; + const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", + "gost256", "gost512" }; int testno; if (print_header) @@ -899,14 +900,22 @@ ecc_bench (int iterations, int print_header) int count; int p_size; int is_ed25519; + int is_gost; is_ed25519 = !strcmp (p_sizes[testno], "Ed25519"); + is_gost = !strncmp (p_sizes[testno], "gost", 4); if (is_ed25519) { p_size = 256; printf ("EdDSA Ed25519 "); fflush (stdout); } + else if (is_gost) + { + p_size = atoi (p_sizes[testno] + 4); + printf ("GOST %3d bit ", p_size); + fflush (stdout); + } else { p_size = atoi (p_sizes[testno]); @@ -917,6 +926,10 @@ ecc_bench (int iterations, int print_header) if (is_ed25519) err = gcry_sexp_build (&key_spec, NULL, "(genkey (ecdsa (curve \"Ed25519\")))"); + else if (is_gost) + err = gcry_sexp_build (&key_spec, NULL, + "(genkey (ecdsa (curve %s)))", + p_size == 256 ? "GOST2001-test" : "GOST2012-test"); else err = gcry_sexp_build (&key_spec, NULL, "(genkey (ECDSA (nbits %d)))", p_size); @@ -950,6 +963,8 @@ ecc_bench (int iterations, int print_header) err = gcry_sexp_build (&data, NULL, "(data (flags eddsa)(hash-algo sha512)" " (value %m))", x); + else if (is_gost) + err = gcry_sexp_build (&data, NULL, "(data (flags gost) (value %m))", x); else err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); gcry_mpi_release (x); -- 1.8.4.rc3 From dbaryshkov at gmail.com Thu Sep 26 14:07:41 2013 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 26 Sep 2013 16:07:41 +0400 Subject: [PATCH 1/3] Fix 256-bit ecdsa test key definition Message-ID: <1380197263-750-1-git-send-email-dbaryshkov@gmail.com> * tests/basic.c (check_pubkey): fix nistp256 testing key declaration - add missing comma. Signed-off-by: Dmitry Eremin-Solenikov --- tests/basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basic.c b/tests/basic.c index e9709d5..fd8ca0f 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -4014,7 +4014,7 @@ check_pubkey (void) " (curve nistp256)\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2B" " EB6644D3609FC781B71F9A8072F58CB66AE2F89BB1245187" - " 3ABF7D91F9E1FBF96BF2F70E73AAC9A283#)))\n" + " 3ABF7D91F9E1FBF96BF2F70E73AAC9A283#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } -- 1.8.4.rc3 From chris at chatsecure.org Fri Sep 27 10:13:27 2013 From: chris at chatsecure.org (Chris Ballinger) Date: Fri, 27 Sep 2013 01:13:27 -0700 Subject: -ffast-math safety? Message-ID: Is it discouraged to use gcc or clang's "fast math" flag when compiling libgcrypt? -------------- next part -------------- An HTML attachment was scrubbed... URL: From gniibe at fsij.org Fri Sep 27 11:06:51 2013 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 27 Sep 2013 18:06:51 +0900 Subject: -ffast-math safety? In-Reply-To: References: Message-ID: <1380272811.6413.1.camel@cfw2.gniibe.org> On 2013-09-27 at 01:13 -0700, Chris Ballinger wrote: > Is it discouraged to use gcc or clang's "fast math" flag when > compiling libgcrypt? I can't find any floating point computation in libgcrypt (except timing calculations and some code in random/rndw32.c). So, I think that it doesn't matter at all. -- From lekensteyn at gmail.com Thu Sep 26 23:20:32 2013 From: lekensteyn at gmail.com (Peter Wu) Date: Thu, 26 Sep 2013 23:20:32 +0200 Subject: [PATCH] Add support for 128-bit keys in RC2 Message-ID: <1380230432-13431-1-git-send-email-lekensteyn@gmail.com> This patch adds support for decrypting (and encrypting) using 128-bit keys using the RC2 algorithm. Signed-off-by: Peter Wu --- Hi, First of all a disclaimer, I am not a cryptographer but a computer science student. The purpose of this patch is to allow Wireshark to decrypt TLS packets using the TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 cipher suite (all cipher suites are supported, except RC2[1]). doc/gcrypt.texi was deliberately not updated as the help text might need other notes like "this algorithm should not be used as it is insecure" besides "Both 40-bit and 128-bit keys are supported". I leave updating this document up to you. Regards, Peter [1]: https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9144 --- cipher/cipher.c | 2 ++ cipher/rfc2268.c | 13 +++++++++++++ src/cipher.h | 1 + 3 files changed, 16 insertions(+) diff --git a/cipher/cipher.c b/cipher/cipher.c index 6ddd58b..3b271d6 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -87,6 +87,8 @@ static struct cipher_table_entry #if USE_RFC2268 { &_gcry_cipher_spec_rfc2268_40, &dummy_extra_spec, GCRY_CIPHER_RFC2268_40 }, + { &_gcry_cipher_spec_rfc2268_128, + &dummy_extra_spec, GCRY_CIPHER_RFC2268_128 }, #endif #if USE_SEED { &_gcry_cipher_spec_seed, diff --git a/cipher/rfc2268.c b/cipher/rfc2268.c index 130be9b..da0b9f4 100644 --- a/cipher/rfc2268.c +++ b/cipher/rfc2268.c @@ -351,8 +351,21 @@ static gcry_cipher_oid_spec_t oids_rfc2268_40[] = { NULL } }; +static gcry_cipher_oid_spec_t oids_rfc2268_128[] = + { + /* pbeWithSHAAnd128BitRC2_CBC */ + { "1.2.840.113549.1.12.1.5", GCRY_CIPHER_MODE_CBC }, + { NULL } + }; + gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = { "RFC2268_40", NULL, oids_rfc2268_40, RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context), do_setkey, encrypt_block, decrypt_block }; + +gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_128 = { + "RFC2268_128", NULL, oids_rfc2268_128, + RFC2268_BLOCKSIZE, 128, sizeof(RFC2268_context), + do_setkey, encrypt_block, decrypt_block +}; diff --git a/src/cipher.h b/src/cipher.h index 7791083..516154f 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -193,6 +193,7 @@ extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128; extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192; extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256; extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40; +extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_128; extern gcry_cipher_spec_t _gcry_cipher_spec_seed; extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128; extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192; -- 1.8.4 From chrisballinger at gmail.com Fri Sep 27 20:30:02 2013 From: chrisballinger at gmail.com (Chris Ballinger) Date: Fri, 27 Sep 2013 11:30:02 -0700 Subject: -ffast-math safety? In-Reply-To: <1380272811.6413.1.camel@cfw2.gniibe.org> References: <1380272811.6413.1.camel@cfw2.gniibe.org> Message-ID: Thanks! On Fri, Sep 27, 2013 at 2:06 AM, NIIBE Yutaka wrote: > On 2013-09-27 at 01:13 -0700, Chris Ballinger wrote: > > Is it discouraged to use gcc or clang's "fast math" flag when > > compiling libgcrypt? > > I can't find any floating point computation in libgcrypt (except > timing calculations and some code in random/rndw32.c). > > So, I think that it doesn't matter at all. > -- > > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cvs at cvs.gnupg.org Mon Sep 30 10:51:08 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 30 Sep 2013 10:51:08 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-275-gd2076f2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via d2076f27bb7c5d505abf25fc622d21794c4a5df3 (commit) from db60d828137c4f3682ca4ca2a54fe3d96d3db5f9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d2076f27bb7c5d505abf25fc622d21794c4a5df3 Author: Werner Koch Date: Mon Sep 30 10:18:25 2013 +0200 Add logging functions to the API. * src/gcrypt.h.in (_GCRY_GCC_ATTR_PRINTF): New. (gcry_log_debug, gcry_log_debughex, gcry_log_debugmpi): New. (gcry_log_debugpnt, gcry_log_debugsxp): New. * src/visibility.c (gcry_log_debug): New. (gcry_log_debughex, gcry_log_debugmpi, gcry_log_debugpnt): New. (gcry_log_debugsxp): New. * src/libgcrypt.def, src/libgcrypt.vers: Add new functions. * src/misc.c (_gcry_logv): Make public. (_gcry_log_printsxp): New. * src/g10lib.h (log_printsxp): New macro. -- For debugging applications it is often required to dump certain data structures. Libgcrypt uses several internal functions for this. To avoid re-implementing everything in the caller, we now provide access to some of those functions. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 1e84cbe..c232a99 100644 --- a/NEWS +++ b/NEWS @@ -107,6 +107,10 @@ Noteworthy changes in version 1.6.0 (unreleased) GCRY_MD_STRIBOG512 NEW. GCRYCTL_DISABLE_ALGO CHANGED: Not anymore thread-safe. GCRY_PK_ECC NEW. + gcry_log_debug NEW. + gcry_log_debughex NEW. + gcry_log_debugmpi NEW. + gcry_log_debugpnt NEW. Noteworthy changes in version 1.5.0 (2011-06-29) diff --git a/src/g10lib.h b/src/g10lib.h index 73ba683..ff7f4b3 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -115,6 +115,8 @@ void _gcry_divide_by_zero (void) JNLIB_GCC_A_NR; const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1); void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR; +void _gcry_logv (int level, + const char *fmt, va_list arg_ptr) JNLIB_GCC_A_PRINTF(2,0); void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3); void _gcry_log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); @@ -126,6 +128,7 @@ void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); void _gcry_log_printhex (const char *text, const void *buffer, size_t length); void _gcry_log_printmpi (const char *text, gcry_mpi_t mpi); +void _gcry_log_printsxp (const char *text, gcry_sexp_t sexp); void _gcry_set_log_verbosity( int level ); int _gcry_log_verbosity( int level ); @@ -153,6 +156,7 @@ int _gcry_log_verbosity( int level ); #define log_printf _gcry_log_printf #define log_printhex _gcry_log_printhex #define log_printmpi _gcry_log_printmpi +#define log_printsxp _gcry_log_printsxp /* Compatibility macro. */ #define log_mpidump _gcry_log_printmpi diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 5f49edc..8fca52e 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -100,6 +100,8 @@ extern "C" { #define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__)) #endif +#define _GCRY_GCC_ATTR_PRINTF(f,a) __attribute__ ((format (printf,f,a))) + #endif /*__GNUC__*/ #ifndef _GCRY_GCC_ATTR_DEPRECATED @@ -111,6 +113,9 @@ extern "C" { #ifndef _GCRY_GCC_ATTR_MALLOC #define _GCRY_GCC_ATTR_MALLOC #endif +#ifndef _GCRY_GCC_ATTR_PRINTF +#define _GCRY_GCC_ATTR_PRINTF +#endif /* Make up an attribute to mark functions and types as deprecated but allow internal use by Libgcrypt. */ @@ -1405,6 +1410,15 @@ gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); /* Release the context object CTX. */ void gcry_ctx_release (gcry_ctx_t ctx); +/* Log data using Libgcrypt's own log interface. */ +void gcry_log_debug (const char *fmt, ...) _GCRY_GCC_ATTR_PRINTF(1,2); +void gcry_log_debughex (const char *text, const void *buffer, size_t length); +void gcry_log_debugmpi (const char *text, gcry_mpi_t mpi); +void gcry_log_debugpnt (const char *text, + gcry_mpi_point_t point, gcry_ctx_t ctx); +void gcry_log_debugsxp (const char *text, gcry_sexp_t sexp); + + /* Log levels used by the internal logging facility. */ enum gcry_log_levels { diff --git a/src/libgcrypt.def b/src/libgcrypt.def index 9fa4245..7efb3b9 100644 --- a/src/libgcrypt.def +++ b/src/libgcrypt.def @@ -247,5 +247,11 @@ EXPORTS gcry_md_hash_buffers @219 + gcry_log_debug @220 + gcry_log_debughex @221 + gcry_log_debugmpi @222 + gcry_log_debugpnt @223 + gcry_log_debugsxp @224 + ;; end of file with public symbols for Windows. diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers index 904ab41..b1669fd 100644 --- a/src/libgcrypt.vers +++ b/src/libgcrypt.vers @@ -101,6 +101,9 @@ GCRYPT_1.6 { gcry_mpi_ec_dup; gcry_mpi_ec_add; gcry_mpi_ec_mul; gcry_mpi_ec_curve_point; + gcry_log_debug; + gcry_log_debughex; gcry_log_debugmpi; gcry_log_debugpnt; gcry_log_debugsxp; + _gcry_mpi_get_const; gcry_ctx_release; diff --git a/src/misc.c b/src/misc.c index a19e1e4..d9b85cb 100644 --- a/src/misc.c +++ b/src/misc.c @@ -115,7 +115,7 @@ _gcry_log_verbosity( int level ) * This is our log function which prints all log messages to stderr or * using the function defined with gcry_set_log_handler(). */ -static void +void _gcry_logv( int level, const char *fmt, va_list arg_ptr ) { if (log_handler) @@ -361,6 +361,55 @@ _gcry_log_printmpi (const char *text, gcry_mpi_t mpi) } } +/* Print SEXP in human readabale format. With TEXT of NULL print just the raw + dump without any wrappping, with TEXT an empty string, print a + trailing linefeed, otherwise print the full debug output. */ +void +_gcry_log_printsxp (const char *text, gcry_sexp_t sexp) +{ + int with_lf = 0; + + if (text && *text) + { + if ((with_lf = strchr (text, '\n'))) + log_debug ("%s", text); + else + log_debug ("%s: ", text); + } + if (sexp) + { + int any = 0; + char *buf, *p, *pend; + size_t size; + + size = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); + p = buf = gcry_xmalloc (size); + gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, size); + + do + { + if (any && !with_lf) + log_debug ("%*s ", (int)strlen(text), ""); + else + any = 1; + pend = strchr (p, '\n'); + size = pend? (pend - p) : strlen (p); + if (with_lf) + log_debug ("%.*s\n", (int)size, p); + else + log_printf ("%.*s\n", (int)size, p); + if (pend) + p = pend + 1; + else + p += size; + } + while (*p); + gcry_free (buf); + } + if (text) + log_printf ("\n"); +} + void _gcry_burn_stack (unsigned int bytes) diff --git a/src/visibility.c b/src/visibility.c index cfb159f..6e3c755 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -1209,6 +1209,42 @@ gcry_ctx_release (gcry_ctx_t ctx) } void +gcry_log_debug (const char *fmt, ...) +{ + va_list arg_ptr ; + + va_start( arg_ptr, fmt ) ; + _gcry_logv (GCRY_LOG_DEBUG, fmt, arg_ptr); + va_end (arg_ptr); +} + +void +gcry_log_debughex (const char *text, const void *buffer, size_t length) +{ + _gcry_log_printhex (text, buffer, length); +} + +void +gcry_log_debugmpi (const char *text, gcry_mpi_t mpi) +{ + _gcry_log_printmpi (text, mpi); +} + +void +gcry_log_debugpnt (const char *text, mpi_point_t point, gcry_ctx_t ctx) +{ + mpi_ec_t ec = ctx? _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC) : NULL; + + _gcry_mpi_point_log (text, point, ec); +} + +void +gcry_log_debugsxp (const char *text, gcry_sexp_t sexp) +{ + _gcry_log_printsxp (text, sexp); +} + +void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data) { _gcry_set_progress_handler (cb, cb_data); diff --git a/src/visibility.h b/src/visibility.h index 5e3556c..7e7793b 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -604,6 +604,12 @@ MARK_VISIBLE (gcry_mpi_test_bit) MARK_VISIBLE (gcry_ctx_release) +MARK_VISIBLEX(gcry_log_debug) +MARK_VISIBLEX(gcry_log_debughex) +MARK_VISIBLEX(gcry_log_debugmpi) +MARK_VISIBLEX(gcry_log_debugpnt) +MARK_VISIBLEX(gcry_log_debugsxp) + /* Functions used to implement macros. */ MARK_VISIBLEX(_gcry_mpi_get_const) ----------------------------------------------------------------------- Summary of changes: NEWS | 4 ++++ src/g10lib.h | 4 ++++ src/gcrypt.h.in | 14 ++++++++++++++ src/libgcrypt.def | 6 ++++++ src/libgcrypt.vers | 3 +++ src/misc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/visibility.c | 36 ++++++++++++++++++++++++++++++++++++ src/visibility.h | 6 ++++++ 8 files changed, 123 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Mon Sep 30 20:11:16 2013 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Mon, 30 Sep 2013 20:11:16 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-278-g68cefd0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 68cefd0f1d60ac33b58031df9b1d165cb1bf0f14 (commit) via a96d622e1a36d40d1504b7ada567e90ec9957443 (commit) via 10d7351411f19bb2c03d2e24ca5a38dabe45023b (commit) from d2076f27bb7c5d505abf25fc622d21794c4a5df3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 68cefd0f1d60ac33b58031df9b1d165cb1bf0f14 Author: Jussi Kivilinna Date: Sat Sep 21 13:54:38 2013 +0300 Make Whirlpool use the _gcry_md_block_write helper * cipher/whirlpool.c (whirlpool_context_t): Add 'bctx', remove 'buffer', 'count' and 'nblocks'. (whirlpool_init): Initialize 'bctx'. (whirlpool_transform): Adjust context argument type and burn stack depth. (whirlpool_add): Remove. (whirlpool_write): Use _gcry_md_block_write. (whirlpool_final, whirlpool_read): Adjust for 'bctx' usage. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/hash-common.h b/cipher/hash-common.h index 3caf0a7..ce91da5 100644 --- a/cipher/hash-common.h +++ b/cipher/hash-common.h @@ -32,8 +32,8 @@ const char * _gcry_hash_selftest_check_one typedef unsigned int (*_gcry_md_block_write_t) (void *c, const unsigned char *buf); -#if defined(HAVE_U64_TYPEDEF) && defined(USE_SHA512) -/* SHA-512 needs u64 and larger buffer. */ +#if defined(HAVE_U64_TYPEDEF) && (defined(USE_SHA512) || defined(USE_WHIRLPOOL)) +/* SHA-512 needs u64 and larger buffer. Whirlpool needs u64. */ # define MD_BLOCK_MAX_BLOCKSIZE 128 # define MD_NBLOCKS_TYPE u64 #else diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c index 6b5f1a9..fa632f9 100644 --- a/cipher/whirlpool.c +++ b/cipher/whirlpool.c @@ -38,6 +38,7 @@ #include "cipher.h" #include "bufhelp.h" +#include "hash-common.h" /* Size of a whirlpool block (in bytes). */ #define BLOCK_SIZE 64 @@ -51,10 +52,8 @@ typedef u64 whirlpool_block_t[BLOCK_SIZE / 8]; typedef struct { + gcry_md_block_ctx_t bctx; whirlpool_block_t hash_state; - unsigned char buffer[BLOCK_SIZE]; - size_t count; - u64 nblocks; } whirlpool_context_t; @@ -1161,12 +1160,20 @@ static const u64 C7[256] = +static unsigned int +whirlpool_transform (void *ctx, const unsigned char *data); + + + static void whirlpool_init (void *ctx) { whirlpool_context_t *context = ctx; memset (context, 0, sizeof (*context)); + + context->bctx.blocksize = BLOCK_SIZE; + context->bctx.bwrite = whirlpool_transform; } @@ -1174,8 +1181,9 @@ whirlpool_init (void *ctx) * Transform block. */ static unsigned int -whirlpool_transform (whirlpool_context_t *context, const unsigned char *data) +whirlpool_transform (void *ctx, const unsigned char *data) { + whirlpool_context_t *context = ctx; whirlpool_block_t data_block; whirlpool_block_t key; whirlpool_block_t state; @@ -1269,67 +1277,18 @@ whirlpool_transform (whirlpool_context_t *context, const unsigned char *data) block_xor (context->hash_state, state, i); return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + - 3 * sizeof(void*); -} - -static void -whirlpool_add (whirlpool_context_t *context, - const void *buffer_arg, size_t buffer_n) -{ - const unsigned char *buffer = buffer_arg; - unsigned int burn = 0; - - if (context->count == BLOCK_SIZE) - { - /* Flush the buffer. */ - burn = whirlpool_transform (context, context->buffer); - _gcry_burn_stack (burn); - burn = 0; - context->count = 0; - context->nblocks++; - } - if (! buffer) - return; /* Nothing to add. */ - - if (context->count) - { - while (buffer_n && (context->count < BLOCK_SIZE)) - { - context->buffer[context->count++] = *buffer++; - buffer_n--; - } - whirlpool_add (context, NULL, 0); - /* Can return early now that bit counter calculation is done in final. */ - if (!buffer_n) - return; - } - - while (buffer_n >= BLOCK_SIZE) - { - burn = whirlpool_transform (context, buffer); - context->count = 0; - context->nblocks++; - buffer_n -= BLOCK_SIZE; - buffer += BLOCK_SIZE; - } - while (buffer_n && (context->count < BLOCK_SIZE)) - { - context->buffer[context->count++] = *buffer++; - buffer_n--; - } - - _gcry_burn_stack (burn); + 4 * sizeof(void*); } static void whirlpool_write (void *ctx, const void *buffer, size_t buffer_n) { whirlpool_context_t *context = ctx; - u64 old_nblocks = context->nblocks; + u64 old_nblocks = context->bctx.nblocks; - whirlpool_add (context, buffer, buffer_n); + _gcry_md_block_write (context, buffer, buffer_n); - gcry_assert (old_nblocks <= context->nblocks); + gcry_assert (old_nblocks <= context->bctx.nblocks); } static void @@ -1340,13 +1299,13 @@ whirlpool_final (void *ctx) u64 t, lsb, msb; unsigned char *length; - t = context->nblocks; + t = context->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 58; /* add the count */ t = lsb; - if ((lsb += context->count) < t) + if ((lsb += context->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -1358,28 +1317,28 @@ whirlpool_final (void *ctx) whirlpool_write (context, NULL, 0); /* Pad. */ - context->buffer[context->count++] = 0x80; + context->bctx.buf[context->bctx.count++] = 0x80; - if (context->count > 32) + if (context->bctx.count > 32) { /* An extra block is necessary. */ - while (context->count < 64) - context->buffer[context->count++] = 0; + while (context->bctx.count < 64) + context->bctx.buf[context->bctx.count++] = 0; whirlpool_write (context, NULL, 0); } - while (context->count < 32) - context->buffer[context->count++] = 0; + while (context->bctx.count < 32) + context->bctx.buf[context->bctx.count++] = 0; /* Add length of message. */ - length = context->buffer + context->count; + length = context->bctx.buf + context->bctx.count; buf_put_be64(&length[0 * 8], 0); buf_put_be64(&length[1 * 8], 0); buf_put_be64(&length[2 * 8], msb); buf_put_be64(&length[3 * 8], lsb); - context->count += 32; + context->bctx.count += 32; whirlpool_write (context, NULL, 0); - block_to_buffer (context->buffer, context->hash_state, i); + block_to_buffer (context->bctx.buf, context->hash_state, i); } static byte * @@ -1387,7 +1346,7 @@ whirlpool_read (void *ctx) { whirlpool_context_t *context = ctx; - return context->buffer; + return context->bctx.buf; } gcry_md_spec_t _gcry_digest_spec_whirlpool = commit a96d622e1a36d40d1504b7ada567e90ec9957443 Author: Jussi Kivilinna Date: Sat Sep 21 13:54:38 2013 +0300 whirlpool: add stack burning after transform * cipher/whirlpool.c (whirlpool_transform): Return burn stack depth. (whirlpool_add): Do burn_stack. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c index 1ee8916..6b5f1a9 100644 --- a/cipher/whirlpool.c +++ b/cipher/whirlpool.c @@ -1173,7 +1173,7 @@ whirlpool_init (void *ctx) /* * Transform block. */ -static void +static unsigned int whirlpool_transform (whirlpool_context_t *context, const unsigned char *data) { whirlpool_block_t data_block; @@ -1267,6 +1267,9 @@ whirlpool_transform (whirlpool_context_t *context, const unsigned char *data) block_xor (context->hash_state, data_block, i); block_xor (context->hash_state, state, i); + + return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + + 3 * sizeof(void*); } static void @@ -1274,12 +1277,14 @@ whirlpool_add (whirlpool_context_t *context, const void *buffer_arg, size_t buffer_n) { const unsigned char *buffer = buffer_arg; + unsigned int burn = 0; if (context->count == BLOCK_SIZE) { /* Flush the buffer. */ - whirlpool_transform (context, context->buffer); - /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */ + burn = whirlpool_transform (context, context->buffer); + _gcry_burn_stack (burn); + burn = 0; context->count = 0; context->nblocks++; } @@ -1298,11 +1303,10 @@ whirlpool_add (whirlpool_context_t *context, if (!buffer_n) return; } - /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */ while (buffer_n >= BLOCK_SIZE) { - whirlpool_transform (context, buffer); + burn = whirlpool_transform (context, buffer); context->count = 0; context->nblocks++; buffer_n -= BLOCK_SIZE; @@ -1313,6 +1317,8 @@ whirlpool_add (whirlpool_context_t *context, context->buffer[context->count++] = *buffer++; buffer_n--; } + + _gcry_burn_stack (burn); } static void commit 10d7351411f19bb2c03d2e24ca5a38dabe45023b Author: Jussi Kivilinna Date: Sat Sep 21 13:54:38 2013 +0300 whirlpool: do bitcount calculation in finalization part * cipher/whirlpool.c (whirlpool_context_t): Remove 'length', add 'nblocks'. (whirlpool_add): Update 'nblocks' instead of 'length', and add early return at one spot. (whirlpool_write): Check for 'nblocks' overflow. (whirlpool_final): Convert 'nblocks' to bit-counter, and use whirlpool_write instead of whirlpool_add. -- Currently Whirlpool uses large 256 bit counter that is increased in the 'write' function. However, we could to bit counter calculation as is done in all the rest hash algorithms; use 64-bit block counter that is converted to bit counter in finalization function. This change does limit amount of bytes Whirlpool can process before overflowing bit counter. With 256-bit counter, overflow happens after ~1.3e67 gigabytes. With 64-bit block counter, overflow happens just after ~1.1e12 gigabytes. Patch keeps the old behaviour of halting if counter overflows. Main benefit for this patch is that after this change, we can use the _gcry_md_block_write helper for Whirlpool too. Signed-off-by: Jussi Kivilinna diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c index 954640a..1ee8916 100644 --- a/cipher/whirlpool.c +++ b/cipher/whirlpool.c @@ -54,7 +54,7 @@ typedef struct { whirlpool_block_t hash_state; unsigned char buffer[BLOCK_SIZE]; size_t count; - unsigned char length[32]; + u64 nblocks; } whirlpool_context_t; @@ -1274,11 +1274,6 @@ whirlpool_add (whirlpool_context_t *context, const void *buffer_arg, size_t buffer_n) { const unsigned char *buffer = buffer_arg; - u64 buffer_size; - unsigned int carry; - unsigned int i; - - buffer_size = buffer_n; if (context->count == BLOCK_SIZE) { @@ -1286,6 +1281,7 @@ whirlpool_add (whirlpool_context_t *context, whirlpool_transform (context, context->buffer); /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */ context->count = 0; + context->nblocks++; } if (! buffer) return; /* Nothing to add. */ @@ -1298,6 +1294,9 @@ whirlpool_add (whirlpool_context_t *context, buffer_n--; } whirlpool_add (context, NULL, 0); + /* Can return early now that bit counter calculation is done in final. */ + if (!buffer_n) + return; } /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */ @@ -1305,6 +1304,7 @@ whirlpool_add (whirlpool_context_t *context, { whirlpool_transform (context, buffer); context->count = 0; + context->nblocks++; buffer_n -= BLOCK_SIZE; buffer += BLOCK_SIZE; } @@ -1313,29 +1313,17 @@ whirlpool_add (whirlpool_context_t *context, context->buffer[context->count++] = *buffer++; buffer_n--; } - - /* Update bit counter. */ - carry = 0; - buffer_size <<= 3; - for (i = 1; i <= 32; i++) - { - if (! (buffer_size || carry)) - break; - - carry += context->length[32 - i] + (buffer_size & 0xFF); - context->length[32 - i] = carry; - buffer_size >>= 8; - carry >>= 8; - } - gcry_assert (! (buffer_size || carry)); } static void whirlpool_write (void *ctx, const void *buffer, size_t buffer_n) { whirlpool_context_t *context = ctx; + u64 old_nblocks = context->nblocks; whirlpool_add (context, buffer, buffer_n); + + gcry_assert (old_nblocks <= context->nblocks); } static void @@ -1343,9 +1331,25 @@ whirlpool_final (void *ctx) { whirlpool_context_t *context = ctx; unsigned int i; + u64 t, lsb, msb; + unsigned char *length; + + t = context->nblocks; + /* multiply by 64 to make a byte count */ + lsb = t << 6; + msb = t >> 58; + /* add the count */ + t = lsb; + if ((lsb += context->count) < t) + msb++; + /* multiply by 8 to make a bit count */ + t = lsb; + lsb <<= 3; + msb <<= 3; + msb |= t >> 61; /* Flush. */ - whirlpool_add (context, NULL, 0); + whirlpool_write (context, NULL, 0); /* Pad. */ context->buffer[context->count++] = 0x80; @@ -1355,15 +1359,19 @@ whirlpool_final (void *ctx) /* An extra block is necessary. */ while (context->count < 64) context->buffer[context->count++] = 0; - whirlpool_add (context, NULL, 0); + whirlpool_write (context, NULL, 0); } while (context->count < 32) context->buffer[context->count++] = 0; /* Add length of message. */ - memcpy (context->buffer + context->count, context->length, 32); + length = context->buffer + context->count; + buf_put_be64(&length[0 * 8], 0); + buf_put_be64(&length[1 * 8], 0); + buf_put_be64(&length[2 * 8], msb); + buf_put_be64(&length[3 * 8], lsb); context->count += 32; - whirlpool_add (context, NULL, 0); + whirlpool_write (context, NULL, 0); block_to_buffer (context->buffer, context->hash_state, i); } ----------------------------------------------------------------------- Summary of changes: cipher/hash-common.h | 4 +- cipher/whirlpool.c | 131 ++++++++++++++++++++------------------------------ 2 files changed, 54 insertions(+), 81 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Mon Sep 30 21:23:11 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 30 Sep 2013 21:23:11 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-281-ga2618c8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via a2618c822e666d4121cba29bee3fd50bf70c9743 (commit) via c325adb8f5092b80a626bd3bb5e49cf7f3a29fc8 (commit) via d69a13d3d1c14ad6a6aa7cd349d6d2dfb152d422 (commit) from 68cefd0f1d60ac33b58031df9b1d165cb1bf0f14 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a2618c822e666d4121cba29bee3fd50bf70c9743 Author: Werner Koch Date: Mon Sep 30 20:32:20 2013 +0200 ecc: Prepare for future Ed25519 optimization. * mpi/ec-ed25519.c: New but empty file. * mpi/ec-internal.h: New. * mpi/ec.c: Include ec-internal.h. (ec_mod): New. (ec_addm): Use ec_mod. (ec_mulm): Remove commented code. Use ec_mod. (ec_subm): Call simple sub. (ec_pow2): Use ec_mulm. (ec_mul2): New. (dup_point_weierstrass): Use ec_mul2. (dup_point_twistededwards): Add special case for a == -1. Use ec_mul2. (add_points_weierstrass): Use ec_mul2. (add_points_twistededwards): Add special case for a == -1. (_gcry_mpi_ec_curve_point): Ditto. (ec_p_init): Add hack to test Barrett functions. * src/ec-context.h (mpi_ec_ctx_s): Add P_BARRETT. * mpi/mpi-mod.c (_gcry_mpi_mod_barrett): Fix sign problem. Signed-off-by: Werner Koch diff --git a/mpi/Makefile.am b/mpi/Makefile.am index e900539..c41b1ea 100644 --- a/mpi/Makefile.am +++ b/mpi/Makefile.am @@ -174,4 +174,4 @@ libmpi_la_SOURCES = longlong.h \ mpih-div.c \ mpih-mul.c \ mpiutil.c \ - ec.c + ec.c ec-internal.h ec-ed25519.c diff --git a/mpi/ec-ed25519.c b/mpi/ec-ed25519.c new file mode 100644 index 0000000..acfe2a6 --- /dev/null +++ b/mpi/ec-ed25519.c @@ -0,0 +1,37 @@ +/* ec-ed25519.c - Ed25519 optimized elliptic curve functions + * Copyright (C) 2013 g10 Code GmbH + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include +#include +#include +#include + +#include "mpi-internal.h" +#include "longlong.h" +#include "g10lib.h" +#include "context.h" +#include "ec-context.h" + + +void +_gcry_mpi_ec_ed25519_mod (gcry_mpi_t a) +{ + (void)a; + +} diff --git a/mpi/ec-internal.h b/mpi/ec-internal.h new file mode 100644 index 0000000..759335a --- /dev/null +++ b/mpi/ec-internal.h @@ -0,0 +1,25 @@ +/* ec-internal.h - Internal declarations of ec*.c + * Copyright (C) 2013 g10 Code GmbH + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef GCRY_EC_INTERNAL_H +#define GCRY_EC_INTERNAL_H + +void _gcry_mpi_ec_ed25519_mod (gcry_mpi_t a); + +#endif /*GCRY_EC_INTERNAL_H*/ diff --git a/mpi/ec.c b/mpi/ec.c index de681a1..889df8e 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -28,6 +28,7 @@ #include "g10lib.h" #include "context.h" #include "ec-context.h" +#include "ec-internal.h" #define point_init(a) _gcry_mpi_point_init ((a)) @@ -224,131 +225,46 @@ gcry_mpi_point_snatch_set (mpi_point_t point, } +/* W = W mod P. */ +static void +ec_mod (gcry_mpi_t w, mpi_ec_t ec) +{ + if (0 && ec->dialect == ECC_DIALECT_ED25519) + _gcry_mpi_ec_ed25519_mod (w); + else if (ec->t.p_barrett) + _gcry_mpi_mod_barrett (w, w, ec->t.p_barrett); + else + _gcry_mpi_mod (w, w, ec->p); +} + static void ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) { - mpi_addm (w, u, v, ctx->p); + gcry_mpi_add (w, u, v); + ec_mod (w, ctx); } static void -ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) +ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec) { - mpi_subm (w, u, v, ctx->p); + (void)ec; + gcry_mpi_sub (w, u, v); + /*ec_mod (w, ec);*/ } static void ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) { -#if 0 - /* NOTE: This code works only for limb sizes of 32 bit. */ - mpi_limb_t *wp, *sp; + mpi_mul (w, u, v); + ec_mod (w, ctx); +} - if (ctx->nist_nbits == 192) - { - mpi_mul (w, u, v); - mpi_resize (w, 12); - wp = w->d; - - sp = ctx->s[0]->d; - sp[0*2+0] = wp[0*2+0]; - sp[0*2+1] = wp[0*2+1]; - sp[1*2+0] = wp[1*2+0]; - sp[1*2+1] = wp[1*2+1]; - sp[2*2+0] = wp[2*2+0]; - sp[2*2+1] = wp[2*2+1]; - - sp = ctx->s[1]->d; - sp[0*2+0] = wp[3*2+0]; - sp[0*2+1] = wp[3*2+1]; - sp[1*2+0] = wp[3*2+0]; - sp[1*2+1] = wp[3*2+1]; - sp[2*2+0] = 0; - sp[2*2+1] = 0; - - sp = ctx->s[2]->d; - sp[0*2+0] = 0; - sp[0*2+1] = 0; - sp[1*2+0] = wp[4*2+0]; - sp[1*2+1] = wp[4*2+1]; - sp[2*2+0] = wp[4*2+0]; - sp[2*2+1] = wp[4*2+1]; - - sp = ctx->s[3]->d; - sp[0*2+0] = wp[5*2+0]; - sp[0*2+1] = wp[5*2+1]; - sp[1*2+0] = wp[5*2+0]; - sp[1*2+1] = wp[5*2+1]; - sp[2*2+0] = wp[5*2+0]; - sp[2*2+1] = wp[5*2+1]; - - ctx->s[0]->nlimbs = 6; - ctx->s[1]->nlimbs = 6; - ctx->s[2]->nlimbs = 6; - ctx->s[3]->nlimbs = 6; - - mpi_add (ctx->c, ctx->s[0], ctx->s[1]); - mpi_add (ctx->c, ctx->c, ctx->s[2]); - mpi_add (ctx->c, ctx->c, ctx->s[3]); - - while ( mpi_cmp (ctx->c, ctx->p ) >= 0 ) - mpi_sub ( ctx->c, ctx->c, ctx->p ); - mpi_set (w, ctx->c); - } - else if (ctx->nist_nbits == 384) - { - int i; - mpi_mul (w, u, v); - mpi_resize (w, 24); - wp = w->d; - -#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \ - sp = ctx->s[(a)]->d; \ - i = 0; } while (0) -#define X(a) do { sp[i++] = wp[(a)];} while (0) -#define X0(a) do { sp[i++] = 0; } while (0) - NEXT(0); - X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11); - NEXT(1); - X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0(); - NEXT(2); - X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23); - NEXT(3); - X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20); - NEXT(4); - X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19); - NEXT(5); - X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0(); - NEXT(6); - X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0(); - NEXT(7); - X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22); - NEXT(8); - X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0(); - NEXT(9); - X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0(); -#undef X0 -#undef X -#undef NEXT - mpi_add (ctx->c, ctx->s[0], ctx->s[1]); - mpi_add (ctx->c, ctx->c, ctx->s[1]); - mpi_add (ctx->c, ctx->c, ctx->s[2]); - mpi_add (ctx->c, ctx->c, ctx->s[3]); - mpi_add (ctx->c, ctx->c, ctx->s[4]); - mpi_add (ctx->c, ctx->c, ctx->s[5]); - mpi_add (ctx->c, ctx->c, ctx->s[6]); - mpi_sub (ctx->c, ctx->c, ctx->s[7]); - mpi_sub (ctx->c, ctx->c, ctx->s[8]); - mpi_sub (ctx->c, ctx->c, ctx->s[9]); - - while ( mpi_cmp (ctx->c, ctx->p ) >= 0 ) - mpi_sub ( ctx->c, ctx->c, ctx->p ); - while ( ctx->c->sign ) - mpi_add ( ctx->c, ctx->c, ctx->p ); - mpi_set (w, ctx->c); - } - else -#endif /*0*/ - mpi_mulm (w, u, v, ctx->p); +/* W = 2 * U mod P. */ +static void +ec_mul2 (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx) +{ + mpi_lshift (w, u, 1); + ec_mod (w, ctx); } static void @@ -368,7 +284,7 @@ ec_pow2 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx) { /* Using mpi_mul is slightly faster (at least on amd64). */ /* mpi_powm (w, b, mpi_const (MPI_C_TWO), ctx->p); */ - mpi_mulm (w, b, b, ctx->p); + ec_mulm (w, b, b, ctx); } @@ -437,6 +353,15 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model, gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b) { int i; + static int use_barrett; + + if (!use_barrett) + { + if (getenv ("GCRYPT_BARRETT")) + use_barrett = 1; + else + use_barrett = -1; + } /* Fixme: Do we want to check some constraints? e.g. a < p */ @@ -451,6 +376,8 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model, if (b && model == MPI_EC_TWISTEDEDWARDS) ctx->b = mpi_copy (b); + ctx->t.p_barrett = use_barrett > 0? _gcry_mpi_barrett_init (ctx->p, 0):NULL; + _gcry_mpi_ec_get_reset (ctx); /* Allocate scratch variables. */ @@ -483,6 +410,8 @@ ec_deinit (void *opaque) mpi_ec_t ctx = opaque; int i; + _gcry_mpi_barrett_free (ctx->t.p_barrett); + /* Domain parameter. */ mpi_free (ctx->p); mpi_free (ctx->a); @@ -732,7 +661,7 @@ dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) } /* Z3 = 2YZ */ ec_mulm (z3, point->y, point->z, ctx); - ec_mulm (z3, z3, mpi_const (MPI_C_TWO), ctx); + ec_mul2 (z3, z3, ctx); /* L2 = 4XY^2 */ /* T2: used for Y2; required later. */ @@ -743,7 +672,7 @@ dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) /* X3 = L1^2 - 2L2 */ /* T1: used for L2^2. */ ec_pow2 (x3, l1, ctx); - ec_mulm (t1, l2, mpi_const (MPI_C_TWO), ctx); + ec_mul2 (t1, l2, ctx); ec_subm (x3, x3, t1, ctx); /* L3 = 8Y^4 */ @@ -811,7 +740,13 @@ dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) ec_pow2 (D, Y1, ctx); /* E = aC */ - ec_mulm (E, ctx->a, C, ctx); + if (ctx->dialect == ECC_DIALECT_ED25519) + { + mpi_set (E, C); + _gcry_mpi_neg (E, E); + } + else + ec_mulm (E, ctx->a, C, ctx); /* F = E + D */ ec_addm (F, E, D, ctx); @@ -820,7 +755,7 @@ dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) ec_pow2 (H, Z1, ctx); /* J = F - 2H */ - ec_mulm (J, H, mpi_const (MPI_C_TWO), ctx); + ec_mul2 (J, H, ctx); ec_subm (J, F, J, ctx); /* X_3 = (B - C - D) ? J */ @@ -978,7 +913,7 @@ add_points_weierstrass (mpi_point_t result, ec_mulm (t2, t2, l7, ctx); ec_subm (x3, t1, t2, ctx); /* l9 = l7 l3^2 - 2 x3 */ - ec_mulm (t1, x3, mpi_const (MPI_C_TWO), ctx); + ec_mul2 (t1, x3, ctx); ec_subm (l9, t2, t1, ctx); /* y3 = (l9 l6 - l8 l3^3)/2 */ ec_mulm (l9, l9, l6, ctx); @@ -1085,8 +1020,19 @@ add_points_twistededwards (mpi_point_t result, ec_mulm (X3, X3, A, ctx); /* Y_3 = A ? G ? (D - aC) */ - ec_mulm (Y3, ctx->a, C, ctx); - ec_subm (Y3, D, Y3, ctx); + if (ctx->dialect == ECC_DIALECT_ED25519) + { + /* Using ec_addm (Y3, D, C, ctx) is possible but a litte bit + slower because a subm does currently skip the mod step. */ + mpi_set (Y3, C); + _gcry_mpi_neg (Y3, Y3); + ec_subm (Y3, D, Y3, ctx); + } + else + { + ec_mulm (Y3, ctx->a, C, ctx); + ec_subm (Y3, D, Y3, ctx); + } ec_mulm (Y3, Y3, G, ctx); ec_mulm (Y3, Y3, A, ctx); @@ -1282,7 +1228,13 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) /* a ? x^2 + y^2 - 1 - b ? x^2 ? y^2 == 0 */ ec_pow2 (x, x, ctx); ec_pow2 (y, y, ctx); - ec_mulm (w, ctx->a, x, ctx); + if (ctx->dialect == ECC_DIALECT_ED25519) + { + mpi_set (w, x); + _gcry_mpi_neg (w, w); + } + else + ec_mulm (w, ctx->a, x, ctx); ec_addm (w, w, y, ctx); ec_subm (w, w, mpi_const (MPI_C_ONE), ctx); ec_mulm (x, x, y, ctx); diff --git a/mpi/mpi-mod.c b/mpi/mpi-mod.c index 795826e..3d6248b 100644 --- a/mpi/mpi-mod.c +++ b/mpi/mpi-mod.c @@ -111,7 +111,7 @@ _gcry_mpi_barrett_free (mpi_barrett_t ctx) _gcry_mpi_barrett_init must have been called to do the precalculations. CTX is the context created by this precalculation and also conveys M. If the Barret reduction could no be done a - starightforward reduction method is used. + straightforward reduction method is used. We assume that these conditions are met: Input: x =(x_2k-1 ...x_0)_b @@ -126,6 +126,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx) gcry_mpi_t y = ctx->y; gcry_mpi_t r1 = ctx->r1; gcry_mpi_t r2 = ctx->r2; + int sign; mpi_normalize (x); if (mpi_get_nlimbs (x) > 2*k ) @@ -134,6 +135,9 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx) return; } + sign = x->sign; + x->sign = 0; + /* 1. q1 = floor( x / b^k-1) * q2 = q1 * y * q3 = floor( q2 / b^k+1 ) @@ -172,6 +176,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx) while ( mpi_cmp( r, m ) >= 0 ) mpi_sub ( r, r, m ); + x->sign = sign; } diff --git a/src/ec-context.h b/src/ec-context.h index 8dce7a7..ba6bdfc 100644 --- a/src/ec-context.h +++ b/src/ec-context.h @@ -53,6 +53,8 @@ struct mpi_ec_ctx_s gcry_mpi_t two_inv_p; + mpi_barrett_t p_barrett; + /* Scratch variables. */ gcry_mpi_t scratch[11]; diff --git a/src/misc.c b/src/misc.c index d577b24..912039a 100644 --- a/src/misc.c +++ b/src/misc.c @@ -396,7 +396,8 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp) { int any = 0; int n_closing; - char *buf, *p, *pend; + char *buf, *pend; + const char *p; size_t size; size = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); commit c325adb8f5092b80a626bd3bb5e49cf7f3a29fc8 Author: Werner Koch Date: Mon Sep 30 20:17:05 2013 +0200 ecc: Fix recomputing of Q for Ed25519. * cipher/ecc-misc.c (reverse_buffer): New. (_gcry_ecc_compute_public): Add ED255519 specific code. * cipher/ecc.c (sign_eddsa): Allocate DIGEST in secure memory. Get rid of HASH_D. * tests/t-mpi-point.c (context_param): Test recomputing of Q for Ed25519. Signed-off-by: Werner Koch diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 1dc0480..d89971f 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -234,22 +234,96 @@ _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value) } +static void +reverse_buffer (unsigned char *buffer, unsigned int length) +{ + unsigned int tmp, i; + + for (i=0; i < length/2; i++) + { + tmp = buffer[i]; + buffer[i] = buffer[length-1-i]; + buffer[length-1-i] = tmp; + } +} + + /* Compute the public key from the the context EC. Obviously a requirement is that the secret key is available in EC. On success - Q is returned; on error NULL. If Q is NULL a newly allocated pint + Q is returned; on error NULL. If Q is NULL a newly allocated point is returned. */ mpi_point_t _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec) { + int rc; + if (!ec->d || !ec->G || !ec->p || !ec->a) return NULL; if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b) return NULL; - if (!Q) - Q = gcry_mpi_point_new (0); - if (!Q) - return NULL; - _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec); + switch (ec->dialect) + { + case ECC_DIALECT_ED25519: + { + gcry_mpi_t a; + unsigned char *rawmpi = NULL; + unsigned int rawmpilen; + unsigned char *digest; + gcry_buffer_t hvec[2]; + int b = (ec->nbits+7)/8; + + gcry_assert (b >= 32); + digest = gcry_calloc_secure (2, b); + if (!digest) + return NULL; + memset (hvec, 0, sizeof hvec); + + rawmpi = _gcry_mpi_get_buffer (ec->d, 0, &rawmpilen, NULL); + if (!rawmpi) + return NULL; + memset (digest, 0, b); + hvec[0].data = digest; + hvec[0].off = 0; + hvec[0].len = b > rawmpilen? b - rawmpilen : 0; + hvec[1].data = rawmpi; + hvec[1].off = 0; + hvec[1].len = rawmpilen; + /* FIXME: Put and take the hash algo from the context. */ + rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, digest, hvec, 2); + gcry_free (rawmpi); + if (rc) + { + gcry_free (digest); + return NULL; + } + + /* Compute the A value. */ + reverse_buffer (digest, 32); /* Only the first half of the hash. */ + digest[0] = (digest[0] & 0x7f) | 0x40; + digest[31] &= 0xf8; + a = mpi_snew (0); + _gcry_mpi_set_buffer (a, digest, 32, 0); + gcry_free (digest); + + /* And finally the public key. */ + if (!Q) + Q = gcry_mpi_point_new (0); + if (Q) + _gcry_mpi_ec_mul_point (Q, a, ec->G, ec); + mpi_free (a); + } + break; + + default: + { + if (!Q) + Q = gcry_mpi_point_new (0); + if (Q) + _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec); + } + break; + } + return Q; } diff --git a/cipher/ecc.c b/cipher/ecc.c index abd501f..a7fb90f 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -909,8 +909,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, mpi_ec_t ctx = NULL; int b; unsigned int tmp; - unsigned char hash_d[64]; /* Fixme: malloc in secure memory */ - unsigned char digest[64]; + unsigned char *digest; gcry_buffer_t hvec[3]; const void *mbuf; size_t mlen; @@ -938,37 +937,41 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, r = mpi_new (0); ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, skey->E.p, skey->E.a, skey->E.b); - b = ctx->nbits/8; + b = (ctx->nbits+7)/8; if (b != 256/8) return GPG_ERR_INTERNAL; /* We only support 256 bit. */ + digest = gcry_calloc_secure (2, b); + if (!digest) + { + rc = gpg_err_code_from_syserror (); + goto leave; + } - /* Hash the secret key. We clear DIGEST so we can use it to left - pad the key with zeroes for hashing. */ + /* Hash the secret key. We clear DIGEST so we can use it as input + to left pad the key with zeroes for hashing. */ rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL); if (!rawmpi) { rc = gpg_err_code_from_syserror (); goto leave; } - memset (digest, 0, b); hvec[0].data = digest; hvec[0].off = 0; hvec[0].len = b > rawmpilen? b - rawmpilen : 0; hvec[1].data = rawmpi; hvec[1].off = 0; hvec[1].len = rawmpilen; - rc = _gcry_md_hash_buffers (hashalgo, 0, hash_d, hvec, 2); + rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2); gcry_free (rawmpi); rawmpi = NULL; if (rc) goto leave; - /* Compute the A value (this modifies hash_d). */ - reverse_buffer (hash_d, 32); /* Only the first half of the hash. */ - hash_d[0] = (hash_d[0] & 0x7f) | 0x40; - hash_d[31] &= 0xf8; - _gcry_mpi_set_buffer (a, hash_d, 32, 0); - /* log_printmpi (" a", a); */ + /* Compute the A value (this modifies DIGEST). */ + reverse_buffer (digest, 32); /* Only the first half of the hash. */ + digest[0] = (digest[0] & 0x7f) | 0x40; + digest[31] &= 0xf8; + _gcry_mpi_set_buffer (a, digest, 32, 0); /* Compute the public key if it has not been supplied as optional parameter. */ @@ -1001,7 +1004,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, if (DBG_CIPHER) log_printhex (" m", mbuf, mlen); - hvec[0].data = hash_d; + hvec[0].data = digest; hvec[0].off = 32; hvec[0].len = 32; hvec[1].data = (char*)mbuf; @@ -1063,6 +1066,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (r); + gcry_free (digest); _gcry_mpi_ec_free (ctx); point_free (&I); point_free (&Q); diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 0641779..5a0b311 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -666,9 +666,17 @@ context_param (void) "Ed25519", ctx); get_and_cmp_mpi ("q at eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx); - /* Delete Q by setting d and the clearing d. The clearing is + /* Set d tosee whether Q is correctly re-computed. */ + d = hex2mpi (sample_ed25519_d); + err = gcry_mpi_ec_set_mpi ("d", d, ctx); + if (err) + fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (d); + get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx); + + /* Delete Q by setting d and then clearing d. The clearing is required so that we can check whether Q has been cleared and - because further tests only expect a public key. */ + because further tests only expect a public key. */ d = hex2mpi (sample_ed25519_d); err = gcry_mpi_ec_set_mpi ("d", d, ctx); if (err) commit d69a13d3d1c14ad6a6aa7cd349d6d2dfb152d422 Author: Werner Koch Date: Mon Sep 30 13:20:06 2013 +0200 log: Try to print s-expressions in a more compact format. * src/misc.c (count_closing_parens): New. (_gcry_log_printsxp): Use new function. * mpi/ec.c (_gcry_mpi_point_log): Take care of a NULL point. Signed-off-by: Werner Koch diff --git a/mpi/ec.c b/mpi/ec.c index c6d0fc8..de681a1 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -42,6 +42,12 @@ _gcry_mpi_point_log (const char *name, mpi_point_t point, mpi_ec_t ctx) gcry_mpi_t x, y; char buf[100]; + if (!point) + { + snprintf (buf, sizeof buf - 1, "%s.*", name); + log_mpidump (buf, NULL); + return; + } snprintf (buf, sizeof buf - 1, "%s.X", name); if (ctx) diff --git a/src/misc.c b/src/misc.c index d9b85cb..d577b24 100644 --- a/src/misc.c +++ b/src/misc.c @@ -361,6 +361,22 @@ _gcry_log_printmpi (const char *text, gcry_mpi_t mpi) } } + +static int +count_closing_parens (const char *p) +{ + int count = 0; + + for (; *p; p++) + if (*p == ')') + count++; + else if (!strchr ("\n \t", *p)) + return 0; + + return count; +} + + /* Print SEXP in human readabale format. With TEXT of NULL print just the raw dump without any wrappping, with TEXT an empty string, print a trailing linefeed, otherwise print the full debug output. */ @@ -371,7 +387,7 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp) if (text && *text) { - if ((with_lf = strchr (text, '\n'))) + if ((with_lf = !!strchr (text, '\n'))) log_debug ("%s", text); else log_debug ("%s: ", text); @@ -379,6 +395,7 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp) if (sexp) { int any = 0; + int n_closing; char *buf, *p, *pend; size_t size; @@ -395,18 +412,26 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp) pend = strchr (p, '\n'); size = pend? (pend - p) : strlen (p); if (with_lf) - log_debug ("%.*s\n", (int)size, p); + log_debug ("%.*s", (int)size, p); else - log_printf ("%.*s\n", (int)size, p); + log_printf ("%.*s", (int)size, p); if (pend) p = pend + 1; else p += size; + n_closing = count_closing_parens (p); + if (n_closing) + { + while (n_closing--) + log_printf (")"); + p = ""; + } + log_printf ("\n"); } while (*p); gcry_free (buf); } - if (text) + else if (text) log_printf ("\n"); } ----------------------------------------------------------------------- Summary of changes: cipher/ecc-misc.c | 86 +++++++++++++- cipher/ecc.c | 32 +++--- mpi/Makefile.am | 2 +- cipher/gost.h => mpi/ec-ed25519.c | 30 +++-- src/hwf-common.h => mpi/ec-internal.h | 16 +-- mpi/ec.c | 200 +++++++++++++-------------------- mpi/mpi-mod.c | 7 +- src/ec-context.h | 2 + src/misc.c | 36 +++++- tests/t-mpi-point.c | 12 ++- 10 files changed, 251 insertions(+), 172 deletions(-) copy cipher/gost.h => mpi/ec-ed25519.c (63%) copy src/hwf-common.h => mpi/ec-internal.h (67%) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Mon Sep 30 21:46:34 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 30 Sep 2013 21:46:34 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-282-g1d85452 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 1d85452412b65e7976bc94969fc513ff6b880ed8 (commit) from a2618c822e666d4121cba29bee3fd50bf70c9743 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1d85452412b65e7976bc94969fc513ff6b880ed8 Author: Werner Koch Date: Mon Sep 30 21:14:11 2013 +0200 ecc: Use faster b parameter for Ed25519. * cipher/ecc-curves.c (domain_parms): Replace b. * tests/t-mpi-point.c (test_curve): Ditto. -- This change has been suggested by NIIBE Yutaka: Here, 0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4 is: (121666^-1 mod q)*121665. (121666^-1) * 121665 mod q is: 0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A While it works for both, I think that shorter is better. Signed-off-by: Werner Koch diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index 7447340..15888a8 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -103,7 +103,7 @@ static const ecc_domain_parms_t domain_parms[] = MPI_EC_TWISTEDEDWARDS, ECC_DIALECT_ED25519, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", "-0x01", - "-0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4", + "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", "0x6666666666666666666666666666666666666666666666666666666666666658" diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 5a0b311..a345cbc 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -125,7 +125,7 @@ static struct "Ed25519", "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", "-0x01", - "-0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4", + "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", "0x6666666666666666666666666666666666666666666666666666666666666658" ----------------------------------------------------------------------- Summary of changes: cipher/ecc-curves.c | 2 +- tests/t-mpi-point.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits