comparison dsa_sign_hash.c @ 0:d7da3b1e1540 libtomcrypt

put back the 0.95 makefile which was inadvertently merged over
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:21:40 +0000
parents
children 5d99163f7e32
comparison
equal deleted inserted replaced
-1:000000000000 0:d7da3b1e1540
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11 #include "mycrypt.h"
12
13 #ifdef MDSA
14
15 int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
16 unsigned char *out, unsigned long *outlen,
17 prng_state *prng, int wprng, dsa_key *key)
18 {
19 mp_int k, kinv, tmp, r, s;
20 unsigned char buf[512];
21 int err, y;
22 unsigned long len;
23
24
25 _ARGCHK(in != NULL);
26 _ARGCHK(out != NULL);
27 _ARGCHK(outlen != NULL);
28 _ARGCHK(key != NULL);
29
30 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
31 return err;
32 }
33 if (key->type != PK_PRIVATE) {
34 return CRYPT_PK_NOT_PRIVATE;
35 }
36
37 /* check group order size */
38 if (key->qord >= (int)sizeof(buf)) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 /* Init our temps */
43 if ((err = mp_init_multi(&k, &kinv, &r, &s, &tmp, NULL)) != MP_OKAY) { goto error; }
44
45 retry:
46
47 do {
48 /* gen random k */
49 if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
50 err = CRYPT_ERROR_READPRNG;
51 goto done;
52 }
53
54 /* read k */
55 if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != MP_OKAY) { goto error; }
56
57 /* k > 1 ? */
58 if (mp_cmp_d(&k, 1) != MP_GT) { goto retry; }
59
60 /* test gcd */
61 if ((err = mp_gcd(&k, &key->q, &tmp)) != MP_OKAY) { goto error; }
62 } while (mp_cmp_d(&tmp, 1) != MP_EQ);
63
64 /* now find 1/k mod q */
65 if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY) { goto error; }
66
67 /* now find r = g^k mod p mod q */
68 if ((err = mp_exptmod(&key->g, &k, &key->p, &r)) != MP_OKAY) { goto error; }
69 if ((err = mp_mod(&r, &key->q, &r)) != MP_OKAY) { goto error; }
70
71 if (mp_iszero(&r) == MP_YES) { goto retry; }
72
73 /* now find s = (in + xr)/k mod q */
74 if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; }
75 if ((err = mp_mul(&key->x, &r, &s)) != MP_OKAY) { goto error; }
76 if ((err = mp_add(&s, &tmp, &s)) != MP_OKAY) { goto error; }
77 if ((err = mp_mulmod(&s, &kinv, &key->q, &s)) != MP_OKAY) { goto error; }
78
79 if (mp_iszero(&s) == MP_YES) { goto retry; }
80
81 /* now store em both */
82
83 /* first check that we have enough room */
84 if (*outlen < (unsigned long)(PACKET_SIZE + 4 + mp_unsigned_bin_size(&s) + mp_unsigned_bin_size(&r))) {
85 err = CRYPT_BUFFER_OVERFLOW;
86 goto done;
87 }
88
89 /* packet header */
90 packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_SIGNED);
91 y = PACKET_SIZE;
92
93 /* store length of r */
94 len = mp_unsigned_bin_size(&r);
95 out[y++] = (len>>8)&255;
96 out[y++] = len&255;
97
98 /* store r */
99 if ((err = mp_to_unsigned_bin(&r, out+y)) != MP_OKAY) { goto error; }
100 y += len;
101
102 /* store length of s */
103 len = mp_unsigned_bin_size(&s);
104 out[y++] = (len>>8)&255;
105 out[y++] = len&255;
106
107 /* store s */
108 if ((err = mp_to_unsigned_bin(&s, out+y)) != MP_OKAY) { goto error; }
109 y += len;
110
111 /* reset size */
112 *outlen = y;
113
114 err = CRYPT_OK;
115 goto done;
116
117 error : err = mpi_to_ltc_error(err);
118 done : mp_clear_multi(&k, &kinv, &r, &s, &tmp, NULL);
119 #ifdef CLEAN_STACK
120 zeromem(buf, sizeof(buf));
121 #endif
122 return err;
123 }
124
125 #endif