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
- */
1
+ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2
+ /* SPDX-License-Identifier: Unlicense */
9
3
10
4
#include "tomcrypt_private.h"
11
5
25
19
@param key [out] Newly created deterministic key
26
20
@return CRYPT_OK if successful, upon error all allocated memory will be freed
27
21
*/
28
- int ecc_rfc6979_key (const ecc_key * priv , const unsigned char * in , int inlen , ecc_key * key )
22
+ int ecc_rfc6979_key (const ecc_key * priv , const unsigned char * in , unsigned long inlen , ecc_key * key )
29
23
{
30
- int err , hash , i ;
31
- unsigned char v [32 ], k [32 ], digest [32 ]; /* No way to determine hash so always use SHA256 */
32
- unsigned char buffer [256 ];
33
- unsigned long outlen , buflen , qlen ;
24
+ int err , hash = -1 ;
25
+ unsigned char v [MAXBLOCKSIZE ], k [MAXBLOCKSIZE ];
26
+ unsigned char buffer [256 ], sep [1 ], privkey [128 ];
27
+ unsigned long order_bits , len_diff , pk_len , zero_extend , outlen , klen , vlen , buflen , qlen , hashsize ;
28
+ void * r , * d ;
34
29
35
30
LTC_ARGCHK (ltc_mp .name != NULL );
31
+ LTC_ARGCHK (priv != NULL );
36
32
LTC_ARGCHK (key != NULL );
37
33
LTC_ARGCHK (key -> dp .size > 0 );
38
34
39
- hash = find_hash ("sha256" );
40
- if (hash == -1 ) {err = CRYPT_ERROR ; goto error ;}
35
+ if (priv -> rfc6979_hash_alg == NULL ) {
36
+ return CRYPT_INVALID_ARG ;
37
+ }
38
+ hash = find_hash (priv -> rfc6979_hash_alg );
39
+ if ((err = hash_is_valid (hash )) != CRYPT_OK ) {
40
+ return err ;
41
+ }
42
+
43
+ hashsize = hash_descriptor [hash ].hashsize ;
44
+
45
+ if ((err = ltc_mp_init_multi (& r , & d , NULL )) != CRYPT_OK ) {
46
+ return err ;
47
+ }
41
48
42
49
/* Length, in bytes, of key */
43
- i = mp_count_bits (key -> dp .order );
44
- qlen = (i + 7 ) >> 3 ;
50
+ order_bits = ltc_mp_count_bits (key -> dp .order );
51
+ qlen = (order_bits + 7 ) >> 3 ;
52
+ len_diff = qlen > inlen ? qlen - inlen : 0 ;
53
+ pk_len = (ltc_mp_count_bits (priv -> k )+ 7 ) >> 3 ;
54
+ zero_extend = qlen - pk_len ;
55
+ XMEMSET (buffer , 0x00 , len_diff + zero_extend );
45
56
46
57
/* RFC6979 3.2b, set V */
47
- for ( i = 0 ; i < 32 ; i ++ ) v [ i ] = 0x01 ;
58
+ XMEMSET ( v , 0x01 , hashsize ) ;
48
59
49
60
/* RFC6979 3.2c, set K */
50
- for ( i = 0 ; i < 32 ; i ++ ) k [ i ] = 0x00 ;
61
+ XMEMSET ( k , 0x00 , hashsize ) ;
51
62
63
+ if ((err = ltc_mp_to_unsigned_bin (priv -> k , privkey ) != CRYPT_OK )) { goto error ; }
52
64
/* RFC6979 3.2d, set K to HMAC_K(V::0x00::priv::in) */
53
- XMEMCPY (& buffer [0 ], v , 32 );
54
- buffer [32 ] = 0x00 ;
55
- if ((err = mp_to_unsigned_bin (priv -> k , & buffer [33 ]) != CRYPT_OK )) { goto error ; }
56
- XMEMCPY (& buffer [33 + qlen ], in , inlen );
57
- buflen = 32 + 1 + qlen + inlen ;
58
- outlen = sizeof (digest );
59
- if ((err = hmac_memory (hash , k , 32 , buffer , buflen , digest , & outlen )) != CRYPT_OK ) { goto error ; }
60
- XMEMCPY (k , digest , 32 );
65
+ sep [0 ] = 0 ;
66
+ klen = sizeof (k );
67
+ if ((err = hmac_memory_multi (hash ,
68
+ k , hashsize ,
69
+ k , & klen ,
70
+ v , hashsize ,
71
+ sep , 1 ,
72
+ buffer , zero_extend ,
73
+ privkey , qlen - zero_extend ,
74
+ buffer , len_diff ,
75
+ in , qlen - len_diff ,
76
+ LTC_NULL )) != CRYPT_OK ) { goto error ; }
61
77
62
78
/* RFC6979 3.2e, set V = HMAC_K(V) */
63
- outlen = sizeof (digest );
64
- if ((err = hmac_memory (hash , k , 32 , v , 32 , digest , & outlen )) != CRYPT_OK ) { goto error ; }
65
- XMEMCPY (v , digest , 32 );
79
+ vlen = sizeof (v );
80
+ if ((err = hmac_memory (hash , k , klen , v , hashsize , v , & vlen )) != CRYPT_OK ) { goto error ; }
66
81
67
82
/* RFC6979 3.2f, set K to HMAC_K(V::0x01::priv::in) */
68
- XMEMCPY (& buffer [0 ], v , 32 );
69
- buffer [32 ] = 0x01 ;
70
- if ((err = mp_to_unsigned_bin (priv -> k , & buffer [33 ]) != CRYPT_OK )) { goto error ; }
71
- XMEMCPY (& buffer [33 + qlen ], in , inlen );
72
- buflen = 32 + 1 + qlen + inlen ;
73
- outlen = sizeof (digest );
74
- if ((err = hmac_memory (hash , k , 32 , buffer , buflen , digest , & outlen )) != CRYPT_OK ) { goto error ; }
75
- XMEMCPY (k , digest , 32 );
83
+ sep [0 ] = 0x01 ;
84
+ outlen = sizeof (k );
85
+ if ((err = hmac_memory_multi (hash ,
86
+ k , klen ,
87
+ k , & klen ,
88
+ v , hashsize ,
89
+ sep , 1 ,
90
+ buffer , zero_extend ,
91
+ privkey , qlen - zero_extend ,
92
+ buffer , len_diff ,
93
+ in , qlen - len_diff ,
94
+ LTC_NULL )) != CRYPT_OK ) { goto error ; }
76
95
77
96
/* RFC6979 3.2g, set V = HMAC_K(V) */
78
- outlen = sizeof (digest );
79
- if ((err = hmac_memory (hash , k , 32 , v , 32 , digest , & outlen )) != CRYPT_OK ) { goto error ; }
80
- XMEMCPY (v , digest , 32 );
97
+ outlen = sizeof (v );
98
+ if ((err = hmac_memory (hash , k , klen , v , hashsize , v , & outlen )) != CRYPT_OK ) { goto error ; }
81
99
82
100
/* RFC6979 3.2h, generate and check key */
83
101
do {
84
102
/* concatenate hash bits into T */
85
103
buflen = 0 ;
86
104
while (buflen < qlen ) {
87
- outlen = sizeof (digest );
88
- if ((err = hmac_memory (hash , k , 32 , v , 32 , digest , & outlen )) != CRYPT_OK ) { goto error ; }
89
- XMEMCPY (v , digest , 32 );
90
- XMEMCPY (& buffer [buflen ], v , 32 );
91
- buflen += 32 ;
105
+ outlen = sizeof (v );
106
+ if ((err = hmac_memory (hash , k , klen , v , hashsize , v , & outlen )) != CRYPT_OK ) { goto error ; }
107
+ XMEMCPY (& buffer [buflen ], v , hashsize );
108
+ buflen += hashsize ;
92
109
}
93
110
94
111
/* key->k = bits2int(T) */
95
- if ((err = mp_read_unsigned_bin (key -> k , (unsigned char * )buffer , qlen )) != CRYPT_OK ) { goto error ; }
96
-
97
- /* make the public key */
98
- if ((err = ltc_mp .ecc_ptmul (key -> k , & key -> dp .base , & key -> pubkey , key -> dp .A , key -> dp .prime , 1 )) != CRYPT_OK ) {
99
- goto error ;
112
+ if ((err = ltc_mp_read_unsigned_bin (r , buffer , qlen )) != CRYPT_OK ) { goto error ; }
113
+ if ((qlen * 8 ) > order_bits ) {
114
+ if ((err = ltc_mp_2expt (d , (qlen * 8 ) - order_bits )) != CRYPT_OK ) { goto error ; }
115
+ if ((err = ltc_mp_div (r , d , r , NULL )) != CRYPT_OK ) { goto error ; }
116
+ if ((err = ltc_mp_to_unsigned_bin (r , buffer )) != CRYPT_OK ) { goto error ; }
117
+ qlen = ltc_mp_unsigned_bin_size (r );
100
118
}
101
119
120
+ if ((err = ecc_set_key (buffer , qlen , PK_PRIVATE , key ))!= CRYPT_OK ) { goto error ; }
121
+
102
122
/* check that k is in range [1,q-1] */
103
- if (mp_cmp_d (key -> k , 0 ) == LTC_MP_GT && mp_cmp (key -> k , key -> dp .order ) == LTC_MP_LT ) {
104
- /* TODO: Check that pubkey.x != 0 (mod p) */
123
+ if (ltc_mp_cmp_d (key -> k , 0 ) == LTC_MP_GT && ltc_mp_cmp (key -> k , key -> dp .order ) == LTC_MP_LT ) {
124
+ /* Check that pubkey.x != 0 (mod p) */
125
+ if ((err = ltc_mp_mod (key -> pubkey .x , key -> dp .order , r )) != CRYPT_OK ) { goto error ; }
105
126
106
127
/* if we have a valid key, exit loop */
107
- break ;
128
+ if (ltc_mp_iszero (r ) == LTC_MP_NO )
129
+ break ;
108
130
} else {
131
+ if (hashsize == sizeof (buffer )) {
132
+ err = CRYPT_BUFFER_OVERFLOW ;
133
+ goto error ;
134
+ }
109
135
/* K = HMAC_K(V::0x00) */
110
- XMEMCPY (& buffer [0 ], v , 32 );
111
- buffer [32 ] = 0x00 ;
112
- buflen = 32 + 1 ;
113
- outlen = sizeof (digest );
114
- if ((err = hmac_memory (hash , k , 32 , buffer , buflen , digest , & outlen )) != CRYPT_OK ) { goto error ; }
115
- XMEMCPY (k , digest , 32 );
136
+ buffer [0 ] = 0x0 ;
137
+ outlen = sizeof (k );
138
+ if ((err = hmac_memory_multi (hash , k , klen , k , & klen , v , hashsize , buffer , 1 , LTC_NULL )) != CRYPT_OK ) { goto error ; }
116
139
117
140
/* V = HMAC_K(V) */
118
- outlen = sizeof (digest );
119
- if ((err = hmac_memory (hash , k , 32 , v , 32 , digest , & outlen )) != CRYPT_OK ) { goto error ; }
120
- XMEMCPY (v , digest , 32 );
141
+ outlen = sizeof (v );
142
+ if ((err = hmac_memory (hash , k , klen , v , hashsize , v , & outlen )) != CRYPT_OK ) { goto error ; }
121
143
122
144
/* ... and try again! */
123
145
}
@@ -132,12 +154,9 @@ int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, int inlen, ecc
132
154
error :
133
155
ecc_free (key );
134
156
cleanup :
157
+ ltc_mp_cleanup_multi (& d , & r , NULL );
135
158
return err ;
136
159
}
137
160
138
161
#endif
139
162
#endif
140
- /* ref: $Format:%D$ */
141
- /* git commit: $Format:%H$ */
142
- /* commit time: $Format:%ai$ */
143
-
0 commit comments