mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-08 22:13:48 +01:00
scalar multiplication for x25519
This commit is contained in:
parent
a8278fc78b
commit
046a80cfe4
3 changed files with 103 additions and 9 deletions
|
@ -411,12 +411,103 @@ namespace crypto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed25519::Mul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
BIGNUM * Ed25519::ScalarMul (const BIGNUM * p, const BIGNUM * n, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
auto P = DecodePublicKey (p, ctx);
|
BN_CTX_start (ctx);
|
||||||
BIGNUM * e1 = DecodeBN<32> (e);
|
auto x1 = BN_CTX_get (ctx); BN_copy (x1, p);
|
||||||
EncodePublicKey (Mul (P, e1, ctx), buf, ctx);
|
auto x2 = BN_CTX_get (ctx); BN_one (x2);
|
||||||
BN_free (e1);
|
auto z2 = BN_CTX_get (ctx); BN_zero (z2);
|
||||||
|
auto x3 = BN_CTX_get (ctx); BN_copy (x1, p);
|
||||||
|
auto z3 = BN_CTX_get (ctx); BN_one (z3);
|
||||||
|
auto a24 = BN_CTX_get (ctx); BN_set_word (a24, 121665);
|
||||||
|
auto a = BN_CTX_get (ctx); auto aa = BN_CTX_get (ctx);
|
||||||
|
auto b = BN_CTX_get (ctx); auto bb = BN_CTX_get (ctx);
|
||||||
|
auto e = BN_CTX_get (ctx); auto c = BN_CTX_get (ctx);
|
||||||
|
auto d = BN_CTX_get (ctx);
|
||||||
|
auto da = BN_CTX_get (ctx); auto cb = BN_CTX_get (ctx);
|
||||||
|
auto tmp1 = BN_CTX_get (ctx); auto tmp2 = BN_CTX_get (ctx);
|
||||||
|
unsigned int swap = 0;
|
||||||
|
auto bits = BN_num_bits (n);
|
||||||
|
while(bits)
|
||||||
|
{
|
||||||
|
--bits;
|
||||||
|
auto k_t = BN_is_bit_set(n, bits) ? 1 : 0;
|
||||||
|
swap ^= k_t;
|
||||||
|
if (swap)
|
||||||
|
{
|
||||||
|
std::swap (x2, x3);
|
||||||
|
std::swap (z2, z3);
|
||||||
|
}
|
||||||
|
swap = k_t;
|
||||||
|
// a = x2 + z2
|
||||||
|
BN_mod_add(a, x2, z2, q, ctx);
|
||||||
|
// aa = a^2
|
||||||
|
BN_mod_sqr(aa, a, q, ctx);
|
||||||
|
// b = x2 - z2
|
||||||
|
BN_mod_sub(b, x2, z2, q, ctx);
|
||||||
|
// bb = b^2
|
||||||
|
BN_mod_sqr(bb, b, q, ctx);
|
||||||
|
// e = aa - bb
|
||||||
|
BN_mod_sub(e, aa, bb, q, ctx);
|
||||||
|
// c = x3 + z3
|
||||||
|
BN_mod_add(c, x3, z3, q, ctx);
|
||||||
|
// d = x3 - z3
|
||||||
|
BN_mod_sub(d, x3, z3, q, ctx);
|
||||||
|
// da = d * a
|
||||||
|
BN_mod_mul(da, d, a, q, ctx);
|
||||||
|
// cb = c * b
|
||||||
|
BN_mod_mul(cb, c, b, q, ctx);
|
||||||
|
// x3 = ( da + cb )^2
|
||||||
|
BN_mod_add(tmp1, da, cb, q, ctx);
|
||||||
|
BN_mod_sqr(x3, tmp1, q, ctx);
|
||||||
|
// z3 == x1 * (da - cb)^2
|
||||||
|
BN_mod_sub(tmp1, da, cb, q, ctx);
|
||||||
|
BN_mod_sqr(tmp2, tmp1, q, ctx);
|
||||||
|
BN_mod_mul(z3, x1, tmp2, q, ctx);
|
||||||
|
// x2 = aa * bb
|
||||||
|
BN_mod_mul(x2, aa, bb, q, ctx);
|
||||||
|
// z2 = e * (aa + a24 * e)
|
||||||
|
BN_mod_mul(tmp1, a24, e, q, ctx);
|
||||||
|
BN_mod_add(tmp2, aa, tmp1, q, ctx);
|
||||||
|
BN_mod_mul(z2, e, tmp2, q, ctx);
|
||||||
|
}
|
||||||
|
if (swap)
|
||||||
|
{
|
||||||
|
std::swap (x2, x3);
|
||||||
|
std::swap (z2, z3);
|
||||||
|
}
|
||||||
|
// x2 * (z2 ^ (q - 2))
|
||||||
|
BN_set_word(tmp1, 2);
|
||||||
|
BN_sub(tmp2, q, tmp1);
|
||||||
|
BN_mod_exp(tmp1, z2, tmp2, q, ctx);
|
||||||
|
BIGNUM * res = BN_new (); // not from ctx
|
||||||
|
BN_mod_mul(res, x2, tmp1, q, ctx);
|
||||||
|
BN_CTX_end (ctx);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ed25519::ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
||||||
|
{
|
||||||
|
BIGNUM * p1 = DecodeBN<32> (p);
|
||||||
|
uint8_t k[32];
|
||||||
|
memcpy (k, e, 32);
|
||||||
|
k[0] &= 248; k[31] &= 127; k[31] |= 64;
|
||||||
|
BIGNUM * n = DecodeBN<32> (k);
|
||||||
|
BIGNUM * q1 = ScalarMul (p1, n, ctx);
|
||||||
|
EncodeBN (q1, buf, 32);
|
||||||
|
BN_free (p1); BN_free (n); BN_free (q1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ed25519::ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
||||||
|
{
|
||||||
|
BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
|
||||||
|
uint8_t k[32];
|
||||||
|
memcpy (k, e, 32);
|
||||||
|
k[0] &= 248; k[31] &= 127; k[31] |= 64;
|
||||||
|
BIGNUM * n = DecodeBN<32> (k);
|
||||||
|
BIGNUM * q1 = ScalarMul (p1, n, ctx);
|
||||||
|
EncodeBN (q1, buf, 32);
|
||||||
|
BN_free (p1); BN_free (n); BN_free (q1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed25519::ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey)
|
void Ed25519::ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey)
|
||||||
|
|
|
@ -75,7 +75,8 @@ namespace crypto
|
||||||
EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const;
|
EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const;
|
||||||
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
|
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
|
||||||
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
|
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
|
||||||
void Mul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number
|
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
|
||||||
|
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
|
||||||
|
|
||||||
bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const;
|
bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const;
|
||||||
void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const;
|
void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const;
|
||||||
|
@ -99,6 +100,9 @@ namespace crypto
|
||||||
BIGNUM * DecodeBN (const uint8_t * buf) const;
|
BIGNUM * DecodeBN (const uint8_t * buf) const;
|
||||||
void EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const;
|
void EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const;
|
||||||
|
|
||||||
|
// for x25519
|
||||||
|
BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
BIGNUM * q, * l, * d, * I;
|
BIGNUM * q, * l, * d, * I;
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace transport
|
||||||
// x25519 between rs and priv
|
// x25519 between rs and priv
|
||||||
uint8_t inputKeyMaterial[32];
|
uint8_t inputKeyMaterial[32];
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
i2p::crypto::GetEd25519 ()->Mul (rs, m_ExpandedPrivateKey, inputKeyMaterial, ctx); // rs*priv
|
i2p::crypto::GetEd25519 ()->ScalarMul (rs, m_ExpandedPrivateKey, inputKeyMaterial, ctx); // rs*priv
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
// temp_key = HMAC-SHA256(ck, input_key_material)
|
// temp_key = HMAC-SHA256(ck, input_key_material)
|
||||||
uint8_t tempKey[32]; unsigned int len;
|
uint8_t tempKey[32]; unsigned int len;
|
||||||
|
@ -87,8 +87,7 @@ namespace transport
|
||||||
RAND_bytes (key, 32);
|
RAND_bytes (key, 32);
|
||||||
i2p::crypto::Ed25519::ExpandPrivateKey (key, m_ExpandedPrivateKey);
|
i2p::crypto::Ed25519::ExpandPrivateKey (key, m_ExpandedPrivateKey);
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
auto publicKey = i2p::crypto::GetEd25519 ()->GeneratePublicKey (m_ExpandedPrivateKey, ctx);
|
i2p::crypto::GetEd25519 ()->ScalarMulB (m_ExpandedPrivateKey, pub, ctx);
|
||||||
i2p::crypto::GetEd25519 ()->EncodePublicKey (publicKey, pub, ctx);
|
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue