|
|
@ -1,6 +1,8 @@ |
|
|
|
#include <zlib.h> // for crc32 |
|
|
|
#include <zlib.h> // for crc32 |
|
|
|
#include <openssl/sha.h> |
|
|
|
#include <openssl/sha.h> |
|
|
|
#include <openssl/hmac.h> |
|
|
|
#include <openssl/hmac.h> |
|
|
|
|
|
|
|
#include <openssl/ec.h> |
|
|
|
|
|
|
|
#include <openssl/bn.h> |
|
|
|
#include "Base.h" |
|
|
|
#include "Base.h" |
|
|
|
#include "Crypto.h" |
|
|
|
#include "Crypto.h" |
|
|
|
#include "Log.h" |
|
|
|
#include "Log.h" |
|
|
@ -13,14 +15,70 @@ namespace i2p |
|
|
|
{ |
|
|
|
{ |
|
|
|
namespace data |
|
|
|
namespace data |
|
|
|
{ |
|
|
|
{ |
|
|
|
BlindedPublicKey::BlindedPublicKey (std::shared_ptr<const IdentityEx> identity, SigningKeyType blindedKeyType): |
|
|
|
const EC_POINT * BlindPublicKeyECDSA (const EC_GROUP * group, const EC_POINT * pub, const uint8_t * seed) |
|
|
|
m_BlindedSigType (blindedKeyType) |
|
|
|
{ |
|
|
|
|
|
|
|
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<const IdentityEx> identity) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!identity) return; |
|
|
|
if (!identity) return; |
|
|
|
auto len = identity->GetSigningPublicKeyLen (); |
|
|
|
auto len = identity->GetSigningPublicKeyLen (); |
|
|
|
m_PublicKey.resize (len); |
|
|
|
m_PublicKey.resize (len); |
|
|
|
memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); |
|
|
|
memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); |
|
|
|
m_SigType = identity->GetSigningKeyType (); |
|
|
|
m_SigType = identity->GetSigningKeyType (); |
|
|
|
|
|
|
|
m_BlindedSigType = m_SigType; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
BlindedPublicKey::BlindedPublicKey (const std::string& b33) |
|
|
|
BlindedPublicKey::BlindedPublicKey (const std::string& b33) |
|
|
@ -129,7 +187,7 @@ namespace data |
|
|
|
{ |
|
|
|
{ |
|
|
|
i2p::data::IdentHash hash; |
|
|
|
i2p::data::IdentHash hash; |
|
|
|
if (m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 || |
|
|
|
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]; |
|
|
|
uint8_t blinded[32]; |
|
|
|
if (date) |
|
|
|
if (date) |
|
|
|