diff --git a/Gost.cpp b/Gost.cpp new file mode 100644 index 00000000..7d9db0f8 --- /dev/null +++ b/Gost.cpp @@ -0,0 +1,150 @@ +#include +#include +#include "Gost.h" + +namespace i2p +{ +namespace crypto +{ + GOSTR3410Curve::GOSTR3410Curve (BIGNUM * a, BIGNUM * b, BIGNUM * p, BIGNUM * q, BIGNUM * x, BIGNUM * y) + { + BN_CTX * ctx = BN_CTX_new (); + m_Group = EC_GROUP_new_curve_GFp (p, a, b, ctx); + EC_POINT * P = EC_POINT_new (m_Group); + EC_POINT_set_affine_coordinates_GFp (m_Group, P, x, y, ctx); + EC_GROUP_set_generator (m_Group, P, q, nullptr); + EC_GROUP_set_curve_name (m_Group, NID_id_GostR3410_2001); + EC_POINT_free(P); + BN_CTX_free (ctx); + } + + GOSTR3410Curve::~GOSTR3410Curve () + { + EC_GROUP_free (m_Group); + } + + EC_POINT * GOSTR3410Curve::MulP (const BIGNUM * n) const + { + BN_CTX * ctx = BN_CTX_new (); + auto p = EC_POINT_new (m_Group); + EC_POINT_mul (m_Group, p, n, nullptr, nullptr, ctx); + BN_CTX_free (ctx); + return p; + } + + bool GOSTR3410Curve::GetXY (const EC_POINT * p, BIGNUM * x, BIGNUM * y) const + { + return EC_POINT_get_affine_coordinates_GFp (m_Group, p, x, y, nullptr); + } + + EC_POINT * GOSTR3410Curve::CreatePoint (const BIGNUM * x, const BIGNUM * y) const + { + EC_POINT * p = EC_POINT_new (m_Group); + EC_POINT_set_affine_coordinates_GFp (m_Group, p, x, y, nullptr); + return p; + } + + void GOSTR3410Curve::Sign (const BIGNUM * priv, const BIGNUM * digest, BIGNUM * r, BIGNUM * s) + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order(m_Group, q, ctx); + BIGNUM * k = BN_CTX_get (ctx); + BN_rand_range (k, q); // 0 < k < q + EC_POINT * C = MulP (k); // C = k*P + GetXY (C, r, nullptr); // r = Cx + EC_POINT_free (C); + BN_mod_mul (s, r, priv, q, ctx); // (r*priv)%q + BIGNUM * tmp = BN_CTX_get (ctx); + BN_mod_mul (tmp, k, digest, q, ctx); // (k*digest)%q + BN_mod_add (s, s, tmp, q, ctx); // (r*priv+k*digest)%q + BN_CTX_end (ctx); + BN_CTX_free (ctx); + } + + bool GOSTR3410Curve::Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s) + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order(m_Group, q, ctx); + BIGNUM * h = BN_CTX_get (ctx); + BN_mod (h, digest, q, ctx); // h = digest % q + BN_mod_inverse (h, h, q, ctx); // 1/h mod q + BIGNUM * z1 = BN_CTX_get (ctx); + BN_mod_mul (z1, s, h, q, ctx); // z1 = s/h + BIGNUM * z2 = BN_CTX_get (ctx); + BN_sub (z2, q, r); // z2 = -r + BN_mod_mul (z2, z2, h, q, ctx); // z2 = -r/h + EC_POINT * C = EC_POINT_new (m_Group); + EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub + BIGNUM * x = BN_CTX_get (ctx); + GetXY (C, x, nullptr); // Cx + BN_mod (x, x, q, ctx); // Cx % q + bool ret = !BN_cmp (x, r); // Cx = r ? + EC_POINT_free (C); + BN_CTX_end (ctx); + BN_CTX_free (ctx); + return ret; + } + + static GOSTR3410Curve * CreateGOSTR3410Curve (GOSTR3410ParamSet paramSet) + { + // a, b, p, q, x, y + static const char * params[eGOSTR3410NumParamSets][6] = + { + { + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", + "A6", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", + "1", + "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14" + }, // A + { + "8000000000000000000000000000000000000000000000000000000000000C96", + "3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B", + "8000000000000000000000000000000000000000000000000000000000000C99", + "800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F", + "1", + "3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC" + }, // B + { + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598", + "805A", + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B", + "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", + "0", + "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67" + } // C + }; + + BIGNUM * a = nullptr, * b = nullptr, * p = nullptr, * q =nullptr, * x = nullptr, * y = nullptr; + BN_hex2bn(&a, params[paramSet][0]); + BN_hex2bn(&b, params[paramSet][1]); + BN_hex2bn(&p, params[paramSet][2]); + BN_hex2bn(&q, params[paramSet][3]); + BN_hex2bn(&x, params[paramSet][4]); + BN_hex2bn(&y, params[paramSet][5]); + auto curve = new GOSTR3410Curve (a, b, p, q, x, y); + BN_free (a); BN_free (b); BN_free (p); BN_free (q); BN_free (x); BN_free (y); + return curve; + } + + static std::array, eGOSTR3410NumParamSets> g_GOSTR3410Curves; + std::unique_ptr& GetGOSTR3410Curve (GOSTR3410ParamSet paramSet) + { + if (!g_GOSTR3410Curves[paramSet]) + { + auto c = CreateGOSTR3410Curve (paramSet); + if (!g_GOSTR3410Curves[paramSet]) // make sure it was not created already + g_GOSTR3410Curves[paramSet].reset (c); + else + delete c; + } + return g_GOSTR3410Curves[paramSet]; + } + +} +} diff --git a/Gost.h b/Gost.h new file mode 100644 index 00000000..f287219f --- /dev/null +++ b/Gost.h @@ -0,0 +1,47 @@ +#ifndef GOST_H__ +#define GOST_H__ + +#include +#include + +namespace i2p +{ +namespace crypto +{ + + // ГОСТ Р 34.10 + + enum GOSTR3410ParamSet + { + eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1 + eGOSTR3410CryptoProB, // 1.2.643.2.2.35.2 + eGOSTR3410CryptoProC, // 1.2.643.2.2.35.3 + //eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0 + //eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1 + // XchA = A, XchB = C + eGOSTR3410NumParamSets + }; + + class GOSTR3410Curve + { + public: + + GOSTR3410Curve (BIGNUM * a, BIGNUM * b, BIGNUM * p, BIGNUM * q, BIGNUM * x, BIGNUM * y); + ~GOSTR3410Curve (); + + EC_POINT * MulP (const BIGNUM * n) const; + bool GetXY (const EC_POINT * p, BIGNUM * x, BIGNUM * y) const; + EC_POINT * CreatePoint (const BIGNUM * x, const BIGNUM * y) const; + void Sign (const BIGNUM * priv, const BIGNUM * digest, BIGNUM * r, BIGNUM * s); + bool Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s); + + private: + + EC_GROUP * m_Group; + }; + + std::unique_ptr& GetGOSTR3410Curve (GOSTR3410ParamSet paramSet); +} +} + +#endif \ No newline at end of file diff --git a/Signature.cpp b/Signature.cpp index 15d606dc..bcb451f2 100644 --- a/Signature.cpp +++ b/Signature.cpp @@ -1,5 +1,4 @@ #include -#include #include "Log.h" #include "Signature.h" @@ -497,155 +496,6 @@ namespace crypto //---------------------------------------------- // GOST - class GOSTR3410Curve - { - public: - - GOSTR3410Curve (BIGNUM * a, BIGNUM * b, BIGNUM * p, BIGNUM * q, BIGNUM * x, BIGNUM * y) - { - BN_CTX * ctx = BN_CTX_new (); - m_Group = EC_GROUP_new_curve_GFp (p, a, b, ctx); - EC_POINT * P = EC_POINT_new (m_Group); - EC_POINT_set_affine_coordinates_GFp (m_Group, P, x, y, ctx); - EC_GROUP_set_generator (m_Group, P, q, nullptr); - EC_GROUP_set_curve_name (m_Group, NID_id_GostR3410_2001); - EC_POINT_free(P); - BN_CTX_free (ctx); - } - - ~GOSTR3410Curve () - { - EC_GROUP_free (m_Group); - } - - EC_POINT * MulP (const BIGNUM * n) const - { - BN_CTX * ctx = BN_CTX_new (); - auto p = EC_POINT_new (m_Group); - EC_POINT_mul (m_Group, p, n, nullptr, nullptr, ctx); - BN_CTX_free (ctx); - return p; - } - - bool GetXY (const EC_POINT * p, BIGNUM * x, BIGNUM * y) const - { - return EC_POINT_get_affine_coordinates_GFp (m_Group, p, x, y, nullptr); - } - - EC_POINT * CreatePoint (const BIGNUM * x, const BIGNUM * y) const - { - EC_POINT * p = EC_POINT_new (m_Group); - EC_POINT_set_affine_coordinates_GFp (m_Group, p, x, y, nullptr); - return p; - } - - void Sign (const BIGNUM * priv, const BIGNUM * digest, BIGNUM * r, BIGNUM * s) - { - BN_CTX * ctx = BN_CTX_new (); - BN_CTX_start (ctx); - BIGNUM * q = BN_CTX_get (ctx); - EC_GROUP_get_order(m_Group, q, ctx); - BIGNUM * k = BN_CTX_get (ctx); - BN_rand_range (k, q); // 0 < k < q - EC_POINT * C = MulP (k); // C = k*P - GetXY (C, r, nullptr); // r = Cx - EC_POINT_free (C); - BN_mod_mul (s, r, priv, q, ctx); // (r*priv)%q - BIGNUM * tmp = BN_CTX_get (ctx); - BN_mod_mul (tmp, k, digest, q, ctx); // (k*digest)%q - BN_mod_add (s, s, tmp, q, ctx); // (r*priv+k*digest)%q - BN_CTX_end (ctx); - BN_CTX_free (ctx); - } - - bool Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s) - { - BN_CTX * ctx = BN_CTX_new (); - BN_CTX_start (ctx); - BIGNUM * q = BN_CTX_get (ctx); - EC_GROUP_get_order(m_Group, q, ctx); - BIGNUM * h = BN_CTX_get (ctx); - BN_mod (h, digest, q, ctx); // h = digest % q - BN_mod_inverse (h, h, q, ctx); // 1/h mod q - BIGNUM * z1 = BN_CTX_get (ctx); - BN_mod_mul (z1, s, h, q, ctx); // z1 = s/h - BIGNUM * z2 = BN_CTX_get (ctx); - BN_sub (z2, q, r); // z2 = -r - BN_mod_mul (z2, z2, h, q, ctx); // z2 = -r/h - EC_POINT * C = EC_POINT_new (m_Group); - EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub - BIGNUM * x = BN_CTX_get (ctx); - GetXY (C, x, nullptr); // Cx - BN_mod (x, x, q, ctx); // Cx % q - bool ret = !BN_cmp (x, r); // Cx = r ? - EC_POINT_free (C); - BN_CTX_end (ctx); - BN_CTX_free (ctx); - return ret; - } - - private: - - EC_GROUP * m_Group; - }; - - GOSTR3410Curve * CreateGOSTR3410Curve (GOSTR3410ParamSet paramSet) - { - // a, b, p, q, x, y - static const char * params[eGOSTR3410NumParamSets][6] = - { - { - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", - "A6", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", - "1", - "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14" - }, // A - { - "8000000000000000000000000000000000000000000000000000000000000C96", - "3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B", - "8000000000000000000000000000000000000000000000000000000000000C99", - "800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F", - "1", - "3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC" - }, // B - { - "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598", - "805A", - "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B", - "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", - "0", - "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67" - } // C - }; - - BIGNUM * a = nullptr, * b = nullptr, * p = nullptr, * q =nullptr, * x = nullptr, * y = nullptr; - BN_hex2bn(&a, params[paramSet][0]); - BN_hex2bn(&b, params[paramSet][1]); - BN_hex2bn(&p, params[paramSet][2]); - BN_hex2bn(&q, params[paramSet][3]); - BN_hex2bn(&x, params[paramSet][4]); - BN_hex2bn(&y, params[paramSet][5]); - auto curve = new GOSTR3410Curve (a, b, p, q, x, y); - BN_free (a); BN_free (b); BN_free (p); BN_free (q); BN_free (x); BN_free (y); - return curve; - } - - static std::array, eGOSTR3410NumParamSets> g_GOSTR3410Curves; - std::unique_ptr& GetGOSTR3410Curve (GOSTR3410ParamSet paramSet) - { - if (!g_GOSTR3410Curves[paramSet]) - { - auto c = CreateGOSTR3410Curve (paramSet); - if (!g_GOSTR3410Curves[paramSet]) // make sure it was not created already - g_GOSTR3410Curves[paramSet].reset (c); - else - delete c; - } - return g_GOSTR3410Curves[paramSet]; - } - GOSTR3410Verifier::GOSTR3410Verifier (GOSTR3410ParamSet paramSet, const uint8_t * signingKey): m_ParamSet (paramSet) { diff --git a/Signature.h b/Signature.h index 0ccb99ea..91f0e66b 100644 --- a/Signature.h +++ b/Signature.h @@ -9,6 +9,7 @@ #include #include #include "Crypto.h" +#include "Gost.h" namespace i2p { @@ -443,17 +444,6 @@ namespace crypto } // ГОСТ Р 34.10-2001 - - enum GOSTR3410ParamSet - { - eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1 - eGOSTR3410CryptoProB, // 1.2.643.2.2.35.2 - eGOSTR3410CryptoProC, // 1.2.643.2.2.35.3 - //eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0 - //eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1 - // XchA = A, XchB = C - eGOSTR3410NumParamSets - }; const size_t GOSTR3410_PUBLIC_KEY_LENGTH = 64; const size_t GOSTR3410_SIGNATURE_LENGTH = 64; diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 1bba69f0..46e00896 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -59,6 +59,7 @@ LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp \ ../../TunnelPool.cpp \ ../../Timestamp.cpp \ ../../Event.cpp \ + ../../Gost.cpp \ ../../WebSocks.cpp \ ../../BloomFilter.cpp \ ../../util.cpp \ diff --git a/filelist.mk b/filelist.mk index d5d703a6..9149eefa 100644 --- a/filelist.mk +++ b/filelist.mk @@ -5,7 +5,7 @@ LIB_SRC = \ SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \ Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \ - Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Event.cpp + Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Event.cpp Gost.cpp LIB_CLIENT_SRC = \ AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \ diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 36883399..dd3987d9 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -36,7 +36,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ ../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \ - ../../Event.cpp ../../BloomFilter.cpp ../../WebSocks.cpp ../../i2pd.cpp + ../../Event.cpp ../../BloomFiler.cpp ../../Gost.cpp ../../i2pd.cpp HEADERS += DaemonQT.h mainwindow.h \ ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ @@ -51,7 +51,7 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \ ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \ ../../util.h ../../version.h ../../Gzip.h ../../Tag.h \ - ../../BloomFilter.h ../../Event.h ../../WebSocks.h + ../../BloomFiler.h ../../Event.h ../../Gost.h FORMS += mainwindow.ui