/** * Writes a sha256 hash. */ void write_sha256(const sha256 & value) { write_bytes( reinterpret_cast<const char *>(value.digest()), value.digest_length ); }
bool key::set_compact_signature( const sha256 & h, const std::vector<std::uint8_t> & signature ) { if (signature.size() != 65) { return false; } int v = signature[0]; if (v < 27 || v >= 35) { return false; } ECDSA_SIG * sig = ECDSA_SIG_new(); BN_bin2bn(&signature[1], 32, sig->r); BN_bin2bn(&signature[33], 32, sig->s); EC_KEY_free(m_EC_KEY); m_EC_KEY = EC_KEY_new_by_curve_name(NID_secp256k1); if (v >= 31) { set_compressed_public_key(); v -= 4; } if ( ECDSA_SIG_recover_key_GFp(m_EC_KEY, sig, h.digest(), sha256::digest_length, v - 27, 0) == 1 ) { m_set = true; ECDSA_SIG_free(sig); return true; } return false; }
bool db_tx::read_sha256(const std::string & key, sha256 & value) { if (m_Db == 0) { return false; } /** * Read the next record. */ data_buffer key_data; key_data.write_var_int(key.size()); key_data.write((void *)key.c_str(), key.size()); Dbt dat_key( (void *)key_data.data(), static_cast<std::uint32_t> (key_data.size()) ); Dbt dat_value; dat_value.set_flags(DB_DBT_MALLOC); int ret = m_Db->get(m_DbTxn, &dat_key, &dat_value, 0); std::memset(dat_key.get_data(), 0, dat_key.get_size()); if (dat_value.get_data() == 0) { return false; } std::memcpy( (void *)value.digest(), dat_value.get_data(), dat_value.get_size() ); std::memset(dat_value.get_data(), 0, dat_value.get_size()); free(dat_value.get_data()); return ret == 0; }
bool key::sign(const sha256 & h, std::vector<std::uint8_t> & signature) { unsigned int size = ECDSA_size(m_EC_KEY); signature.resize(size); if ( !ECDSA_sign(0, h.digest(), sha256::digest_length, &signature[0], &size, m_EC_KEY) ) { signature.clear(); return false; } signature.resize(size); return true; }
bool crypter::encrypt_secret( types::keying_material_t & master_key, const key::secret_t & plain_text, const sha256 & iv, std::vector<std::uint8_t> & cipher_text ) { crypter crypter_key; std::vector<std::uint8_t> new_iv(wallet_key_size); std::memcpy(&new_iv[0], iv.digest(), wallet_key_size); if (crypter_key.set_key(master_key, new_iv) == false) { return false; } return crypter_key.encrypt((types::keying_material_t)plain_text, cipher_text) ; }
bool key::verify( const sha256 & h, const std::vector<std::uint8_t> & signature ) { bool ret = false; if (signature.size() > 0) { auto ptr_signature = &signature[0]; ECDSA_SIG * ecdsa_sig = 0; if ( (ecdsa_sig = d2i_ECDSA_SIG( 0, &ptr_signature, signature.size())) != 0 ) { std::uint8_t * pp = 0; auto len = i2d_ECDSA_SIG(ecdsa_sig, &pp); ECDSA_SIG_free(ecdsa_sig), ecdsa_sig = 0; if (pp && len > 0) { ret = ECDSA_verify( 0, h.digest(), sha256::digest_length, pp, len, m_EC_KEY ) == 1; OPENSSL_free(pp), pp = 0; } } } return ret; }
bool key::sign_compact( const sha256 & h, std::vector<std::uint8_t> & signature ) { bool ret = false; ECDSA_SIG * sig = ECDSA_do_sign( h.digest(), sha256::digest_length, m_EC_KEY ); if (sig == 0) { return false; } signature.clear(); signature.resize(65, 0); int nBitsR = BN_num_bits(sig->r); int nBitsS = BN_num_bits(sig->s); if (nBitsR <= 256 && nBitsS <= 256) { int nRecId = -1; for (auto i = 0; i < 4; i++) { key keyRec; keyRec.m_set = true; if (m_compressed) { keyRec.set_compressed_public_key(); } if ( ECDSA_SIG_recover_key_GFp(keyRec.m_EC_KEY, sig, h.digest(), sha256::digest_length, i, 1) == 1 ) { if (keyRec.get_public_key() == get_public_key()) { nRecId = i; break; } } } if (nRecId == -1) { throw std::runtime_error("unable to construct recoverable key"); } signature[0] = nRecId + 27 + (m_compressed ? 4 : 0); BN_bn2bin(sig->r, &signature[33 - (nBitsR + 7) / 8]); BN_bn2bin(sig->s, &signature[65 - (nBitsS + 7) / 8]); ret = true; } ECDSA_SIG_free(sig); return ret; }