mirror of https://github.com/PurpleI2P/i2pd.git
orignal
5 years ago
committed by
GitHub
37 changed files with 844 additions and 160 deletions
@ -1,34 +0,0 @@
@@ -1,34 +0,0 @@
|
||||
-----BEGIN CERTIFICATE----- |
||||
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 |
||||
Q5DD3jExbpwG5n35HEcHYw== |
||||
-----END CERTIFICATE----- |
@ -0,0 +1,132 @@
@@ -0,0 +1,132 @@
|
||||
#include <string.h> |
||||
#include <openssl/sha.h> |
||||
#include "Log.h" |
||||
#include "Crypto.h" |
||||
#include "Elligator.h" |
||||
#include "Tag.h" |
||||
#include "I2PEndian.h" |
||||
#include "ECIESX25519AEADRatchetSession.h" |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace garlic |
||||
{ |
||||
|
||||
ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession () |
||||
{ |
||||
// TODO : use precalculated hashes
|
||||
static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes
|
||||
SHA256 ((const uint8_t *)protocolName, 40, m_H); |
||||
memcpy (m_CK, m_H, 32); |
||||
SHA256 (m_H, 32, m_H); |
||||
} |
||||
|
||||
ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession () |
||||
{ |
||||
} |
||||
|
||||
void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) |
||||
{ |
||||
SHA256_CTX ctx; |
||||
SHA256_Init (&ctx); |
||||
SHA256_Update (&ctx, m_H, 32); |
||||
SHA256_Update (&ctx, buf, len); |
||||
SHA256_Final (m_H, &ctx); |
||||
} |
||||
|
||||
bool ECIESX25519AEADRatchetSession::NewIncomingSession (const i2p::data::LocalDestination& dest, |
||||
const uint8_t * buf, size_t len, CloveHandler handleClove) |
||||
{ |
||||
// we are Bob
|
||||
// KDF1
|
||||
MixHash (dest.GetEncryptionPublicKey (), 32); // h = SHA256(h || bpk)
|
||||
|
||||
uint8_t aepk[32]; // Alice's ephemeral key
|
||||
if (!i2p::crypto::GetElligator ()->Decode (buf, aepk)) |
||||
{ |
||||
LogPrint (eLogError, "Garlic: Can't decode elligator"); |
||||
return false; |
||||
} |
||||
buf += 32; len -= 32; |
||||
MixHash (aepk, 32); // h = SHA256(h || aepk)
|
||||
|
||||
uint8_t sharedSecret[32], keyData[64]; |
||||
dest.Decrypt (aepk, sharedSecret, nullptr); // x25519(bsk, aepk)
|
||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64)
|
||||
memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31]
|
||||
|
||||
// decrypt flags/static
|
||||
uint8_t nonce[12], fs[32]; |
||||
memset (nonce, 0, 12); // n = 0
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, keyData + 32, nonce, fs, 32, false)) // decrypt
|
||||
{ |
||||
LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); |
||||
return false; |
||||
} |
||||
MixHash (buf, 48); // h = SHA256(h || ciphertext)
|
||||
buf += 48; len -= 48; // 32 data + 16 poly
|
||||
|
||||
// decrypt payload
|
||||
std::vector<uint8_t> payload (len - 16); |
||||
// KDF2 for payload
|
||||
bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); |
||||
if (isStatic) |
||||
{ |
||||
// static key, fs is apk
|
||||
dest.Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk)
|
||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64)
|
||||
memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31]
|
||||
} |
||||
else // all zeros flags
|
||||
htole64buf (nonce + 4, 1); // n = 1
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keyData + 32, nonce, payload.data (), len - 16, false)) // decrypt
|
||||
{ |
||||
LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); |
||||
return false; |
||||
} |
||||
if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext)
|
||||
|
||||
HandlePayload (payload.data (), len - 16, handleClove); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove) |
||||
{ |
||||
size_t offset = 0; |
||||
while (offset < len) |
||||
{ |
||||
uint8_t blk = buf[offset]; |
||||
offset++; |
||||
auto size = bufbe16toh (buf + offset); |
||||
offset += 2; |
||||
LogPrint (eLogDebug, "Garlic: Block type ", (int)blk, " of size ", size); |
||||
if (size > len) |
||||
{ |
||||
LogPrint (eLogError, "Garlic: Unexpected block length ", size); |
||||
break; |
||||
} |
||||
switch (blk) |
||||
{ |
||||
case eECIESx25519BlkGalicClove: |
||||
handleClove (buf + offset, size); |
||||
break; |
||||
case eECIESx25519BlkDateTime: |
||||
LogPrint (eLogDebug, "Garlic: datetime"); |
||||
break; |
||||
case eECIESx25519BlkOptions: |
||||
LogPrint (eLogDebug, "Garlic: options"); |
||||
break; |
||||
case eECIESx25519BlkPadding: |
||||
LogPrint (eLogDebug, "Garlic: padding"); |
||||
break; |
||||
default: |
||||
LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); |
||||
} |
||||
offset += size; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
#ifndef ECIES_X25519_AEAD_RATCHET_SESSION_H__ |
||||
#define ECIES_X25519_AEAD_RATCHET_SESSION_H__ |
||||
|
||||
#include <inttypes.h> |
||||
#include <functional> |
||||
#include "Identity.h" |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace garlic |
||||
{ |
||||
enum ECIESx25519BlockType |
||||
{ |
||||
eECIESx25519BlkDateTime = 0, |
||||
eECIESx25519BlkSessionID = 1, |
||||
eECIESx25519BlkTermination = 4, |
||||
eECIESx25519BlkOptions = 5, |
||||
eECIESx25519BlkNextSessionKey = 7, |
||||
eECIESx25519BlkGalicClove = 11, |
||||
eECIESx25519BlkPadding = 254 |
||||
}; |
||||
|
||||
class ECIESX25519AEADRatchetSession |
||||
{ |
||||
public: |
||||
|
||||
typedef std::function<void (const uint8_t * buf, size_t len)> CloveHandler; |
||||
|
||||
ECIESX25519AEADRatchetSession (); |
||||
~ECIESX25519AEADRatchetSession (); |
||||
|
||||
bool NewIncomingSession (const i2p::data::LocalDestination& dest, const uint8_t * buf, size_t len, |
||||
CloveHandler handleClove); |
||||
|
||||
private: |
||||
|
||||
void MixHash (const uint8_t * buf, size_t len); |
||||
|
||||
void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); |
||||
|
||||
private: |
||||
|
||||
uint8_t m_H[32], m_CK[32]; |
||||
}; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,196 @@
@@ -0,0 +1,196 @@
|
||||
#include "Crypto.h" |
||||
#include "Elligator.h" |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace crypto |
||||
{ |
||||
|
||||
Elligator2::Elligator2 () |
||||
{ |
||||
// TODO: share with Ed22519
|
||||
p = BN_new (); |
||||
// 2^255-19
|
||||
BN_set_bit (p, 255); // 2^255
|
||||
BN_sub_word (p, 19); |
||||
p38 = BN_dup (p); BN_add_word (p38, 3); BN_div_word (p38, 8); // (p+3)/8
|
||||
p12 = BN_dup (p); BN_sub_word (p12, 1); BN_div_word (p12, 2); // (p-1)/2
|
||||
p14 = BN_dup (p); BN_sub_word (p14, 1); BN_div_word (p14, 4); // (p-1)/4
|
||||
|
||||
A = BN_new (); BN_set_word (A, 486662); |
||||
nA = BN_new (); BN_sub (nA, p, A); |
||||
|
||||
BN_CTX * ctx = BN_CTX_new (); |
||||
// calculate sqrt(-1)
|
||||
sqrtn1 = BN_new (); |
||||
BN_set_word (sqrtn1, 2); |
||||
BN_mod_exp (sqrtn1, sqrtn1, p14, p, ctx); // 2^((p-1)/4
|
||||
|
||||
u = BN_new (); BN_set_word (u, 2); |
||||
iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); |
||||
|
||||
BN_CTX_free (ctx); |
||||
} |
||||
|
||||
Elligator2::~Elligator2 () |
||||
{ |
||||
BN_free (p); BN_free (p38); BN_free (p12); BN_free (p14); |
||||
BN_free (sqrtn1); BN_free (A); BN_free (nA); |
||||
BN_free (u); BN_free (iu); |
||||
} |
||||
|
||||
bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY) const |
||||
{ |
||||
bool ret = true; |
||||
BN_CTX * ctx = BN_CTX_new (); |
||||
BN_CTX_start (ctx); |
||||
|
||||
uint8_t key1[32]; |
||||
for (size_t i = 0; i < 16; i++) // from Little Endian
|
||||
{ |
||||
key1[i] = key[31 - i]; |
||||
key1[31 - i] = key[i]; |
||||
} |
||||
|
||||
BIGNUM * x = BN_CTX_get (ctx); BN_bin2bn (key1, 32, x); |
||||
BIGNUM * xA = BN_CTX_get (ctx); BN_add (xA, x, A); // x + A
|
||||
BN_sub (xA, p, xA); // p - (x + A)
|
||||
|
||||
BIGNUM * uxxA = BN_CTX_get (ctx); // u*x*xA
|
||||
BN_mod_mul (uxxA, u, x, p, ctx); |
||||
BN_mod_mul (uxxA, uxxA, xA, p, ctx); |
||||
|
||||
if (Legendre (uxxA, ctx) != -1) |
||||
{ |
||||
BIGNUM * r = BN_CTX_get (ctx); |
||||
if (highY) |
||||
{ |
||||
BN_mod_inverse (r, x, p, ctx); |
||||
BN_mod_mul (r, r, xA, p, ctx); |
||||
} |
||||
else |
||||
{ |
||||
BN_mod_inverse (r, xA, p, ctx); |
||||
BN_mod_mul (r, r, x, p, ctx); |
||||
} |
||||
BN_mod_mul (r, r, iu, p, ctx); |
||||
|
||||
SquareRoot (r, r, ctx); |
||||
bn2buf (r, encoded, 32); |
||||
|
||||
for (size_t i = 0; i < 16; i++) // To Little Endian
|
||||
{ |
||||
uint8_t tmp = encoded[i]; |
||||
encoded[i] = encoded[31 - i]; |
||||
encoded[31 - i] = tmp; |
||||
} |
||||
} |
||||
else |
||||
ret = false; |
||||
|
||||
BN_CTX_end (ctx); |
||||
BN_CTX_free (ctx); |
||||
return ret; |
||||
} |
||||
|
||||
bool Elligator2::Decode (const uint8_t * encoded, uint8_t * key) const |
||||
{ |
||||
bool ret = true; |
||||
BN_CTX * ctx = BN_CTX_new (); |
||||
BN_CTX_start (ctx); |
||||
|
||||
uint8_t encoded1[32]; |
||||
for (size_t i = 0; i < 16; i++) // from Little Endian
|
||||
{ |
||||
encoded1[i] = encoded[31 - i]; |
||||
encoded1[31 - i] = encoded[i]; |
||||
} |
||||
|
||||
BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r); |
||||
|
||||
if (BN_cmp (r, p12) <= 0) // r < (p-1)/2
|
||||
{ |
||||
// v = -A/(1+u*r^2)
|
||||
BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); |
||||
BN_mod_mul (v, v, u, p, ctx); |
||||
BN_add_word (v, 1); |
||||
BN_mod_inverse (v, v, p, ctx); |
||||
BN_mod_mul (v, v, nA, p, ctx); |
||||
|
||||
BIGNUM * vpA = BN_CTX_get (ctx); |
||||
BN_add (vpA, v, A); // v + A
|
||||
// t = v^3+A*v^2+v = v^2*(v+A)+v
|
||||
BIGNUM * t = BN_CTX_get (ctx); BN_mod_sqr (t, v, p, ctx); |
||||
BN_mod_mul (t, t, vpA, p, ctx); |
||||
BN_mod_add (t, t, v, p, ctx); |
||||
|
||||
int legendre = Legendre (t, ctx); |
||||
BIGNUM * x = BN_CTX_get (ctx); |
||||
if (legendre == 1) |
||||
BN_copy (x, v); |
||||
else |
||||
{ |
||||
BN_sub (x, p, v); |
||||
BN_mod_sub (x, x, A, p, ctx); |
||||
} |
||||
|
||||
bn2buf (x, key, 32); |
||||
for (size_t i = 0; i < 16; i++) // To Little Endian
|
||||
{ |
||||
uint8_t tmp = key[i]; |
||||
key[i] = key[31 - i]; |
||||
key[31 - i] = tmp; |
||||
} |
||||
} |
||||
else |
||||
ret = false; |
||||
|
||||
BN_CTX_end (ctx); |
||||
BN_CTX_free (ctx); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
void Elligator2::SquareRoot (const BIGNUM * x, BIGNUM * r, BN_CTX * ctx) const |
||||
{ |
||||
BIGNUM * t = BN_CTX_get (ctx); |
||||
BN_mod_exp (t, x, p14, p, ctx); // t = x^((p-1)/4)
|
||||
BN_mod_exp (r, x, p38, p, ctx); // r = x^((p+3)/8)
|
||||
BN_add_word (t, 1); |
||||
|
||||
if (!BN_cmp (t, p)) |
||||
BN_mod_mul (r, r, sqrtn1, p, ctx); |
||||
|
||||
if (BN_cmp (r, p12) > 0) // r > (p-1)/2
|
||||
BN_sub (r, p, r); |
||||
} |
||||
|
||||
int Elligator2::Legendre (const BIGNUM * a, BN_CTX * ctx) const |
||||
{ |
||||
// assume a < p, so don't check for a % p = 0, but a = 0 only
|
||||
if (BN_is_zero(a)) return 0; |
||||
BIGNUM * r = BN_CTX_get (ctx); |
||||
BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
|
||||
if (BN_is_word(r, 1)) |
||||
return 1; |
||||
else if (BN_is_zero(r)) |
||||
return 0; |
||||
return -1; |
||||
} |
||||
|
||||
static std::unique_ptr<Elligator2> g_Elligator; |
||||
std::unique_ptr<Elligator2>& GetElligator () |
||||
{ |
||||
if (!g_Elligator) |
||||
{ |
||||
auto el = new Elligator2(); |
||||
if (!g_Elligator) // make sure it was not created already
|
||||
g_Elligator.reset (el); |
||||
else |
||||
delete el; |
||||
} |
||||
return g_Elligator; |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
#ifndef ELLIGATOR_H__ |
||||
#define ELLIGATOR_H__ |
||||
|
||||
#include <inttypes.h> |
||||
#include <memory> |
||||
#include <openssl/bn.h> |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace crypto |
||||
{ |
||||
|
||||
class Elligator2 |
||||
{ |
||||
public: |
||||
|
||||
Elligator2 (); |
||||
~Elligator2 (); |
||||
|
||||
bool Encode (const uint8_t * key, uint8_t * encoded, bool highY = false) const; |
||||
bool Decode (const uint8_t * encoded, uint8_t * key) const; |
||||
|
||||
private: |
||||
|
||||
void SquareRoot (const BIGNUM * x, BIGNUM * r, BN_CTX * ctx) const; |
||||
int Legendre (const BIGNUM * a, BN_CTX * ctx) const; // a/p
|
||||
|
||||
private: |
||||
|
||||
BIGNUM * p, * p38, * p12, * p14, * sqrtn1, * A, * nA, * u, * iu; |
||||
}; |
||||
|
||||
std::unique_ptr<Elligator2>& GetElligator (); |
||||
} |
||||
} |
||||
|
||||
#endif |
||||
|
||||
|
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
#include <cassert> |
||||
#include <inttypes.h> |
||||
#include <string.h> |
||||
|
||||
#include "Elligator.h" |
||||
|
||||
const uint8_t key[32] = |
||||
{ |
||||
0x33, 0x95, 0x19, 0x64, 0x00, 0x3c, 0x94, 0x08, 0x78, 0x06, 0x3c, 0xcf, 0xd0, 0x34, 0x8a, 0xf4, |
||||
0x21, 0x50, 0xca, 0x16, 0xd2, 0x64, 0x6f, 0x2c, 0x58, 0x56, 0xe8, 0x33, 0x83, 0x77, 0xd8, 0x80 |
||||
}; |
||||
|
||||
const uint8_t encoded_key[32] = |
||||
{ |
||||
0x28, 0x20, 0xb6, 0xb2, 0x41, 0xe0, 0xf6, 0x8a, 0x6c, 0x4a, 0x7f, 0xee, 0x3d, 0x97, 0x82, 0x28, |
||||
0xef, 0x3a, 0xe4, 0x55, 0x33, 0xcd, 0x41, 0x0a, 0xa9, 0x1a, 0x41, 0x53, 0x31, 0xd8, 0x61, 0x2d |
||||
}; |
||||
|
||||
const uint8_t encoded_key_high_y[32] = |
||||
{ |
||||
0x3c, 0xfb, 0x87, 0xc4, 0x6c, 0x0b, 0x45, 0x75, 0xca, 0x81, 0x75, 0xe0, 0xed, 0x1c, 0x0a, 0xe9, |
||||
0xda, 0xe7, 0x9d, 0xb7, 0x8d, 0xf8, 0x69, 0x97, 0xc4, 0x84, 0x7b, 0x9f, 0x20, 0xb2, 0x77, 0x18 |
||||
}; |
||||
|
||||
const uint8_t encoded1[32] = |
||||
{ |
||||
0xe7, 0x35, 0x07, 0xd3, 0x8b, 0xae, 0x63, 0x99, 0x2b, 0x3f, 0x57, 0xaa, 0xc4, 0x8c, 0x0a, 0xbc, |
||||
0x14, 0x50, 0x95, 0x89, 0x28, 0x84, 0x57, 0x99, 0x5a, 0x2b, 0x4c, 0xa3, 0x49, 0x0a, 0xa2, 0x07 |
||||
}; |
||||
|
||||
const uint8_t key1[32] = |
||||
{ |
||||
0x1e, 0x8a, 0xff, 0xfe, 0xd6, 0xbf, 0x53, 0xfe, 0x27, 0x1a, 0xd5, 0x72, 0x47, 0x32, 0x62, 0xde, |
||||
0xd8, 0xfa, 0xec, 0x68, 0xe5, 0xe6, 0x7e, 0xf4, 0x5e, 0xbb, 0x82, 0xee, 0xba, 0x52, 0x60, 0x4f |
||||
}; |
||||
|
||||
const uint8_t encoded2[32] = |
||||
{ |
||||
0x95, 0xa1, 0x60, 0x19, 0x04, 0x1d, 0xbe, 0xfe, 0xd9, 0x83, 0x20, 0x48, 0xed, 0xe1, 0x19, 0x28, |
||||
0xd9, 0x03, 0x65, 0xf2, 0x4a, 0x38, 0xaa, 0x7a, 0xef, 0x1b, 0x97, 0xe2, 0x39, 0x54, 0x10, 0x1b |
||||
}; |
||||
|
||||
const uint8_t key2[32] = |
||||
{ |
||||
0x79, 0x4f, 0x05, 0xba, 0x3e, 0x3a, 0x72, 0x95, 0x80, 0x22, 0x46, 0x8c, 0x88, 0x98, 0x1e, 0x0b, |
||||
0xe5, 0x78, 0x2b, 0xe1, 0xe1, 0x14, 0x5c, 0xe2, 0xc3, 0xc6, 0xfd, 0xe1, 0x6d, 0xed, 0x53, 0x63 |
||||
}; |
||||
|
||||
const uint8_t encoded3[32] = |
||||
{ |
||||
0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f |
||||
}; |
||||
|
||||
const uint8_t key3[32] = |
||||
{ |
||||
0x9c, 0xdb, 0x52, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, |
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 |
||||
}; |
||||
|
||||
int main () |
||||
{ |
||||
uint8_t buf[32]; |
||||
i2p::crypto::Elligator2 el; |
||||
// encoding tests
|
||||
el.Encode (key, buf); |
||||
assert(memcmp (buf, encoded_key, 32) == 0); |
||||
el.Encode (key, buf, true); // with highY
|
||||
assert(memcmp (buf, encoded_key_high_y, 32) == 0); |
||||
// decoding tests
|
||||
el.Decode (encoded1, buf); |
||||
assert(memcmp (buf, key1, 32) == 0); |
||||
el.Decode (encoded2, buf); |
||||
assert(memcmp (buf, key2, 32) == 0); |
||||
el.Decode (encoded3, buf); |
||||
assert(memcmp (buf, key3, 32) == 0); |
||||
} |
Loading…
Reference in new issue