-
Notifications
You must be signed in to change notification settings - Fork 904
[sw,cryptolib] Hardened bn.sel for internal point mult #28462
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
05dd29f
to
423d12e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, the logic looks fine to me.
Could you please have a look why the tests are failing?
This commit adds hardening for the internal scalar point multiplication. Before the shares would be combined in the main loop to decide whether 0, P or 2P should be added. This commit determines this without combining the shares. If the MSB of both shares are both 1 we want to add 2P. If only one bit is 1 we want to add P. If both bits are 0 we want to add 0. In a simplified way this is done as explained below. In a first step we pick P if MSB(d0) ^ MSB(d1) is 1 and 2P otherwise. This is done as follows: p_temp0 = d0 ? (d1 ? 2P : P) : (d1 ? P : 2P) In a second step we pick between p_temp and 0. If MSB(d0) | MSB(d1) = 1 then we pick p_temp otherwise we pick 0. This is done as follows: p_temp1 = d0 ? p_temp0 : 0 p_temp2 = d1 ? p_temp0 : p_temp1 Signed-off-by: Hakim Filali <[email protected]>
423d12e
to
acc92fc
Compare
Thanks @nasahlpa ! |
thanks @h-filali this is a very helpful addition. can we please mention the impact on code size (ca. 300 Bytes?) and runtime (seem ok, ca. 30k) |
bn.lid x2, 448(x30) | ||
|
||
/* Select whether P or 2P will be stored in dmem[p_temp1]. | ||
([w21,w20], [w19,w18], [w17, w16]) <= M ? 2P : P */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
target regs were used for Q in last iteration; no horizontal leakage; no randomisation prior use required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rhanks @h-filali great work
The execution times change from
to:
The mem size goes from 96'961 to 97'233 Bytes |
Thanks @nasahlpa and @johannheyszl for leaving a review! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing the CI failure. The code looks good to me.
|
||
/* select either Q or Q_a | ||
if M: Q = ([w21,w20], [w19,w18], [w17,w16]) <= Q else: Q <= Q_a */ | ||
if M: Q_temp = ([w21,w20], [w19,w18], [w17,w16]) <= Q_a else: Q_temp <= Q */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I was a bit confused just with the comments, Q_a was not defined before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very nice, a very good change that will better protect p384! Thank you!
/* select either Q or Q_a | ||
if M: Q = ([w21,w20], [w19,w18], [w17,w16]) <= Q else: Q <= Q_a */ | ||
if M: Q_temp = ([w21,w20], [w19,w18], [w17,w16]) <= Q_a else: Q_temp <= Q */ | ||
bn.sel w16, w25, w6, M |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
w16 to w21 contained the decision P or 2P, is that overwrite safe? Could definitely be, but I wasn't sure myself
This commit adds hardening for the internal scalar point multiplication.
Before the shares would be combined in the main loop to decide whether 0, P or 2P should be added.
This commit determines this without combining the shares. If the MSB of both shares are both 1 we want to add 2P. If only one bit is 1 we want to add P.
If both bits are 0 we want to add 0.
In a simplified way this is done as explained below.
In a first step we pick P if MSB(d0) ^ MSB(d1) is 1 and 2P otherwise. This is done as follows:
p_temp0 = d0 ? (d1 ? 2P : P) : (d1 ? P : 2P)
In a second step we pick between p_temp and 0.
If MSB(d0) | MSB(d1) = 1 then we pick p_temp otherwise we pick 0. This is done as follows:
p_temp1 = d0 ? p_temp0 : 0
p_temp2 = d1 ? p_temp0 : p_temp1
Thanks to @siemen11 for implementing this for p256 and letting me draw inspiration #28248.