Potential ECC signing optimization: optional blinding in ecc_sign_hash_internal #798
Labels
No labels
bug
duplicate
enhancement
feature
help wanted
improve API
invalid
needs documentation
not-planned
rtfm
stale
support
wishlist
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libtom/libtomcrypt#798
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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.Thanks for your report, but ECC implementations w/o blinding are generally considered vulnerable to side-channel attacks nowadays.
So I don't think disabling it should be supported.
We still provide a vulnerable
ltc_ecc_mulmod()insrc/pk/ecc/ltc_ecc_mulmod.cwhich is disabled by default ... RSA blinding can also be disabled ... so I kind of see the point of @headscott but TBH I'm not sure whether we should really have all those knobs ...I agree that having too many knobs can be undesirable, but I think this one is worth having.
The main argument for me is that this is an explicit security/performance trade-off, not just a tuning option. Blinding provides additional side-channel protection, while disabling it can significantly reduce the cost of ECC signing. Since RSA already exposes the same kind of choice, having an equivalent ECC option also makes the behavior more consistent.
I’d keep blinding enabled by default, so there’s no security regression for existing users, and make the opt-out an explicit build-time choice for applications where the side-channel threat model is different.
So IMO
LTC_ECC_BLINDINGis a reasonable knob, whereas I’d agree that adding knobs for purely micro-optimization would probably be too much.@headscott what's the application where signing is too slow currently?
I think there are a few practical use cases where having the option to disable ECC blinding could be useful.
For example, applications that generate a large number of signatures may benefit from the reduced computational cost, especially when signing performance is relevant and the additional side-channel protection provided by blinding is not required in their threat model.
I also see value in having the option for benchmarking and comparative analysis. Being able to run the same implementation with and without blinding makes it easier to quantify the actual performance overhead and compare it with other ECC implementations.
From a development and debugging perspective, having the two modes available could also be useful when investigating performance regressions or trying to isolate where the computational overhead comes from.
Of course, I would consider ECC blinding the safer default. The option to disable it would mainly be useful for applications where the threat model permits it, or for controlled benchmarking/testing environments.
Premptively reducing security "in case someone needs to go faster" doesn't seem like a good way to design a crypto library!
Additionally I guess that this would be another case of YAGNI.
Still I can see the reasoning behind what @headscott is saying.
IMO we should first add the option
LTC_ECC_BLINDINGand in a separate PR remove all those knobs which would reduce security altogether, so whoever may need this can fork the library from before that change and maintain their own version. wdyt?That's a good idea. This should be well documented then.
In that case please give it more discouraging name like
LTC_ECC_DANGEROUS_INSECURE_UNBLINDEDSince we already have
LTC_RSA_BLINDINGand we're going to remove the option shortly after introducing it, I don't see a reason why we shouldn't call itLTC_ECC_BLINDING... or we also rename the RSA option toLTC_RSA_DANGEROUS_INSECURE_UNBLINDED.If we really do want to suppot these I am for
LTC_ECC_DANGEROUS_INSECURE_UNBLINDED+LTC_RSA_DANGEROUS_INSECURE_UNBLINDED