Description
While reviewing ecc_sign_hash_internal, I noticed that the calculation of s = (e + xr) / k performs several additional modular multiplications because a random blinding value b is applied to k.
The current implementation contains:
/* find s = (e + xr)/k */
if ((err = ltc_mp_mulmod(pubkey.k, b, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = kb */
if ((err = ltc_mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/kb */
if ((err = ltc_mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */
if ((err = ltc_mp_mulmod(pubkey.k, s, p, s)) != CRYPT_OK) { goto error; } /* s = xr/kb */
if ((err = ltc_mp_mulmod(pubkey.k, e, p, e)) != CRYPT_OK) { goto error; } /* e = e/kb */
if ((err = ltc_mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e/kb + xr/kb */
if ((err = ltc_mp_mulmod(s, b, p, s)) != CRYPT_OK) { goto error; } /* s = b(e/kb + xr/kb) = (e + xr)/k */
Algebraically, the blinding factor cancels out:
kb = k * b
1 / kb = 1 / (k * b)
b * ((e / kb) + (xr / kb))
= b * ((e + xr) / (k * b))
= (e + xr) / k
Without blinding, the calculation could therefore be reduced to:
/* find s = (e + xr)/k */
if ((err = ltc_mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */
if ((err = ltc_mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; }
if ((err = ltc_mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
if ((err = ltc_mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */
This reduces the number of ltc_mp_mulmod() calls from five to two.
However, since b is used as a blinding value, simply removing it would also cause ltc_mp_invmod() to operate directly on the secret ephemeral scalar k. Therefore, I would not suggest removing the blinding unconditionally.
Instead, would it make sense to introduce an optional LTC_ECC_BLINDING configuration define, similar in concept to the existing configurable LTC_RSA_BLINDING support?
For example:
#ifdef LTC_ECC_BLINDING
/* existing blinded implementation */
#else
/* simplified implementation without blinding */
#endif
This could allow applications that require the additional side-channel protection to keep ECC blinding enabled, while applications where this protection is not required could avoid the additional modular multiplications.
Question
Could someone confirm whether the simplified calculation is mathematically equivalent for all supported ECC curves and whether introducing an LTC_ECC_BLINDING configuration option would be a reasonable approach?
If so, it may be possible to reduce the computational cost of ecc_sign_hash_internal when ECC blinding is disabled, while retaining the current blinded implementation for applications that require the additional side-channel protection.
Description
While reviewing
ecc_sign_hash_internal, I noticed that the calculation ofs = (e + xr) / kperforms several additional modular multiplications because a random blinding valuebis applied tok.The current implementation contains:
Algebraically, the blinding factor cancels out:
Without blinding, the calculation could therefore be reduced to:
This reduces the number of
ltc_mp_mulmod()calls from five to two.However, since
bis used as a blinding value, simply removing it would also causeltc_mp_invmod()to operate directly on the secret ephemeral scalark. Therefore, I would not suggest removing the blinding unconditionally.Instead, would it make sense to introduce an optional
LTC_ECC_BLINDINGconfiguration define, similar in concept to the existing configurableLTC_RSA_BLINDINGsupport?For example:
This could allow applications that require the additional side-channel protection to keep ECC blinding enabled, while applications where this protection is not required could avoid the additional modular multiplications.
Question
Could someone confirm whether the simplified calculation is mathematically equivalent for all supported ECC curves and whether introducing an
LTC_ECC_BLINDINGconfiguration option would be a reasonable approach?If so, it may be possible to reduce the computational cost of
ecc_sign_hash_internalwhen ECC blinding is disabled, while retaining the current blinded implementation for applications that require the additional side-channel protection.