Clear scalar variables computed from scalar in secp256k1_ecmult_const#1885
Clear scalar variables computed from scalar in secp256k1_ecmult_const#1885niooss-ledger wants to merge 2 commits into
secp256k1_ecmult_const#1885Conversation
Function secp256k1_ecdh performs an ECDH computation and clears some intermediate values from the stack before returning. This function calls secp256k1_ecmult_const, which does not clear anything. Clear the scalar variables computed from the scalar operand in secp256k1_ecmult_const.
|
Thanks for a PR!
I think clearing is cheap enough so that we'd prefer to add on the side of caution here and clear all variables that depend on |
Some temporary variables in secp256k1_ecmult_const depends on few bits of the scalar. Clear them as well.
|
Thanks for your quick review! I added a commit which clears the variables I mentioned. I ran the test suite ( I also took a look at the generated assembly code on x86_64, and it seemed reasonable: By the way, to reduce the use of stack variables, |
| ECMULT_CONST_TABLE_GET_GE(&t, pre_a_lam, bits2); | ||
| secp256k1_memclear_explicit(&bits2, sizeof(bits2)); | ||
| secp256k1_gej_add_ge(r, r, &t); | ||
| secp256k1_ge_clear(&t); |
There was a problem hiding this comment.
nit: in theory it should be slightly faster to do the stack clearing only once at the last loop iteration (i.e if group == 0) rather than repeatedly, but practically even with the current code there seems to be no measurable slow-down compared to master (bench_ecmult shows 19.2us for ecmult_const for both branches on my machine), so seems fine as-is
There was a problem hiding this comment.
Actually, as compilers are free to unroll the loop for (group = ECMULT_CONST_GROUPS - 1; group >= 0; --group) and allocate local variables in different places for each iteration, it is a bit unsound to do if (group == 0) { /* clear variables */ }.
If calling clear functions several times is an issue, it will make more sense to move the relevant variables (t, neg_y...) outside of the loop and to clear them after the loop. I did not do this, as I wanted to keep the changes small.
There was a problem hiding this comment.
Ah, good point, the if (group == 0) { ... } proposal was a bit half-baked. I agree that moving variables outside of the loop would be preferred (in the hypothetical case that the multiple clears were indeed an issue).
Hello,
Function
secp256k1_ecdhperforms an ECDH computation and clears some intermediate values from the stack before returning:secp256k1/src/modules/ecdh/main_impl.h
Lines 70 to 74 in 68b45fd
This function calls
secp256k1_ecmult_const, which does not clear anything.Clear the scalar variables computed from the scalar operand in
secp256k1_ecmult_const.N.B. After this PR, some stack variables still hold values related to scalar
q. For example: macroECMULT_CONST_TABLE_GET_GEuses a temporary variablesecp256k1_fe neg_ywhich value comes from some bits of the scalar ; aforloop uses a temporary pointsecp256k1_ge twhich is never cleared ; variablesunsigned int bits1andunsigned int bits2are not cleared, even though the compiler may choose to put them in registers instead of the stack. Nonetheless these remaining variables do not seem to enable reconstructing the value of input scalarq(contrary tos,v1,v2, whose values could be used to reconstructq). I therefore believe it is all right to limit the clearing to what this Pull Request adds.