#include "Crypto.h" #include "Elligator.h" namespace i2p { namespace crypto { static const uint8_t p_[32]= { 0xed, 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, 0x7f }; static const uint8_t n1_[32] = { 0xec, 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, 0x7f }; static const uint8_t n2_[32] = { 0xeb, 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, 0x7f }; static const uint8_t A_[32] = { 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uint8_t u_[32] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define decode_bytes(x) { x = BN_new (); BN_bin2bn (x##_, 32, x); } Elligator2::Elligator2 () { decode_bytes (p); decode_bytes (n1); decode_bytes (n2); decode_bytes (A); decode_bytes (u); BN_CTX * ctx = BN_CTX_new (); BN_mod_inverse (iu, u, p, ctx); BN_CTX_free (ctx); } Elligator2::~Elligator2 () { BN_free (p); BN_free (n1); BN_free (n2); BN_free (A); } void Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * a = BN_CTX_get (ctx); BN_bin2bn (key, 32, a); BIGNUM * b = BN_CTX_get (ctx); BN_add (a, A, b); BIGNUM * c = BN_CTX_get (ctx); BN_mod_exp (c, b, n2, p, ctx); BN_mod_mul (b, c, a, p, ctx); BN_sub (b, p, b); //BN_mod_exp (c, b, n2, p, ctx); BN_mod_mul (c, b, iu, p, ctx); // TODO: bn2buf (b, encoded, 32); BN_CTX_end (ctx); BN_CTX_free (ctx); } static std::unique_ptr g_Elligator; std::unique_ptr& 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; } } }