Van: Mehdi <mehdi.t...@normalesup.org>
naar: pqc-comments <pqc-co...@nist.gov>
CC: pqc-forum <pqc-...@list.nist.gov>
datum: woensdag 19 juli 2023 8:23 CEST
Onderwerp: [pqc-forum] Re: Round 1 (Additional Signatures) OFFICIAL COMMENT: EagleSign
--
You received this message because you are subscribed to the Google Groups "pqc-forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pqc-forum+...@list.nist.gov.
To view this discussion on the web visit https://groups.google.com/a/list.nist.gov/d/msgid/pqc-forum/ZLeBSPnwt9lJ6y9l%40phare.normalesup.org.
To view this discussion on the web visit https://groups.google.com/a/list.nist.gov/d/msgid/pqc-forum/339184993.13469266.1689758386190.JavaMail.zimbra%40cwi.nl.
Hi M. Tibouchi,
Thanks for your analysis.
Simply, your attack is NOT correct (at least for your current version), because you set q=256.
Note that q is just used for security analysis in Sage code and it is not a parameter in the specification and in the c-language reference implementation. In Sage code, we test different values of q to do security analysis and determine the concrete security level. A smaller q means smaller amount of noise than designed is added. The hardness of eMLE 2.0 depends on both dimension and the amount of noises, a difference from lattice problem.
As mentioned in the specification, when q=256, the attack code in our submitted package (adapted from Panny’s attack) is 100%, better than your 80%. Different values of q is discussed in Section 5.3.1 of the specification. Our attack code actually exhaustively search your “a”; so I think your attack has been covered in our attack analysis and security estimation.
Also note that in Table 2 of our specification , the norm of k1 is usually above 11000 for n=64; not “> |k'_1| \approx 1300” as you said in your first email.
If we use q=2^20 to allow all noises as designed in the specification, the result of your attack on my machine is like this, 0% success rate, run twice:
Attack against eMLE-Sig 2.0 keys
--------------------------------
Precompute key-independent reduction:
| ...done
Instance 1/25:
| x1 = (0, 4, 3, -4, 0, -1, 0, 2, 2, 4, 4, -3, -3, -4, -4, ...)
| x2 = (2, 0, -1, 3, -1, 0, 0, 2, 3, -3, 0, -2, 4, 0, -2, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 2/25:
| x1 = (4, 0, -1, 4, 4, 2, -4, -1, 3, -2, -4, -1, -4, 4, 1, ...)
| x2 = (2, 4, 2, -4, 4, -2, -3, -4, -3, 1, -1, 2, 3, -4, -1, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 3/25:
| x1 = (-2, -2, 0, -3, -4, -1, 1, -1, -1, -1, -4, -4, -4, -4, -1, ...)
| x2 = (2, -2, -3, 0, -2, 3, -3, 4, 3, 1, 3, -3, -2, 1, 3, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 4/25:
| x1 = (1, -3, 2, 4, -2, 0, 1, 3, 2, -4, -2, 1, 4, 3, -2, ...)
| x2 = (0, -2, 1, -4, -3, 0, -3, 2, -3, -2, 0, 1, -4, 3, -3, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 5/25:
| x1 = (4, -2, 4, -1, -2, -3, -3, 2, -1, 0, 3, -2, 0, 0, 3, ...)
| x2 = (0, -2, 4, -2, -2, -3, -2, 1, -2, -3, -3, -2, 0, 3, 1, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 6/25:
| x1 = (2, -3, 0, 4, 1, -4, 1, 3, 2, 3, -4, 0, -1, -1, 3, ...)
| x2 = (-3, 0, 4, -4, -4, -1, -1, 3, 2, 0, 4, -4, -4, -4, 0, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 7/25:
| x1 = (-3, -2, 1, -2, 0, 0, 2, 1, 4, 2, -4, -2, -2, 2, 2, ...)
| x2 = (2, -1, 4, -1, -1, -4, 3, 3, -4, 0, 4, 3, -1, -1, -4, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 8/25:
| x1 = (-4, 1, -3, 4, 3, 0, -4, 3, 1, 1, 0, 2, -2, -1, 3, ...)
| x2 = (4, 2, -4, 3, 4, 4, 2, -3, 2, -2, 1, -1, -1, 0, -2, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 9/25:
| x1 = (-2, -1, 2, -2, -1, 1, 2, -1, -2, -2, 0, 4, 4, 1, 4, ...)
| x2 = (4, -1, -4, -4, -2, -3, 3, 1, -1, -3, 4, 3, -4, -2, -4, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 10/25:
| x1 = (2, -4, 0, 0, 1, 3, 3, 1, 4, -4, 3, 2, 2, 1, -3, ...)
| x2 = (-1, -4, -1, 3, -2, -4, -3, 4, -1, -3, 2, -2, -4, 3, 1, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 11/25:
| x1 = (3, -4, 4, -4, -1, 1, 3, 0, 4, -4, -4, 3, -1, 2, -4, ...)
| x2 = (0, -4, -2, -4, 1, 2, -1, -3, -4, 3, 3, 0, 3, -3, 4, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 12/25:
| x1 = (-3, 1, 4, 2, 4, -4, 1, -4, -2, 4, 0, -2, -1, -3, 1, ...)
| x2 = (-1, 4, -1, 0, 3, -4, -2, -4, 3, -2, -3, 1, -1, 3, 0, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 13/25:
| x1 = (-4, -4, 2, -3, -1, 1, 0, -1, 3, 1, -3, -3, -2, -3, -4, ...)
| x2 = (1, 4, 1, 4, -2, -3, -2, -3, -3, -1, 2, 3, -1, 3, -1, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 14/25:
| x1 = (4, 1, -1, 1, 3, 1, 2, 4, -2, -4, -2, -1, 4, -1, 4, ...)
| x2 = (1, -3, -1, -3, 1, -4, 2, 3, -2, -4, -2, -1, 0, -2, -1, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 15/25:
| x1 = (3, 3, -2, 4, 2, -1, 3, 2, -1, -4, 0, -3, -2, 0, 4, ...)
| x2 = (-1, 0, -1, 4, -1, 3, -4, 3, -4, -3, 1, 2, -2, -1, -4, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 16/25:
| x1 = (-4, 4, 2, 3, -3, 1, -1, -3, 4, -2, -2, -1, 4, 3, -4, ...)
| x2 = (1, 0, 1, -4, 4, 2, -1, -2, -1, 2, 3, -1, -4, 3, 2, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 17/25:
| x1 = (-3, 0, 1, 2, 2, -2, 1, -1, 1, -1, -1, 4, -1, -4, -2, ...)
| x2 = (-4, 4, 2, 1, -4, -1, -4, 0, -1, 1, -4, 4, -1, 2, 4, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 18/25:
| x1 = (-2, 1, -1, -4, 3, -4, -2, 3, 3, 1, -4, -2, 0, 2, 2, ...)
| x2 = (-4, 3, -3, 3, 0, 4, 3, 3, -4, 2, 4, 0, -3, 4, -3, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 19/25:
| x1 = (-2, 4, -3, -1, 2, -1, -4, 1, 2, 1, 4, 4, 2, -3, -4, ...)
| x2 = (0, -1, -2, 0, -1, 0, 4, -4, 1, 1, 2, -2, -3, 3, 0, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 20/25:
| x1 = (0, 4, 0, -3, -3, 2, 2, -1, -3, -2, -3, -4, 2, 4, 0, ...)
| x2 = (-2, -4, 3, 2, 2, -4, -4, -1, 3, 3, 3, 2, -1, 2, -4, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 21/25:
| x1 = (4, 2, -3, 3, -2, 2, -3, 2, -4, -1, 4, 3, 1, 0, 2, ...)
| x2 = (4, -2, 0, 1, -2, 2, -1, 3, 3, 0, 3, 0, -4, 4, 2, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 22/25:
| x1 = (-1, 1, -1, 4, -3, -1, -2, -3, 3, -2, 3, 2, 2, -3, 0, ...)
| x2 = (-1, -1, 3, -2, 1, 2, -2, -3, 0, -3, -3, 2, -1, 2, -4, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 23/25:
| x1 = (-3, 1, -4, -3, 0, -3, 3, 3, -2, 1, 4, 3, 4, 4, 2, ...)
| x2 = (2, 0, -4, -4, -4, 0, 3, 1, -1, -3, -2, 4, -3, -4, 2, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 24/25:
| x1 = (2, -4, 4, -3, -4, -1, 2, -2, 3, 0, 3, 1, -2, 0, -4, ...)
| x2 = (-1, 4, -3, 3, 4, -4, 3, -3, 4, -1, 1, 1, 4, -2, -1, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
Instance 25/25:
| x1 = (3, 3, -1, -3, -3, 3, -2, 4, 2, 4, -1, -1, -3, 1, 1, ...)
| x2 = (4, -2, 4, 4, -1, 1, -2, 2, 1, 1, 3, 2, -1, -3, -4, ...)
K0: 6975 5096
| x1 recovery failed
K0: 6975 5096
| x2 recovery failed
0/50 correct recoveries (0.0% success rate)
Regards,
Dongxi Liu
--
You received this message because you are subscribed to the Google Groups "pqc-forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pqc-forum+...@list.nist.gov.
To view this discussion on the web visit https://groups.google.com/a/list.nist.gov/d/msgid/pqc-forum/ZLivEkxdLPjsUNVS%40phare.normalesup.org.
Hi M. Tibouchi,
Your leakage attack works. Thanks for further analysis.
Regards,
Dongxi Liu
Hi Lorenz, Hi M. Tibouchi,
Thanks for your attacks.
eMLE-Sig 2.0 has been revised to address the attacks.
The major revision is summarized below. Welcome further analysis (from anyone).
======================================================
1. Leakage attack
[current] s = x1*c1 + x2*c2 + y
[revised] s = x1*c1 + x2*c2 + (c1+c2)*y
The leakage attack now finds x1-x2 (checked with Tibouchi’s code), no longer individual x1 and x2. So one of x1 or x2 has to be guessed for being able to forge signatures. Together with the revision below, there are about 380 bits to guess for level 1.
2. Lattice reduction attack
The revision is to aggregate public keys and share a new secret z across two eMLE values in a public key.
—Private key
[current] x1, x2
[revised] (x1, x1’), (x2, x2’), z
—Public key
[current] h1 = eMLE(G, x1, G[1]), h2 = eMLE(G, x2, G[1])
[revised] h1 = eMLE(G, x1, G[1]+z)+ eMLE(G’, x1’, 0), h2 = eMLE(G, x2, G[1]+z) + eMLE(G’, x2’, 0)
G[1]+z is embedded into all layers. Elements of z are from 0 to p[2]-1.
The shared z can be removed by h1-h2. But by this, at the best case the attack recovers x1-x2, and x1’-x2’ (the same result as leakage attack). One of (x1, x1’) or (x2, x2’) needs to be guessed.
—Signing
[current] (u, s), where u = eMLE(G, y, c1’+c2’), s = x1*c1 + x2*c2 + y
[revised] (u, s, s’), where u = eMLE(G, y, c1’+c2’-z) + eMLE(G’, y’, 0),
s = x1*c1 + x2*c2 + (c1+c2)*y,
s’ = x1’*c1 + x2’*c2 + (c1+c2)*y’
3. Sizes of public key and signature for the revised version
p[2] changes from 2^26 to 2^22. New sizes are listed below (bigger signature, but smaller pk).
[level 1] pk: 2*22 * 64/8 = 352 bytes, sig: (22 + 2*9)*64/8 = 320 bytes
[level 3] pk: 2*24 * 96/8 = 576 bytes, sig: (24 + 2*10)*96/8 = 528 bytes
[level 5] pk: 2*26 * 128/8 = 832 bytes, sig: (26 + 2*10)*128/8 = 736 bytes
The revised sage implementation is available at:
https://gitlab.com/raykzhao/emle-sig/-/blob/main/Extra/sage-code/impl-gen.sage
https://gitlab.com/raykzhao/emle-sig/-/blob/main/Extra/sage-code/correctness.sage
======================================================
Regards
Dongxi Liu
From: 'Lorenz Panny' via pqc-forum <pqc-...@list.nist.gov>
Date: Sunday, 23 July 2023 at 6:25 pm
To: pqc-co...@nist.gov <pqc-co...@nist.gov>
Cc: pqc-...@list.nist.gov <pqc-...@list.nist.gov>
--
You received this message because you are subscribed to the Google Groups "pqc-forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pqc-forum+...@list.nist.gov.
To view this discussion on the web visit https://groups.google.com/a/list.nist.gov/d/msgid/pqc-forum/20230723102537.3994151a%40l4.
Hi M. Tibouchi,
> Please share the code used to arrive at this conclusion.
Here are the files:
https://gitlab.com/raykzhao/emle-sig/-/blob/main/Extra/sage-code/leakage/impl.c
https://gitlab.com/raykzhao/emle-sig/-/blob/main/Extra/sage-code/leakage/test_attack.c
[impl.c] the sign function is revised to implement “x1*c1 + x2*c2 + (c1+c2)*y”, with y’s elements limited from -4 to 4.
[test_attack.c] your file, with modification to recover also x2zrec, and then print x1z, x2z, x1zrec, x2zrec, x1z-x2z, x1zrec – x2zrec.
You just put these two files into your package; all other steps are the same.
Thanks for your checking. I will answer your other questions after this.
Regards,
Dongxi
From: Mehdi Tibouchi <mehdi.t...@normalesup.org>
Date: Wednesday, 2 August 2023 at 4:12 pm
To: Liu, Dongxi (Data61, Marsfield) <Dongx...@data61.csiro.au>
Hi M. Tibouchi,
Your attack works. Thanks for checking.
Regards,
Dongxi Liu
Hi M. Tibouchi,
Based on your observation “not updating the random seed”, the following solution passes leakage attack.
In the attacked version, we have s = c1*x1+c2*x2 + (c1+c2)*y, where y is randomly sampled. Now we let y = y0 + y1, where y0 is randomly sampled, but y1 is selected from a small number of cases (4 in the test), which can be sampled as part of the private key or derived from private key. y1 simulates the effect of “not updating the random seed”.
Here is the updated implementation file:
https://gitlab.com/raykzhao/emle-sig/-/blob/main/Extra/sage-code/leakage-v1/impl.c
Attack file is the same.
Thanks for your observation and further checking.
Regards,
Dongxi Liu
Dear Dr. Tibouchi,
Thanks for your time and insight to analyse eMLE-Sig last year. Your analysis is valid.
https://gitlab.com/raykzhao/emle-sig/-/tree/main/Extra/sage-code/Updates2024Feb
The updated signature still incudes the component s = c1*x1 + c2*x2 + …. But in the updated scheme, c1[i] and c2[i] are entangled.
c1[i] takes the value either 0 or 1. If c1[i] =0, then c2[i] must be 1. If c1[i] =1, then c2[i] = -1.
More detailed analysis is in the Section 4.1 of the PDF document in the above folder, with leakage.sage to confirm the analysis there.
The dimension parameter n is increased from 64 to 128 for the first security level; a new secret z shared between h1 and h2 requires h1 and h2 must be embedded in one lattice to attack, leading to a bigger lattice to reduce than before even for the same n.
The modulus p[d-1] decreases from 2^26 in the submitted version to 6083 in the new version to make a more dense system. More details are in the PDF document.
The signature sizes become bigger than the submitted version.
Level 1: pk size = 416, sig size = 576 bytes
Level 3: pk size = 672, sig size = 936 bytes
Level 5: pk size = 896, sig size = 1280 bytes
Welcome any comments and questions!
Dear All,
The c implementation of updated eMLE-Sig 2.0 is available at: https://gitlab.com/raykzhao/emle-sig
The performance evaluation is included in the updated document here:
https://gitlab.com/raykzhao/emle-sig/-/tree/main/Extra/sage-code/Updates2024Feb
Thanks for comments.
Regards,
Dongxi Liu
From:
pqc-...@list.nist.gov <pqc-...@list.nist.gov> on behalf of Liu, Dongxi (Data61, Marsfield) <Dongx...@data61.csiro.au>
Date: Saturday, 17 February 2024 at 6:26 pm
To: Mehdi Tibouchi <mehdi.t...@normalesup.org>
Cc: Lorenz Panny <l.s....@tue.nl>, pqc-co...@nist.gov <pqc-co...@nist.gov>, pqc-...@list.nist.gov <pqc-...@list.nist.gov>
Subject: Re: [pqc-forum] Round 1 (Additional Signatures) OFFICIAL COMMENT: eMLE-Sig 2.0
Dear Dr. Tibouchi,
Thanks for your time and insight to analyse eMLE-Sig last year. Your analysis is valid.
1. eMLE-Sig has been thoroughly updated to address all attacks. The updated document, sage implementation, and tests are included in the following folder. No c implementation is available yet.
https://gitlab.com/raykzhao/emle-sig/-/tree/main/Extra/sage-code/Updates2024Feb
2. Addressing leakage attack
The updated signature still incudes the component s = c1*x1 + c2*x2 + …. But in the updated scheme, c1[i] and c2[i] are entangled.
c1[i] takes the value either 0 or 1. If c1[i] =0, then c2[i] must be 1. If c1[i] =1, then c2[i] = -1.
More detailed analysis is in the Section 4.1 of the PDF document in the above folder, with leakage.sage to confirm the analysis there.
3. Addressing lattice-based attack from the following aspects
The dimension parameter n is increased from 64 to 128 for the first security level; a new secret z shared between h1 and h2 requires h1 and h2 must be embedded in one lattice to attack, leading to a bigger lattice to reduce than before even for the same n.
The modulus p[d-1] decreases from 2^26 in the submitted version to 6083 in the new version to make a more dense system. More details are in the PDF document.
4. Sizes of signatures and public keys
To view this discussion on the web visit https://groups.google.com/a/list.nist.gov/d/msgid/pqc-forum/ME3PR01MB6919C5348D70A71FDE82310BD0532%40ME3PR01MB6919.ausprd01.prod.outlook.com.