diff --git a/crypto.cpp b/crypto.cpp index 588fb4d6b..646202168 100644 --- a/crypto.cpp +++ b/crypto.cpp @@ -323,9 +323,13 @@ BOOST_AUTO_TEST_CASE(handshakeNew) Secret nodeAsecret(sha3("privacy")); KeyPair nodeA(nodeAsecret); + BOOST_REQUIRE(nodeA.pub()); Secret nodeBsecret(sha3("privacy++")); KeyPair nodeB(nodeBsecret); + BOOST_REQUIRE(nodeA.pub()); + + BOOST_REQUIRE_NE(nodeA.sec(), nodeB.sec()); // Initiator is Alice (nodeA) ECDHE eA; @@ -348,7 +352,6 @@ BOOST_AUTO_TEST_CASE(handshakeNew) } bytes authcipher; encrypt(nodeB.pub(), &auth, authcipher); - cnote << "initAuth:" << toHex(authcipher); ECDHE eB; bytes nBbytes(fromHex("0xBBBB")); @@ -364,45 +367,89 @@ BOOST_AUTO_TEST_CASE(handshakeNew) } bytes ackcipher; encrypt(nodeA.pub(), &ack, ackcipher); - cnote << "ackAuth:" << toHex(ackcipher); + + BOOST_REQUIRE(eA.pubkey()); + BOOST_REQUIRE(eB.pubkey()); + BOOST_REQUIRE_NE(eA.seckey(), eB.seckey()); /// Alice - // TODO: decrypt ackcipher and check decrypted pubk is eb Secret aEncryptK; Secret aMacK; Secret aEgressMac; Secret aIngressMac; { - bytes keyMaterial(512); + // TODO: decrypt ackcipher and check decrypted material + // TODO: export ess and require equal to b + + bytes keyMaterialBytes(512); + bytesConstRef keyMaterial(&keyMaterialBytes); h256 ess; // todo: ecdh-agree should be able to output bytes s_secp256k1.agree(eA.seckey(), eB.pubkey(), ess); - ess.ref().copyTo(bytesConstRef(&keyMaterial).cropped(0, h256::size)); - ssA.ref().copyTo(bytesConstRef(&keyMaterial).cropped(h256::size, h256::size)); + ess.ref().copyTo(keyMaterial.cropped(0, h256::size)); + ssA.ref().copyTo(keyMaterial.cropped(h256::size, h256::size)); // auto token = sha3(ssA); aEncryptK = sha3(keyMaterial); - aEncryptK.ref().copyTo(bytesConstRef(&keyMaterial).cropped(h256::size, h256::size)); + aEncryptK.ref().copyTo(keyMaterial.cropped(h256::size, h256::size)); aMacK = sha3(keyMaterial); - // todo: resize key-material and copy ciphertext + // todo: replace nonceB with decrypted nonceB + keyMaterialBytes.resize(h256::size + authcipher.size()); + keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); + (aMacK ^ nonceB).ref().copyTo(keyMaterial); + bytesConstRef(&authcipher).copyTo(keyMaterial.cropped(h256::size, authcipher.size())); aEgressMac = sha3(keyMaterial); + + keyMaterialBytes.resize(h256::size + ackcipher.size()); + keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); + (aMacK ^ nonceA).ref().copyTo(keyMaterial); + bytesConstRef(&ackcipher).copyTo(keyMaterial.cropped(h256::size, ackcipher.size())); aIngressMac = sha3(keyMaterial); } -// ecdhe-shared-secret = ecdh.agree(ecdhe-random, remote-ecdhe-random-pubk) -// shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || initiator-nonce)) -// token = sha3(shared-secret) -// aes-secret = sha3(ecdhe-shared-secret || shared-secret) -//# destroy shared-secret -// mac-secret = sha3(ecdhe-shared-secret || aes-secret) -//# destroy ecdhe-shared-secret -// egress-mac = sha3(mac-secret^nonce || auth) -//# destroy nonce -// ingress-mac = sha3(mac-secret^initiator-nonce || auth) -//# destroy remote-nonce + /// Bob + Secret ssB; + s_secp256k1.agree(nodeB.sec(), nodeA.pub(), ssB); + BOOST_REQUIRE_EQUAL(ssA, ssB); + Secret bEncryptK; + Secret bMacK; + Secret bEgressMac; + Secret bIngressMac; + { + bytes keyMaterialBytes(512); + bytesConstRef keyMaterial(&keyMaterialBytes); + + h256 ess; + // todo: ecdh-agree should be able to output bytes + s_secp256k1.agree(eB.seckey(), eA.pubkey(), ess); + ess.ref().copyTo(keyMaterial.cropped(0, h256::size)); + ssB.ref().copyTo(keyMaterial.cropped(h256::size, h256::size)); +// auto token = sha3(ssA); + bEncryptK = sha3(keyMaterial); + bEncryptK.ref().copyTo(keyMaterial.cropped(h256::size, h256::size)); + bMacK = sha3(keyMaterial); + + // todo: replace nonceB with decrypted nonceB + keyMaterialBytes.resize(h256::size + ackcipher.size()); + keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); + (bMacK ^ nonceA).ref().copyTo(keyMaterial); + bytesConstRef(&ackcipher).copyTo(keyMaterial.cropped(h256::size, ackcipher.size())); + bEgressMac = sha3(keyMaterial); + + keyMaterialBytes.resize(h256::size + authcipher.size()); + keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); + (bMacK ^ nonceB).ref().copyTo(keyMaterial); + bytesConstRef(&authcipher).copyTo(keyMaterial.cropped(h256::size, authcipher.size())); + bIngressMac = sha3(keyMaterial); + } + + BOOST_REQUIRE_EQUAL(aEncryptK, bEncryptK); + BOOST_REQUIRE_EQUAL(aMacK, bMacK); + BOOST_REQUIRE_EQUAL(aEgressMac, bIngressMac); + BOOST_REQUIRE_EQUAL(bEgressMac, aIngressMac); } BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac)