ECIES
| 444 | |
| 445 | // ECIES |
| 446 | void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted) |
| 447 | { |
| 448 | BN_CTX * ctx = BN_CTX_new (); |
| 449 | BN_CTX_start (ctx); |
| 450 | BIGNUM * q = BN_CTX_get (ctx); |
| 451 | EC_GROUP_get_order(curve, q, ctx); |
| 452 | int len = BN_num_bytes (q); |
| 453 | BIGNUM * k = BN_CTX_get (ctx); |
| 454 | BN_rand_range (k, q); // 0 < k < q |
| 455 | // point for shared secret |
| 456 | auto p = EC_POINT_new (curve); |
| 457 | EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx); |
| 458 | BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); |
| 459 | EC_POINT_get_affine_coordinates (curve, p, x, y, nullptr); |
| 460 | encrypted[0] = 0; |
| 461 | bn2buf (x, encrypted + 1, len); |
| 462 | bn2buf (y, encrypted + 1 + len, len); |
| 463 | RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len); |
| 464 | // encryption key and iv |
| 465 | EC_POINT_mul (curve, p, nullptr, key, k, ctx); |
| 466 | EC_POINT_get_affine_coordinates (curve, p, x, y, nullptr); |
| 467 | uint8_t keyBuf[64], iv[64], shared[32]; |
| 468 | bn2buf (x, keyBuf, len); |
| 469 | bn2buf (y, iv, len); |
| 470 | SHA256 (keyBuf, len, shared); |
| 471 | // create buffer |
| 472 | uint8_t m[256]; |
| 473 | m[0] = 0xFF; m[255] = 0xFF; |
| 474 | memcpy (m+33, data, 222); |
| 475 | SHA256 (m+33, 222, m+1); |
| 476 | // encrypt |
| 477 | CBCEncryption encryption; |
| 478 | encryption.SetKey (shared); |
| 479 | encrypted[257] = 0; |
| 480 | encryption.Encrypt (m, 256, iv, encrypted + 258); |
| 481 | EC_POINT_free (p); |
| 482 | BN_CTX_end (ctx); |
| 483 | BN_CTX_free (ctx); |
| 484 | } |
| 485 | |
| 486 | bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data) |
| 487 | { |