1313
1414namespace {
1515
16- // Generate a private key from just the secret parameter
17- int EC_KEY_regenerate_key (EC_KEY *eckey, BIGNUM *priv_key)
18- {
19- int ok = 0 ;
20- BN_CTX *ctx = NULL ;
21- EC_POINT *pub_key = NULL ;
22-
23- if (!eckey) return 0 ;
24-
25- const EC_GROUP *group = EC_KEY_get0_group (eckey);
26-
27- if ((ctx = BN_CTX_new ()) == NULL )
28- goto err;
29-
30- pub_key = EC_POINT_new (group);
31-
32- if (pub_key == NULL )
33- goto err;
34-
35- if (!EC_POINT_mul (group, pub_key, priv_key, NULL , NULL , ctx))
36- goto err;
37-
38- EC_KEY_set_private_key (eckey,priv_key);
39- EC_KEY_set_public_key (eckey,pub_key);
40-
41- ok = 1 ;
42-
43- err:
44-
45- if (pub_key)
46- EC_POINT_free (pub_key);
47- if (ctx != NULL )
48- BN_CTX_free (ctx);
49-
50- return (ok);
51- }
52-
5316// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
5417// recid selects which key is recovered
5518// if check is non-zero, additional checks are performed
@@ -135,48 +98,6 @@ CECKey::~CECKey() {
13598 EC_KEY_free (pkey);
13699}
137100
138- void CECKey::GetSecretBytes (unsigned char vch[32 ]) const {
139- const BIGNUM *bn = EC_KEY_get0_private_key (pkey);
140- assert (bn);
141- int nBytes = BN_num_bytes (bn);
142- int n=BN_bn2bin (bn,&vch[32 - nBytes]);
143- assert (n == nBytes);
144- memset (vch, 0 , 32 - nBytes);
145- }
146-
147- void CECKey::SetSecretBytes (const unsigned char vch[32 ]) {
148- bool ret;
149- BIGNUM bn;
150- BN_init (&bn);
151- ret = BN_bin2bn (vch, 32 , &bn) != NULL ;
152- assert (ret);
153- ret = EC_KEY_regenerate_key (pkey, &bn) != 0 ;
154- assert (ret);
155- BN_clear_free (&bn);
156- }
157-
158- int CECKey::GetPrivKeySize (bool fCompressed ) {
159- EC_KEY_set_conv_form (pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
160- return i2d_ECPrivateKey (pkey, NULL );
161- }
162- int CECKey::GetPrivKey (unsigned char * privkey, bool fCompressed ) {
163- EC_KEY_set_conv_form (pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
164- return i2d_ECPrivateKey (pkey, &privkey);
165- }
166-
167- bool CECKey::SetPrivKey (const unsigned char * privkey, size_t size, bool fSkipCheck ) {
168- if (d2i_ECPrivateKey (&pkey, &privkey, size)) {
169- if (fSkipCheck )
170- return true ;
171-
172- // d2i_ECPrivateKey returns true if parsing succeeds.
173- // This doesn't necessarily mean the key is valid.
174- if (EC_KEY_check_key (pkey))
175- return true ;
176- }
177- return false ;
178- }
179-
180101void CECKey::GetPubKey (std::vector<unsigned char > &pubkey, bool fCompressed ) {
181102 EC_KEY_set_conv_form (pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
182103 int nSize = i2o_ECPublicKey (pkey, NULL );
@@ -193,71 +114,13 @@ bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) {
193114 return o2i_ECPublicKey (&pkey, &pubkey, size) != NULL ;
194115}
195116
196- bool CECKey::Sign (const uint256 &hash, std::vector<unsigned char >& vchSig) {
197- vchSig.clear ();
198- ECDSA_SIG *sig = ECDSA_do_sign ((unsigned char *)&hash, sizeof (hash), pkey);
199- if (sig == NULL )
200- return false ;
201- BN_CTX *ctx = BN_CTX_new ();
202- BN_CTX_start (ctx);
203- const EC_GROUP *group = EC_KEY_get0_group (pkey);
204- BIGNUM *order = BN_CTX_get (ctx);
205- BIGNUM *halforder = BN_CTX_get (ctx);
206- EC_GROUP_get_order (group, order, ctx);
207- BN_rshift1 (halforder, order);
208- if (BN_cmp (sig->s , halforder) > 0 ) {
209- // enforce low S values, by negating the value (modulo the order) if above order/2.
210- BN_sub (sig->s , order, sig->s );
211- }
212- BN_CTX_end (ctx);
213- BN_CTX_free (ctx);
214- unsigned int nSize = ECDSA_size (pkey);
215- vchSig.resize (nSize); // Make sure it is big enough
216- unsigned char *pos = &vchSig[0 ];
217- nSize = i2d_ECDSA_SIG (sig, &pos);
218- ECDSA_SIG_free (sig);
219- vchSig.resize (nSize); // Shrink to fit actual size
220- return true ;
221- }
222-
223117bool CECKey::Verify (const uint256 &hash, const std::vector<unsigned char >& vchSig) {
224118 // -1 = error, 0 = bad sig, 1 = good
225119 if (ECDSA_verify (0 , (unsigned char *)&hash, sizeof (hash), &vchSig[0 ], vchSig.size (), pkey) != 1 )
226120 return false ;
227121 return true ;
228122}
229123
230- bool CECKey::SignCompact (const uint256 &hash, unsigned char *p64, int &rec) {
231- bool fOk = false ;
232- ECDSA_SIG *sig = ECDSA_do_sign ((unsigned char *)&hash, sizeof (hash), pkey);
233- if (sig==NULL )
234- return false ;
235- memset (p64, 0 , 64 );
236- int nBitsR = BN_num_bits (sig->r );
237- int nBitsS = BN_num_bits (sig->s );
238- if (nBitsR <= 256 && nBitsS <= 256 ) {
239- std::vector<unsigned char > pubkey;
240- GetPubKey (pubkey, true );
241- for (int i=0 ; i<4 ; i++) {
242- CECKey keyRec;
243- if (ECDSA_SIG_recover_key_GFp (keyRec.pkey , sig, (unsigned char *)&hash, sizeof (hash), i, 1 ) == 1 ) {
244- std::vector<unsigned char > pubkeyRec;
245- keyRec.GetPubKey (pubkeyRec, true );
246- if (pubkeyRec == pubkey) {
247- rec = i;
248- fOk = true ;
249- break ;
250- }
251- }
252- }
253- assert (fOk );
254- BN_bn2bin (sig->r ,&p64[32 -(nBitsR+7 )/8 ]);
255- BN_bn2bin (sig->s ,&p64[64 -(nBitsS+7 )/8 ]);
256- }
257- ECDSA_SIG_free (sig);
258- return fOk ;
259- }
260-
261124bool CECKey::Recover (const uint256 &hash, const unsigned char *p64, int rec)
262125{
263126 if (rec<0 || rec>=3 )
@@ -270,33 +133,6 @@ bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec)
270133 return ret;
271134}
272135
273- bool CECKey::TweakSecret (unsigned char vchSecretOut[32 ], const unsigned char vchSecretIn[32 ], const unsigned char vchTweak[32 ])
274- {
275- bool ret = true ;
276- BN_CTX *ctx = BN_CTX_new ();
277- BN_CTX_start (ctx);
278- BIGNUM *bnSecret = BN_CTX_get (ctx);
279- BIGNUM *bnTweak = BN_CTX_get (ctx);
280- BIGNUM *bnOrder = BN_CTX_get (ctx);
281- EC_GROUP *group = EC_GROUP_new_by_curve_name (NID_secp256k1);
282- EC_GROUP_get_order (group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order...
283- BN_bin2bn (vchTweak, 32 , bnTweak);
284- if (BN_cmp (bnTweak, bnOrder) >= 0 )
285- ret = false ; // extremely unlikely
286- BN_bin2bn (vchSecretIn, 32 , bnSecret);
287- BN_add (bnSecret, bnSecret, bnTweak);
288- BN_nnmod (bnSecret, bnSecret, bnOrder, ctx);
289- if (BN_is_zero (bnSecret))
290- ret = false ; // ridiculously unlikely
291- int nBits = BN_num_bits (bnSecret);
292- memset (vchSecretOut, 0 , 32 );
293- BN_bn2bin (bnSecret, &vchSecretOut[32 -(nBits+7 )/8 ]);
294- EC_GROUP_free (group);
295- BN_CTX_end (ctx);
296- BN_CTX_free (ctx);
297- return ret;
298- }
299-
300136bool CECKey::TweakPublic (const unsigned char vchTweak[32 ]) {
301137 bool ret = true ;
302138 BN_CTX *ctx = BN_CTX_new ();
0 commit comments