Mercurial > dropbear
comparison libtomcrypt/src/pk/dsa/dsa_make_key.c @ 398:59c7938af2bd
merge of '1250b8af44b62d8f4fe0f8d9fc7e7a1cc34e7e1c'
and '7f8670ac3bb975f40967f3979d09d2199b7e90c8'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 03 Feb 2007 08:20:30 +0000 |
parents | 0cbe8f6dbf9e |
children | f849a5ca2efc |
comparison
equal
deleted
inserted
replaced
396:e7c1a77d2921 | 398:59c7938af2bd |
---|---|
4 * algorithms in a highly modular and flexible manner. | 4 * algorithms in a highly modular and flexible manner. |
5 * | 5 * |
6 * The library is free for all purposes without any express | 6 * The library is free for all purposes without any express |
7 * guarantee it works. | 7 * guarantee it works. |
8 * | 8 * |
9 * Tom St Denis, [email protected], http://libtomcrypt.org | 9 * Tom St Denis, [email protected], http://libtomcrypt.com |
10 */ | 10 */ |
11 #include "tomcrypt.h" | 11 #include "tomcrypt.h" |
12 | 12 |
13 /** | 13 /** |
14 @file dsa_make_key.c | 14 @file dsa_make_key.c |
26 @param key [out] Where to store the created key | 26 @param key [out] Where to store the created key |
27 @return CRYPT_OK if successful, upon error this function will free all allocated memory | 27 @return CRYPT_OK if successful, upon error this function will free all allocated memory |
28 */ | 28 */ |
29 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key) | 29 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key) |
30 { | 30 { |
31 mp_int tmp, tmp2; | 31 void *tmp, *tmp2; |
32 int err, res; | 32 int err, res; |
33 unsigned char *buf; | 33 unsigned char *buf; |
34 | 34 |
35 LTC_ARGCHK(key != NULL); | 35 LTC_ARGCHK(key != NULL); |
36 LTC_ARGCHK(ltc_mp.name != NULL); | |
36 | 37 |
37 /* check prng */ | 38 /* check prng */ |
38 if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | 39 if ((err = prng_is_valid(wprng)) != CRYPT_OK) { |
39 return err; | 40 return err; |
40 } | 41 } |
50 if (buf == NULL) { | 51 if (buf == NULL) { |
51 return CRYPT_MEM; | 52 return CRYPT_MEM; |
52 } | 53 } |
53 | 54 |
54 /* init mp_ints */ | 55 /* init mp_ints */ |
55 if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != MP_OKAY) { | 56 if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) { |
56 err = mpi_to_ltc_error(err); | 57 XFREE(buf); |
57 goto LBL_ERR; | 58 return err; |
58 } | 59 } |
59 | 60 |
60 /* make our prime q */ | 61 /* make our prime q */ |
61 if ((err = rand_prime(&key->q, group_size*8, prng, wprng)) != CRYPT_OK) { goto LBL_ERR; } | 62 if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK) { goto error; } |
62 | 63 |
63 /* double q */ | 64 /* double q */ |
64 if ((err = mp_mul_2(&key->q, &tmp)) != MP_OKAY) { goto error; } | 65 if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK) { goto error; } |
65 | 66 |
66 /* now make a random string and multply it against q */ | 67 /* now make a random string and multply it against q */ |
67 if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) { | 68 if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) { |
68 err = CRYPT_ERROR_READPRNG; | 69 err = CRYPT_ERROR_READPRNG; |
69 goto LBL_ERR; | 70 goto error; |
70 } | 71 } |
71 | 72 |
72 /* force magnitude */ | 73 /* force magnitude */ |
73 buf[0] |= 0xC0; | 74 buf[0] |= 0xC0; |
74 | 75 |
75 /* force even */ | 76 /* force even */ |
76 buf[modulus_size - group_size - 1] &= ~1; | 77 buf[modulus_size - group_size - 1] &= ~1; |
77 | 78 |
78 if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size)) != MP_OKAY) { goto error; } | 79 if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; } |
79 if ((err = mp_mul(&key->q, &tmp2, &key->p)) != MP_OKAY) { goto error; } | 80 if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK) { goto error; } |
80 if ((err = mp_add_d(&key->p, 1, &key->p)) != MP_OKAY) { goto error; } | 81 if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK) { goto error; } |
81 | 82 |
82 /* now loop until p is prime */ | 83 /* now loop until p is prime */ |
83 for (;;) { | 84 for (;;) { |
84 if ((err = is_prime(&key->p, &res)) != CRYPT_OK) { goto LBL_ERR; } | 85 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { goto error; } |
85 if (res == MP_YES) break; | 86 if (res == LTC_MP_YES) break; |
86 | 87 |
87 /* add 2q to p and 2 to tmp2 */ | 88 /* add 2q to p and 2 to tmp2 */ |
88 if ((err = mp_add(&tmp, &key->p, &key->p)) != MP_OKAY) { goto error; } | 89 if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK) { goto error; } |
89 if ((err = mp_add_d(&tmp2, 2, &tmp2)) != MP_OKAY) { goto error; } | 90 if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK) { goto error; } |
90 } | 91 } |
91 | 92 |
92 /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ | 93 /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ |
93 mp_set(&key->g, 1); | 94 mp_set(key->g, 1); |
94 | 95 |
95 do { | 96 do { |
96 if ((err = mp_add_d(&key->g, 1, &key->g)) != MP_OKAY) { goto error; } | 97 if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK) { goto error; } |
97 if ((err = mp_exptmod(&key->g, &tmp2, &key->p, &tmp)) != MP_OKAY) { goto error; } | 98 if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK) { goto error; } |
98 } while (mp_cmp_d(&tmp, 1) == MP_EQ); | 99 } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ); |
99 | 100 |
100 /* at this point tmp generates a group of order q mod p */ | 101 /* at this point tmp generates a group of order q mod p */ |
101 mp_exch(&tmp, &key->g); | 102 mp_exch(tmp, key->g); |
102 | 103 |
103 /* so now we have our DH structure, generator g, order q, modulus p | 104 /* so now we have our DH structure, generator g, order q, modulus p |
104 Now we need a random exponent [mod q] and it's power g^x mod p | 105 Now we need a random exponent [mod q] and it's power g^x mod p |
105 */ | 106 */ |
106 do { | 107 do { |
107 if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) { | 108 if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) { |
108 err = CRYPT_ERROR_READPRNG; | 109 err = CRYPT_ERROR_READPRNG; |
109 goto LBL_ERR; | 110 goto error; |
110 } | 111 } |
111 if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != MP_OKAY) { goto error; } | 112 if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK) { goto error; } |
112 } while (mp_cmp_d(&key->x, 1) != MP_GT); | 113 } while (mp_cmp_d(key->x, 1) != LTC_MP_GT); |
113 if ((err = mp_exptmod(&key->g, &key->x, &key->p, &key->y)) != MP_OKAY) { goto error; } | 114 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto error; } |
114 | 115 |
115 key->type = PK_PRIVATE; | 116 key->type = PK_PRIVATE; |
116 key->qord = group_size; | 117 key->qord = group_size; |
117 | |
118 /* shrink the ram required */ | |
119 if ((err = mp_shrink(&key->g)) != MP_OKAY) { goto error; } | |
120 if ((err = mp_shrink(&key->p)) != MP_OKAY) { goto error; } | |
121 if ((err = mp_shrink(&key->q)) != MP_OKAY) { goto error; } | |
122 if ((err = mp_shrink(&key->x)) != MP_OKAY) { goto error; } | |
123 if ((err = mp_shrink(&key->y)) != MP_OKAY) { goto error; } | |
124 | 118 |
125 #ifdef LTC_CLEAN_STACK | 119 #ifdef LTC_CLEAN_STACK |
126 zeromem(buf, MDSA_DELTA); | 120 zeromem(buf, MDSA_DELTA); |
127 #endif | 121 #endif |
128 | 122 |
129 err = CRYPT_OK; | 123 err = CRYPT_OK; |
130 goto done; | 124 goto done; |
131 error: | 125 error: |
132 err = mpi_to_ltc_error(err); | 126 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); |
133 LBL_ERR: | |
134 mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL); | |
135 done: | 127 done: |
136 mp_clear_multi(&tmp, &tmp2, NULL); | 128 mp_clear_multi(tmp, tmp2, NULL); |
137 | |
138 XFREE(buf); | 129 XFREE(buf); |
139 return err; | 130 return err; |
140 } | 131 } |
141 | 132 |
142 #endif | 133 #endif |
143 | 134 |
144 /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_make_key.c,v $ */ | 135 /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_make_key.c,v $ */ |
145 /* $Revision: 1.4 $ */ | 136 /* $Revision: 1.10 $ */ |
146 /* $Date: 2005/06/11 05:45:35 $ */ | 137 /* $Date: 2006/12/04 03:18:43 $ */ |