diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 4469123e..f4d6040e 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -1,6 +1,8 @@ #include // for crc32 #include #include +#include +#include #include "Base.h" #include "Crypto.h" #include "Log.h" @@ -13,14 +15,70 @@ namespace i2p { namespace data { - BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType): - m_BlindedSigType (blindedKeyType) + const EC_POINT * BlindPublicKeyECDSA (const EC_GROUP * group, const EC_POINT * pub, const uint8_t * seed) + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order (group, q, ctx); + // calculate alpha = seed mod q + BIGNUM * alpha = BN_CTX_get (ctx); + BN_bin2bn (seed, 64, alpha); // seed is in BigEndian + BN_mod (alpha, alpha, q, ctx); // % q + // A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha) + auto p = EC_POINT_new (group); + EC_POINT_mul (group, p, alpha, nullptr, nullptr, ctx); // B*alpha + EC_POINT_add (group, p, pub, p, ctx); // pub + B*alpha + BN_CTX_end (ctx); + BN_CTX_free (ctx); + return p; + } + + static void BlindPrivateKeyECDSA (const EC_GROUP * group, const BIGNUM * priv, const uint8_t * seed, BIGNUM * blindedPriv) + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order (group, q, ctx); + // calculate alpha = seed mod q + BIGNUM * alpha = BN_CTX_get (ctx); + BN_bin2bn (seed, 64, alpha); // seed is in BigEndian + BN_mod (alpha, alpha, q, ctx); // % q + BN_add (alpha, alpha, priv); // alpha = alpha + priv + // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod q + BN_mod (blindedPriv, alpha, q, ctx); // % q + BN_CTX_end (ctx); + BN_CTX_free (ctx); + } + + void BlindPrivateKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub) + { + BIGNUM * a = BN_bin2bn (priv, publicKeyLen/2, NULL); + BIGNUM * a1 = BN_new (); + BlindPrivateKeyECDSA (group, a, seed, a1); + BN_free (a); + i2p::crypto::bn2buf (a1, blindedPriv, publicKeyLen/2); + auto p = EC_POINT_new (group); + BN_CTX * ctx = BN_CTX_new (); + EC_POINT_mul (group, p, a1, nullptr, nullptr, ctx); // B*a1 + BN_CTX_free (ctx); + BN_free (a1); + BIGNUM * x = BN_new(), * y = BN_new(); + EC_POINT_get_affine_coordinates_GFp (group, p, x, y, NULL); + EC_POINT_free (p); + i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); + i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); + BN_free (x); BN_free (y); + } + + BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity) { if (!identity) return; auto len = identity->GetSigningPublicKeyLen (); m_PublicKey.resize (len); memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); m_SigType = identity->GetSigningKeyType (); + m_BlindedSigType = m_SigType; } BlindedPublicKey::BlindedPublicKey (const std::string& b33) @@ -129,7 +187,7 @@ namespace data { i2p::data::IdentHash hash; if (m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 || - m_BlindedSigType == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) + m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) { uint8_t blinded[32]; if (date) diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 6c3671c6..56e0d4cd 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -14,7 +14,7 @@ namespace data { public: - BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); + BlindedPublicKey (std::shared_ptr identity); BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p std::string ToB33 () const;