void test_hashing_errors() { bool caught_exception = false; SHA512 test; test << "hello"; string hash; try { hash = test.gethash(); } catch(std::runtime_error e) { caught_exception = true; } assert(caught_exception); test.close(); caught_exception = false; try { test << "more"; } catch(std::runtime_error e) { caught_exception = true; } assert(caught_exception); }
int sha512_test() { SHA512 sha; byte hash[SHA512::DIGEST_SIZE]; testVector test_sha[] = { testVector("abc", "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41" "\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55" "\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3" "\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f" "\xa5\x4c\xa4\x9f"), testVector("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14" "\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88" "\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4" "\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b" "\x87\x4b\xe9\x09") }; int times( sizeof(test_sha) / sizeof(testVector) ); for (int i = 0; i < times; ++i) { sha.Update(test_sha[i].input_, test_sha[i].inLen_); sha.Final(hash); if (memcmp(hash, test_sha[i].output_, SHA512::DIGEST_SIZE) != 0) return -1 - i; } return 0; }
void TestApp::test_hash(const SHA512 &sha512, const char *hash_text) { std::string hash = sha512.get_hash(true); if (hash != hash_text) fail(); if (strlen(hash_text) != 128) fail(); unsigned char out_hash[64]; sha512.get_hash(out_hash); for (int cnt=0; cnt<64; cnt++) { unsigned int value = out_hash[cnt]; char nibble_high = *(hash_text++); char nibble_low = *(hash_text++); nibble_high >= 'A' ? (nibble_high = nibble_high - 'A' + 10) : nibble_high = nibble_high - '0'; nibble_low >= 'A' ? (nibble_low = nibble_low - 'A' + 10) : nibble_low = nibble_low - '0'; if (value != ((nibble_high << 4) | (nibble_low) )) fail(); } }
void provider::hash(const std::string& src, std::string& dst, size_t input_shift) { SHA512 hasher; char result[hash_size]; memset(result, 0, sizeof(result)); hasher.CalculateDigest(reinterpret_cast<byte*>(result), reinterpret_cast<const byte*>(src.data()), src.size() - input_shift); dst.append(result, hash_size); }
Blob DeepScanner::getFileSHA(Error& error, FileInputStream& fis) { const int iBufSize = 4096; SHA512 sha; Buffer buf(iBufSize); while (true) { int iBytesRead = fis.read(error, buf.ptr(), iBufSize); if (error) return Blob(); sha.write(buf.ptr(), iBytesRead); if (iBytesRead < iBufSize) return sha.finish(); } }
/** * \brief Verifies a signature using a specific Ed25519 public key. * * \param signature The signature value to be verified. * \param publicKey The public key to use to verify the signature. * \param message The message whose signature is to be verified. * \param len The length of the \a message to be verified. * * \return Returns true if the \a signature is valid for \a message; * or false if the \a signature is not valid. * * \sa sign() */ bool Ed25519::verify(const uint8_t signature[64], const uint8_t publicKey[32], const void *message, size_t len) { SHA512 hash; Point A; Point R; Point sB; Point kA; uint8_t *k = (uint8_t *)(hash.state.w); // Reuse hash buffer to save memory. bool result = false; // Decode the public key and the R component of the signature. if (decodePoint(A, publicKey) && decodePoint(R, signature)) { // Reconstruct the k value from the signing step. hash.reset(); hash.update(signature, 32); hash.update(publicKey, 32); hash.update(message, len); hash.finalize(k, 0); // Calculate s * B. The s value is stored temporarily in kA.t. BigNumberUtil::unpackLE(kA.t, NUM_LIMBS_256BIT, signature + 32, 32); mul(sB, kA.t, false); // Calculate R + k * A. We don't need sB.t in equal() below, // so we reuse that as a temporary buffer when reducing k. reduceQFromBuffer(sB.t, k, kA.x); mul(kA, sB.t, A, false); add(R, kA); // Compare s * B and R + k * A for equality. result = equal(sB, R); } // Clean up and exit. clean(A); clean(R); clean(sB); clean(kA); return result; }
void test_hashing_comparisons() { SHA512 valid; valid.write("monk"); valid.close(); assert(valid == "83d558db35b474e2e930f6866583bb166fd497dc310d044edcffd8e2e656fce8f2f2564fafc202635e08a9504348fc4932e2e0d65de2c536922096eb82302032"); assert(valid == reference_hash("monk")); SHA512 helper; helper.write("monk"); helper.close(); assert(valid == helper); SHA512 invalid; invalid.write("m0nk"); invalid.close(); assert(invalid != "83d558db35b474e2e930f6866583bb166fd497dc310d044edcffd8e2e656fce8f2f2564fafc202635e08a9504348fc4932e2e0d65de2c536922096eb82302032"); assert(invalid != reference_hash("monk")); assert(invalid != helper); }
/** * \brief Signs a message using a specific Ed25519 private key. * * \param signature The signature value. * \param privateKey The private key to use to sign the message. * \param publicKey The public key corresponding to \a privateKey. * \param message Points to the message to be signed. * \param len The length of the \a message to be signed. * * \sa verify(), derivePublicKey() */ void Ed25519::sign(uint8_t signature[64], const uint8_t privateKey[32], const uint8_t publicKey[32], const void *message, size_t len) { SHA512 hash; uint8_t *buf = (uint8_t *)(hash.state.w); // Reuse hash buffer to save memory. limb_t a[NUM_LIMBS_256BIT]; limb_t r[NUM_LIMBS_256BIT]; limb_t k[NUM_LIMBS_256BIT]; limb_t t[NUM_LIMBS_512BIT + 1]; Point rB; // Derive the secret scalar a and the message prefix from the private key. deriveKeys(&hash, a, privateKey); // Hash the prefix and the message to derive r. hash.reset(); hash.update(buf + 32, 32); hash.update(message, len); hash.finalize(buf, 0); reduceQFromBuffer(r, buf, t); // Encode rB into the first half of the signature buffer as R. mul(rB, r); encodePoint(signature, rB); // Hash R, A, and the message to get k. hash.reset(); hash.update(signature, 32); // R hash.update(publicKey, 32); // A hash.update(message, len); hash.finalize(buf, 0); reduceQFromBuffer(k, buf, t); // Compute s = (r + k * a) mod q. Curve25519::mulNoReduce(t, k, a); t[NUM_LIMBS_512BIT] = 0; reduceQ(t, t); BigNumberUtil::add(t, t, r, NUM_LIMBS_256BIT); BigNumberUtil::reduceQuick_P(t, t, numQ, NUM_LIMBS_256BIT); BigNumberUtil::packLE(signature + 32, 32, t, NUM_LIMBS_256BIT); // Clean up. clean(a); clean(r); clean(k); clean(t); clean(rB); }
void test_basic_hashing() { SHA512 hasher; hasher.write("vossibaer"); hasher.close(); assert(hasher.gethash() == reference_hash("vossibaer")); SHA512 tigger; tigger.write("honey"); tigger.close(); assert(tigger.gethash() == reference_hash("honey")); SHA512 leo; leo.write("lifestyle"); leo.close(); const unsigned char should[64] = { 0xc0, 0x25, 0xb1, 0x2c, 0x03, 0xa6, 0xea, 0x2d, 0xe6, 0x76, 0x00, 0xf5, 0x79, 0x25, 0xb0, 0x60, 0xdd, 0x70, 0xa5, 0xbd, 0x02, 0xb1, 0x4f, 0x39, 0x7f, 0x4e, 0x69, 0x95, 0xec, 0xaa, 0xd4, 0x4c, 0xfc, 0x66, 0xaf, 0xc8, 0xea, 0xcd, 0x61, 0x55, 0x1f, 0x00, 0x93, 0x7c, 0x03, 0x31, 0x83, 0xff, 0x30, 0xa8, 0xb3, 0xe5, 0xbd, 0x45, 0xaf, 0x2c, 0x1b, 0x56, 0xbd, 0xf0, 0x44, 0xf1, 0x58, 0x95, }; unsigned char current[64]; leo.gethash(current); for(int i = 0; i < 64; ++i) { assert(should[i] == current[i]); } }