Skip to content

Conversation

@JulienBeg
Copy link
Contributor

Code, test and documentation for MGL.

Usefull shortcut formula to prove security bounds for masked implementation in terms of mutual information

@cla-bot cla-bot bot added the cla-signed label Oct 6, 2025
Copy link
Contributor

@cassiersg cassiersg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @JulienBeg

I have a few questions for you:

  • In phi_inv, it would be good to fix once an for all the number of iterations if we can achieve complete numerical convergence for all floats in the domain with a small number of iterations, is it feasible?. If that's not reasonable, we should rather parameterize by a limit on iteration step size or bound on abs(phi(x)).
  • In the tests, would it make sense to add other group orders (maybe extremes like 2 and a much larger one), cases with more shares, and cases with MI very close to the borders of phi?
  • I'm not sure how the function should be named. mrs_gerber_lemma feels very long. Maybe we can shorten it to mgl? Or maybe a more "application-oriented" name would be better for user (e.g.,mi_sharing)?

Finally, a few nitpicks:

  • A small comment explaining the relationship between the formulas of the paper and the phi function would be nice. Also, I don't get why it's named "DFT of the binary entropy".
  • base: would it make sense to link it to the group order?
  • For all MI_* variables, please use mi_* (we generally use that naming in scalib).
  • For the internal functions phi*, we can remove the asarray since we control the parameter type.
  • In the tests, please use numpy random generator API see this example - this improves test reproductibility.
  • Divide-by-0 warnings should be silenced where they are expected see here.

return np.where(y > 0, np.where(y < np.log(2), x, 1), 0)


def mrs_gerber_lemma(MI_shares: float, group_order: int, base=2) -> float:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MI_shares isn't a float (should be npt.ArrayLike), the return type as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed I will correct that

----------
MI_shares : array_like, f64
Mutual information for each share. Array must be of shape ``(ns,nv)`` where
``ns`` is the number of shares, ``nv`` the number of sensitive values.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ns is used throughout SCALib to refer to trace length, I would prefer another name. Maybe n_shares?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n_shares sounds good

Upper bound on the mutual information for all nv sensitive values based on Mrs Gerber's Lemma
"""

MI_shares = np.asarray(MI_shares)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want an explicit dtype=np.float64 here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I will explicit it

@JulienBeg
Copy link
Contributor Author

inversion_error

@JulienBeg
Copy link
Contributor Author

JulienBeg commented Oct 16, 2025

With niter=3 we already achieve this precision on the domain of definition so I believe we can let niter=3 be fixed in the code as you suggested !

By precision I estimate phi(phi^{-1}(y))-y. It makes sense to estimate the error in this way rather than as phi^{-1}(phi(x))-x because in the code we need phi( \prod_i phi^{-1}(mi_i) )

@JulienBeg
Copy link
Contributor Author

I am adding two group orders to the tests following your suggestion:

  1. group_order = 2
  2. group_order = 3329 as in Kyber to test larger group

This made me think of something.

We know that the values of the mi provided to the function should be between zero and log_base(group_order).

Should we check this on the inputs and eventually raise some error if the condition is not respected @cassiersg ?

@cassiersg
Copy link
Contributor

Should we check this on the inputs and eventually raise some error if the condition is not respected @cassiersg ?

Good idea, a ValueError would be a good fit.

@cassiersg
Copy link
Contributor

Also, I we're anyway pulling scipy in, can we use its implementation of the Halley method for phi_inv ? It might not change anything except reduce the amount of code we have to maintain...

@cassiersg cassiersg mentioned this pull request Oct 16, 2025
@JulienBeg
Copy link
Contributor Author

Since we cannot vectorize the Halley's method from scipy (the function is different from every input), should I unvectorize the function or do we keep it as is mentioning we implement it ourselves to keep it vectorized ?

@JulienBeg
Copy link
Contributor Author

"A small comment explaining the relationship between the formulas of the paper and the phi function would be nice. Also, I don't get why it's named "DFT of the binary entropy"." ===> I added a reference to an article equation to clarify this point

@JulienBeg
Copy link
Contributor Author

I use a mak instead of numpy where to avoid the divide by zero warning in the inversion

@JulienBeg
Copy link
Contributor Author

base: would it make sense to link it to the group order?

I do not see a link. Do you have a precise idea in mind ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants