mirror of https://github.com/PurpleI2P/i2pd.git
orignal
6 years ago
committed by
GitHub
36 changed files with 1603 additions and 1030 deletions
@ -1,34 +0,0 @@
@@ -1,34 +0,0 @@
|
||||
-----BEGIN CERTIFICATE----- |
||||
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 |
||||
cGpnw4a2u9sHZIUNHzoGq32+7UWXsBI5Ow== |
||||
-----END CERTIFICATE----- |
@ -0,0 +1,301 @@
@@ -0,0 +1,301 @@
|
||||
#include <zlib.h> // for crc32 |
||||
#include <openssl/sha.h> |
||||
#include <openssl/hmac.h> |
||||
#include <openssl/ec.h> |
||||
#include <openssl/bn.h> |
||||
#include "Base.h" |
||||
#include "Crypto.h" |
||||
#include "Log.h" |
||||
#include "Timestamp.h" |
||||
#include "I2PEndian.h" |
||||
#include "Ed25519.h" |
||||
#include "Signature.h" |
||||
#include "Blinding.h" |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace data |
||||
{ |
||||
static 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); |
||||
} |
||||
|
||||
static void BlindEncodedPublicKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * pub, const uint8_t * seed, uint8_t * blindedPub) |
||||
{ |
||||
BIGNUM * x = BN_bin2bn (pub, publicKeyLen/2, NULL); |
||||
BIGNUM * y = BN_bin2bn (pub + publicKeyLen/2, publicKeyLen/2, NULL); |
||||
EC_POINT * p = EC_POINT_new (group); |
||||
EC_POINT_set_affine_coordinates_GFp (group, p, x, y, NULL); |
||||
EC_POINT * p1 = BlindPublicKeyECDSA (group, p, seed); |
||||
EC_POINT_free (p); |
||||
EC_POINT_get_affine_coordinates_GFp (group, p1, x, y, NULL); |
||||
EC_POINT_free (p1); |
||||
i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); |
||||
i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); |
||||
BN_free (x); BN_free (y); |
||||
} |
||||
|
||||
static void BlindEncodedPrivateKeyECDSA (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); |
||||
} |
||||
|
||||
template<typename Fn, typename...Args> |
||||
static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args) |
||||
// blind is BlindEncodedPublicKeyECDSA or BlindEncodedPrivateKeyECDSA
|
||||
{ |
||||
size_t publicKeyLength = 0; |
||||
EC_GROUP * group = nullptr; |
||||
switch (sigType) |
||||
{ |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: |
||||
{ |
||||
publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; |
||||
group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); |
||||
break; |
||||
} |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: |
||||
{ |
||||
publicKeyLength = i2p::crypto::ECDSAP384_KEY_LENGTH; |
||||
group = EC_GROUP_new_by_curve_name (NID_secp384r1); |
||||
break; |
||||
} |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: |
||||
{ |
||||
publicKeyLength = i2p::crypto::ECDSAP521_KEY_LENGTH; |
||||
group = EC_GROUP_new_by_curve_name (NID_secp521r1); |
||||
break; |
||||
} |
||||
default: |
||||
LogPrint (eLogError, "Blinding: signature type ", (int)sigType, " is not ECDSA"); |
||||
} |
||||
if (group) |
||||
{ |
||||
blind (publicKeyLength, group, key, seed, std::forward<Args>(args)...); |
||||
EC_GROUP_free (group); |
||||
} |
||||
return publicKeyLength; |
||||
} |
||||
|
||||
|
||||
BlindedPublicKey::BlindedPublicKey (std::shared_ptr<const IdentityEx> 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) |
||||
{ |
||||
uint8_t addr[40]; // TODO: define length from b33
|
||||
size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40); |
||||
uint32_t checksum = crc32 (0, addr + 3, l - 3); |
||||
// checksum is Little Endian
|
||||
addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); |
||||
uint8_t flag = addr[0]; |
||||
size_t offset = 1; |
||||
if (flag & 0x01) // two bytes signatures
|
||||
{ |
||||
m_SigType = bufbe16toh (addr + offset); offset += 2; |
||||
m_BlindedSigType = bufbe16toh (addr + offset); offset += 2; |
||||
} |
||||
else // one byte sig
|
||||
{ |
||||
m_SigType = addr[offset]; offset++; |
||||
m_BlindedSigType = addr[offset]; offset++; |
||||
} |
||||
std::unique_ptr<i2p::crypto::Verifier> blindedVerifier (i2p::data::IdentityEx::CreateVerifier (m_SigType)); |
||||
if (blindedVerifier) |
||||
{ |
||||
auto len = blindedVerifier->GetPublicKeyLen (); |
||||
if (offset + len <= l) |
||||
{ |
||||
m_PublicKey.resize (len); |
||||
memcpy (m_PublicKey.data (), addr + offset, len); |
||||
} |
||||
else |
||||
LogPrint (eLogError, "Blinding: public key in b33 address is too short for signature type ", (int)m_SigType); |
||||
} |
||||
else |
||||
LogPrint (eLogError, "Blinding: unknown signature type ", (int)m_SigType, " in b33"); |
||||
} |
||||
|
||||
std::string BlindedPublicKey::ToB33 () const |
||||
{ |
||||
if (m_PublicKey.size () > 32) return ""; // assume 25519
|
||||
uint8_t addr[35]; char str[60]; // TODO: define actual length
|
||||
addr[0] = 0; // flags
|
||||
addr[1] = m_SigType; // sig type
|
||||
addr[2] = m_BlindedSigType; // blinded sig type
|
||||
memcpy (addr + 3, m_PublicKey.data (), m_PublicKey.size ()); |
||||
uint32_t checksum = crc32 (0, addr + 3, m_PublicKey.size ()); |
||||
// checksum is Little Endian
|
||||
addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); |
||||
auto l = ByteStreamToBase32 (addr, m_PublicKey.size () + 3, str, 60); |
||||
return std::string (str, str + l); |
||||
} |
||||
|
||||
void BlindedPublicKey::GetCredential (uint8_t * credential) const |
||||
{ |
||||
// A = destination's signing public key
|
||||
// stA = signature type of A, 2 bytes big endian
|
||||
uint16_t stA = htobe16 (GetSigType ()); |
||||
// stA1 = signature type of blinded A, 2 bytes big endian
|
||||
uint16_t stA1 = htobe16 (GetBlindedSigType ()); |
||||
// credential = H("credential", A || stA || stA1)
|
||||
H ("credential", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, credential); |
||||
} |
||||
|
||||
void BlindedPublicKey::GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const |
||||
{ |
||||
uint8_t credential[32]; |
||||
GetCredential (credential); |
||||
// subcredential = H("subcredential", credential || blindedPublicKey)
|
||||
H ("subcredential", { {credential, 32}, {blinded, len} }, subcredential); |
||||
} |
||||
|
||||
void BlindedPublicKey::GenerateAlpha (const char * date, uint8_t * seed) const |
||||
{ |
||||
uint16_t stA = htobe16 (GetSigType ()), stA1 = htobe16 (GetBlindedSigType ()); |
||||
uint8_t salt[32]; |
||||
//seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64)
|
||||
H ("I2PGenerateAlpha", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, salt); |
||||
i2p::crypto::HKDF (salt, (const uint8_t *)date, 8, "i2pblinding1", seed); |
||||
} |
||||
|
||||
size_t BlindedPublicKey::GetBlindedKey (const char * date, uint8_t * blindedKey) const |
||||
{ |
||||
uint8_t seed[64]; |
||||
GenerateAlpha (date, seed); |
||||
|
||||
size_t publicKeyLength = 0; |
||||
switch (m_SigType) |
||||
{ |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: |
||||
publicKeyLength = BlindECDSA (m_SigType, GetPublicKey (), seed, BlindEncodedPublicKeyECDSA, blindedKey); |
||||
break; |
||||
case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: |
||||
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: |
||||
i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); |
||||
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; |
||||
break; |
||||
default: |
||||
LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); |
||||
} |
||||
return publicKeyLength; |
||||
} |
||||
|
||||
size_t BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const |
||||
{ |
||||
uint8_t seed[64]; |
||||
GenerateAlpha (date, seed); |
||||
size_t publicKeyLength = 0; |
||||
switch (m_SigType) |
||||
{ |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: |
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: |
||||
publicKeyLength = BlindECDSA (m_SigType, priv, seed, BlindEncodedPrivateKeyECDSA, blindedPriv, blindedPub); |
||||
break; |
||||
case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: |
||||
i2p::crypto::GetEd25519 ()->BlindPrivateKey (priv, seed, blindedPriv, blindedPub); |
||||
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; |
||||
break; |
||||
default: |
||||
LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); |
||||
} |
||||
return publicKeyLength; |
||||
} |
||||
|
||||
void BlindedPublicKey::H (const std::string& p, const std::vector<std::pair<const uint8_t *, size_t> >& bufs, uint8_t * hash) const |
||||
{ |
||||
SHA256_CTX ctx; |
||||
SHA256_Init (&ctx); |
||||
SHA256_Update (&ctx, p.c_str (), p.length ()); |
||||
for (const auto& it: bufs) |
||||
SHA256_Update (&ctx, it.first, it.second); |
||||
SHA256_Final (hash, &ctx); |
||||
} |
||||
|
||||
i2p::data::IdentHash BlindedPublicKey::GetStoreHash (const char * date) const |
||||
{ |
||||
i2p::data::IdentHash hash; |
||||
uint8_t blinded[128]; |
||||
size_t publicKeyLength = 0; |
||||
if (date) |
||||
publicKeyLength = GetBlindedKey (date, blinded); |
||||
else |
||||
{ |
||||
char currentDate[9]; |
||||
i2p::util::GetCurrentDate (currentDate); |
||||
publicKeyLength = GetBlindedKey (currentDate, blinded); |
||||
} |
||||
if (publicKeyLength) |
||||
{ |
||||
auto stA1 = htobe16 (m_BlindedSigType); |
||||
SHA256_CTX ctx; |
||||
SHA256_Init (&ctx); |
||||
SHA256_Update (&ctx, (const uint8_t *)&stA1, 2); |
||||
SHA256_Update (&ctx, blinded, publicKeyLength); |
||||
SHA256_Final ((uint8_t *)hash, &ctx); |
||||
} |
||||
else |
||||
LogPrint (eLogError, "Blinding: blinded key type ", (int)m_BlindedSigType, " is not supported"); |
||||
return hash; |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
#ifndef BLINDING_H__ |
||||
#define BLINDING_H__ |
||||
|
||||
#include <inttypes.h> |
||||
#include <string> |
||||
#include <vector> |
||||
#include "Identity.h" |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace data |
||||
{ |
||||
class BlindedPublicKey // for encrypted LS2
|
||||
{ |
||||
public: |
||||
|
||||
BlindedPublicKey (std::shared_ptr<const IdentityEx> identity); |
||||
BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p
|
||||
std::string ToB33 () const; |
||||
|
||||
const uint8_t * GetPublicKey () const { return m_PublicKey.data (); }; |
||||
size_t GetPublicKeyLen () const { return m_PublicKey.size (); }; |
||||
SigningKeyType GetSigType () const { return m_SigType; }; |
||||
SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; }; |
||||
|
||||
void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes
|
||||
size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length
|
||||
size_t BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // date is 8 chars "YYYYMMDD", return public key length
|
||||
i2p::data::IdentHash GetStoreHash (const char * date = nullptr) const; // date is 8 chars "YYYYMMDD", use current if null
|
||||
|
||||
private: |
||||
|
||||
void GetCredential (uint8_t * credential) const; // 32 bytes
|
||||
void GenerateAlpha (const char * date, uint8_t * seed) const; // 64 bytes, date is 8 chars "YYYYMMDD"
|
||||
void H (const std::string& p, const std::vector<std::pair<const uint8_t *, size_t> >& bufs, uint8_t * hash) const; |
||||
|
||||
private: |
||||
|
||||
std::vector<uint8_t> m_PublicKey; |
||||
i2p::data::SigningKeyType m_SigType, m_BlindedSigType; |
||||
}; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
#include <cassert> |
||||
#include <memory> |
||||
#include <string.h> |
||||
#include "Blinding.h" |
||||
#include "Identity.h" |
||||
#include "Timestamp.h" |
||||
|
||||
using namespace i2p::data; |
||||
using namespace i2p::util; |
||||
using namespace i2p::crypto; |
||||
|
||||
void BlindTest (SigningKeyType sigType) |
||||
{ |
||||
auto keys = PrivateKeys::CreateRandomKeys (sigType); |
||||
BlindedPublicKey blindedKey (keys.GetPublic ()); |
||||
auto timestamp = GetSecondsSinceEpoch (); |
||||
char date[9]; |
||||
GetDateString (timestamp, date); |
||||
uint8_t blindedPriv[64], blindedPub[128]; |
||||
auto publicKeyLen = blindedKey.BlindPrivateKey (keys.GetSigningPrivateKey (), date, blindedPriv, blindedPub); |
||||
uint8_t blindedPub1[128]; |
||||
blindedKey.GetBlindedKey (date, blindedPub1); |
||||
// check if public key produced from private blinded key matches blided public key
|
||||
assert (!memcmp (blindedPub, blindedPub1, publicKeyLen)); |
||||
// try to sign and verify
|
||||
std::unique_ptr<Signer> blindedSigner (PrivateKeys::CreateSigner (sigType, blindedPriv)); |
||||
uint8_t buf[100], signature[128]; |
||||
memset (buf, 1, 100); |
||||
blindedSigner->Sign (buf, 100, signature); |
||||
std::unique_ptr<Verifier> blindedVerifier (IdentityEx::CreateVerifier (sigType)); |
||||
blindedVerifier->SetPublicKey (blindedPub1); |
||||
assert (blindedVerifier->Verify (buf, 100, signature)); |
||||
} |
||||
|
||||
int main () |
||||
{ |
||||
// RedDSA test
|
||||
BlindTest (SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); |
||||
// P256 test
|
||||
BlindTest (SIGNING_KEY_TYPE_ECDSA_SHA256_P256); |
||||
// P384 test
|
||||
BlindTest (SIGNING_KEY_TYPE_ECDSA_SHA384_P384); |
||||
} |
Loading…
Reference in new issue