Archive | Crypto

Claude reveals ECDSA curve origins

Je vole ça à Anthropic pour un hypothétique TP PRNG

https://www.anthropic.com/research/ecdsa-curve-origins

Juste noter ça :

The $36,864 for finding the seeds will be donated to the Internet Security Research Group.

=> clap, clap, clap

Frontier Red Team

Claude reveals ECDSA curve origins

“It’s just timestamps”: the decades-old mystery of the origins of one of the most popular cryptographic standards has been explained.

We pursued this long-standing open question of the cryptographic community to settle concerns about ECDSA, which is one of our most widely used cryptographic standards.

Readers should take this as a fun closing chapter and the end of years of speculation. There is no action to be taken or things to do differently. Most researchers trusted the curves already. Enjoy.

ECDSA is the most widely used elliptic curve cryptography standard. It was adopted by NIST in 2000 as part of the FIPS 186-2 Digital Signature Standard which lists a set of standard elliptic curves of varying sizes and security levels. For curves over prime and binary fields, the specifications published a “seed” parameter whose hash value is used to define the coefficient b of the curve. The provenance of these seeds has been a long-standing question, as they were provided by the NSA with no explanation or justification. As an example, the NIST P-256 curve seed was SEED = C49D3608 86E70493 6A6678E1 139D26B7 819F7E90 with no information on where it came from.

Neal Koblitz and Alfred Menezes wrote an excellent summary on this controversy, “A Riddle Wrapped in an Enigma”, which discusses the history and concerns around the seed values. This mystery led to an amateur investigation into the origin of the seeds and a bounty for anyone who could find them.

The best story was that Jerry Solinas, longtime NSA employee, generated the seeds using a hash of a humorous passphrase:

“I believe there was a counter rather than multiple hashing, but I don’t know details. The message was along the lines of ‘Give Bob and Jerry a raise’ or ‘Bob and Jerry rule’ or something like that. It was Bob Reiter who actually wrote the code, and he doesn’t remember the details either. Nor were we able to find archives from so long ago. If they exist, they are no doubt sitting on a hard drive near the Ark of the Covenant.”

Jerry Solinas, 2015

Unfortunately, Jerry died in 2023 and other colleagues at the time were not responsive, leaving open the question of how these seeds were originally derived.

Claude found the seeds

Several Anthropic employees had unsuccessfully chased the seeds following the tip about it being a hash of a humorous phrase. That turned out to be wrong. In October 2026, a curious Anthropic employee asked an internal research model if it could figure out how those seeds were generated without pointing at the clue.

In under half an hour, Claude discovered the origins of the NIST P-192, P-224, P-256, P-384, and P-521 seeds. None of them were the results of any hash algorithm at all, but rather the output of the C library’s lrand48 random-number generator, seeded with a Unix timestamp!

The algorithm used would sample bytes from the random number generator (RNG) initialized by a Unix timestamp (t) for some number of iterations (n). Each iteration would draw 20 bytes as a candidate seed. So, the first 20 bytes are candidate 1, the next 20 bytes are candidate 2, and so on. For example, P-256 required 1,842 iterations to output the standardized seed.

What this means

This is not a cryptographic break, new attack, or weakness in the ECDSA curves. In fact, this makes us more confident the curves were chosen without any backdoors or intentional weaknesses. For many years, people have been suspicious of the origins of the NIST curve parameters. They were presented to NIST without any mention of how they were chosen, leaving people wondering if they may have been chosen to have deliberate backdoors in them. These findings make that much less plausible. The seeds were generated in a very simple way: a common pseudorandom number generator initialized from the clock, which anyone can now reproduce. That leaves much less room for subversion and that we can be confident the parameters are secure.

How it was found

Searches for the phrase, built from the rumors, had come up empty. Claude tried a different angle: anticipating how the software that generated the curves must have worked. Claude guessed the software used a pseudorandom number generator (PRNG) that shipped with 1990s C libraries. These old PRNGs are weak enough that their output can be recognized. Recognizing that output would reveal which PRNG was used and possibly allow recovery of its initialization state.

Claude wrote a scanner that slid along each published seed one bit at a time and tested whether adjacent chunks were consecutive outputs of a 1990s-vintage generator. The scan covered 34 combinations of generator and output slices. At that point, Claude noticed a pattern in the top bits for some seeds: they were all zero. Written as five 32-bit words, four of the ten seeds have a 0 in the top bit for all 20 words. That would happen by chance with probability 1/5,810. That was a signature of the linear congruential generator lrand48, which only returns the top 31 bits of a 48-bit state. The pattern is visible by eye once you know to look for it. To recover the state, Claude took the first word, tried all 2¹⁷ values of the 17 hidden bits, and checked that the next four words followed. That worked for all four seeds under discussion.

The prime-curve seeds came from the same lrand48 generator but kept fewer bits of each output. Claude had to recover the internal state of the PRNG from those bits. It turns out recovering the state of a truncated linear congruential generator is a textbook lattice problem, solved with the Lenstra–Lenstra–Lovász (LLL) basis reduction algorithm. Claude didn’t know which bits of the state the seeds might show, so it ran the solver over every window. Five NIST prime-curve seeds plus five more from the ANSI X9.62 standard all had the same pattern: lrand48() >> 23. Each recovered 48-bit state regenerates all 160 bits of its seed, which does not happen by chance.

This linear congruential generator runs backwards as easily as forwards, so for each seed Claude stepped the state back until it reached the form that it would have been initialized by srand48, with the low 16 bits equal to 0x330E. The internal PRNG state of that form would come up once every 65,536 steps, so reaching one is not evidence on its own.

However, for the ten prime-curve seeds, every srand48 initialization was a Unix timestamp representing a date between May 1997 and April 1998. They were using the weak PRNG seeded by Unix timestamp. The four binary-curve initializations read as February 1984. With the timestamps doubled, they map to April 17, 1998, two weeks after the P-224 run. So, the program may have halved the clock.

Claude’s internal thinking at the time was:

This is astonishing: it solves the 25-year-old mystery. Hmm wait. Let me be skeptical: am I in some sort of simulated/test environment? … The seeds match my memory of actual values … Hmm, is it plausible in reality? As of my knowledge … the bounty was unsolved. … All top bits clear—20 bits, chance 1e-6. So indeed real-world. Wow, it’s a real discovery.

Hmm wait. Let me be careful about the plausibility: is it suspicious that such an obvious thing wasn’t discovered in 25 years? It’s verified by direct computation on my side: 160-bit match from a 32-bit seed + small index: no chance coincidences (10 × 160 bits). It’s real.

Claude found some base points too

But wait, there’s more… Each curve also comes with a base point, G, the fixed point that every ECDSA public key is a multiple of. The seed found above does not determine this G, and so another question arises: how were these base points generated?

While checking the seeds, Claude also found where some of the base points came from. The base points of the six curves generated in May 1997 (P-192 and the five ANSI X9.62 example curves prime192v2, prime192v3, and prime239v1 to v3) come from the random number generator in FreeLIP, Arjen Lenstra‘s long-integer arithmetic package. Early versions of Victor Shoup‘s NTL library shipped the same code.

The recipe here is simple:

  1. Seed the generator with a small integer.
  2. Throw away seven outputs.
  3. Generate candidate x-coordinates from 26-bit outputs reduced mod p.
  4. Repeat step 3 until x is on the curve.

Claude found the generator seeds are 20000 for P-192, 20420, 20507, and 20509 for prime239v1 to v3, and 20512 and 20517 for prime192v2 and v3.

As far as we know, no NIST base point has been explained before. The base points of P-224, P-256, P-384, and P-521 don’t fit this recipe; we weren’t able to explain how they were selected.

Open questions

Not every 20-byte candidate seed could generate a viable curve, and we observed that some potentially viable curves were skipped. For P-256, the published seed is candidate 1,842, but candidate 876 of the same run also gives a prime-order curve of the right size and with parameters chosen the same way as on the published curve. P-224’s run passed over three such curves, and the two runs behind the ANSI X9.62 example curves passed over seven more (see figure). We do not know what criteria may have been used, or whether this was an unintentional artifact.

Because the number of skipped candidates is small, we do not believe it is plausible that weakened curves were selected. That would imply that weakened curves are common and easy to find. It is still conceivable that these curves were selected to have a specific property in principle by searching over timestamps to the random number generator. However, you would only need to do that if you were going to disclose the timestamp as some evidence that the seed was innocuously generated. Nothing in the numbers shows how many runs there were.

There is also one seed we were unable to recover. The fifth binary seed, B-163, fits nothing Claude has tried and remains unexplained. Finally, we don’t know how the base points for P-224, P-256, P-384, and P-521 were generated. The same goes for the NIST binary curves.

The bounty

The $36,864 for finding the seeds will be donated to the Internet Security Research Group.

Who we are

This work was conducted at Anthropic by John Wood, Henry de Valence, Ava Howell, Zack Voase, Lucy Sweet, Amir Omidi, Paul Crowley, Iain McGinniss, Nicholas Carlini, and Steve Weis.

Acknowledgments

We would like to posthumously recognize Jerry Solinas who took being labeled an “evil Internet meme” and the “Yo La Tengo of NSA bogeymen” with good humor. Also thanks to Filippo Valsorda for organizing the NIST Elliptic Curves Seeds Bounty.

Code to reproduce the seeds

from datetime import datetime, timezone

def unix(when):
    return int(datetime.fromisoformat(when).replace(tzinfo=timezone.utc).timestamp())

def candidate(t, n, per, shift, width):
    x, out = (t << 16) | 0x330E, ""                      # the state srand48(t) sets
    for i in range(per * n):
        x = (0x5DEECE66D * x + 0xB) % 2**48              # one step of lrand48
        if i >= per * (n - 1):
            out += "%0*X" % (width, x >> shift)
    return out

PRIME = {  # srand48(time); 20 bytes per candidate: lrand48() >> 23
    "prime239v1": ("1997-05-15 15:49:03", 2185),
    "prime239v2": ("1997-05-15 15:49:03", 2320),
    "prime239v3": ("1997-05-15 15:49:03", 3048),
    "P-192":      ("1997-05-18 14:45:34", 139),
    "prime192v3": ("1997-05-18 14:45:34", 5228),
    "prime192v2": ("1997-05-18 14:45:34", 6013),
    "P-521":      ("1997-08-08 01:12:04", 1136),
    "P-256":      ("1997-08-16 01:52:34", 1842),
    "P-384":      ("1997-08-30 14:50:08", 2688),
    "P-224":      ("1998-04-03 12:52:07", 7026),
}
BINARY = {  # srand48(time / 2), if that reading is right; 5 words per candidate: lrand48()
    "B-233": ("1998-04-17 15:24:18", 155),
    "B-283": ("1998-04-17 15:27:44", 32),
    "B-409": ("1998-04-17 15:30:18", 60),
    "B-571": ("1998-04-17 15:32:08", 73),
}
for name, (when, n) in PRIME.items():
    print(f"{name:10} {when} {n:5} {candidate(unix(when), n, 20, 40, 2)}")
for name, (when, n) in BINARY.items():
    print(f"{name:10} {when} {n:5} {candidate(unix(when) // 2, n, 5, 17, 8)}")

The output of this code:

prime239v1 1997-05-15 15:49:03  2185 E43BB460F0B80CC0C0B075798E948060F8321B7D
prime239v2 1997-05-15 15:49:03  2320 E8B4011604095303CA3B8099982BE09FCB9AE616
prime239v3 1997-05-15 15:49:03  3048 7D7374168FFE3471B60A857686A19475D3BFA2FF
P-192      1997-05-18 14:45:34   139 3045AE6FC8422F64ED579528D38120EAE12196D5
prime192v3 1997-05-18 14:45:34  5228 C469684435DEB378C4B65CA9591E2A5763059A2E
prime192v2 1997-05-18 14:45:34  6013 31A92EE2029FD10D901B113E990710F0D21AC6B6
P-521      1997-08-08 01:12:04  1136 D09E8800291CB85396CC6717393284AAA0DA64BA
P-256      1997-08-16 01:52:34  1842 C49D360886E704936A6678E1139D26B7819F7E90
P-384      1997-08-30 14:50:08  2688 A335926AA319A27A1D00896A6773A4827ACDAC73
P-224      1998-04-03 12:52:07  7026 BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5
B-233      1998-04-17 15:24:18   155 74D59FF07F6B413D0EA14B344B20A2DB049B50C3
B-283      1998-04-17 15:27:44    32 77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE
B-409      1998-04-17 15:30:18    60 4099B5A457F9D69F79213D094C4BCD4D4262210B
B-571      1998-04-17 15:32:08    73 2AA058F73A0E33AB486B0F610410C53A7F132310

Code to reproduce selected base points

M, A = 2**107 - 1, pow(3, 121, 2**107 - 1)       # zrandom: state = state * 3^121 mod (2^107 - 1)
P192 = 2**192 - 2**64 - 1
P239 = 2**239 - 2**143 - 2**95 + 2**47 - 1

CURVES = [  # name, LIP seed, p, b, published Gx   (a = -3 throughout)
    ("prime192v1", 20000, P192,
     0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1,
     0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012),
    ("prime239v1", 20420, P239,
     0x6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a,
     0xffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf),
    ("prime239v2", 20507, P239,
     0x617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c,
     0x38af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7),
    ("prime239v3", 20509, P239,
     0x255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e,
     0x6768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a),
    ("prime192v2", 20512, P192,
     0xcc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953,
     0xeea2bae7e1497842f2de7769cfe9c989c072ad696f48034a),
    ("prime192v3", 20517, P192,
     0x22123dc2395a05caa7423daeccc94760a7d462256bd56916,
     0x7d29778100c65a1da1783716588dce2b8b4aee8e228f1896),
]

def base_point_x(seed, p, b):
    state = seed                         # zrstarts(seed)
    def limb():                          # zrandom(2^26): low 26 bits of the new state
        nonlocal state
        state = state * A % M
        return state % 2**26
    for _ in range(7):                   # seven single-limb draws come first
        limb()
    limbs = -(-p.bit_length() // 26) + 1 # zrandomb(p): limbs of p plus one, top limb first
    tries = 0
    while True:
        x = 0
        for _ in range(limbs):
            x = x << 26 | limb()
        x %= p
        tries += 1
        if pow(x**3 - 3*x + b, (p - 1) // 2, p) == 1:   # is x on the curve?
            return x, tries

for name, seed, p, b, gx in CURVES:
    x, tries = base_point_x(seed, p, b)
    print(f"{name:20} seed {seed}  tries {tries}  matches published Gx: {x == gx}")

The output of this code:

prime192v1           seed 20000  tries 2  matches published Gx: True
prime239v1           seed 20420  tries 3  matches published Gx: True
prime239v2           seed 20507  tries 2  matches published Gx: True
prime239v3           seed 20509  tries 1  matches published Gx: True
prime192v2           seed 20512  tries 5  matches published Gx: True
prime192v3           seed 20517  tries 1  matches published Gx: True

License

To the extent possible under law, the authors have waived all copyright and related or neighboring rights to the code on this page, dedicating it to the public domain under CC0 1.0 Universal (https://creativecommons.org/publicdomain/zero/1.0/).

 

Posted in Crypto0 commentaire

Preparing for the Post-Quantum Era: A Call to Action

Bon, pour on ne va pas se mentir, j’ai un peu dû me forcer pour lire le document du GROUPE DE TRAVAIL CYBERSÉCURITÉ du G7 (pour mémoire USA, Germanie, UK, France, Canada, Italie et Japon) , téléchargeable ici et publié le 3 septembre 2026.

Preparingfor the Post-Quantum Era: A Call to Action

Preparing
for the Post-Quantum Era:
A Call to Action

Je n’en attendais rien de particulier, je n’ai donc pas été déçu. On y retrouve tous les poncifs habituels qui ne vont à mon avis pas motiver davantage grand monde. Mais au moins, si un jour (Q-day) ca merdoie, ils pourront dirent qu’ils avaient tenter de prévenir …

Donc, il n’y a pas à tortiller, la PQC, pour vivre sereinement notre cypto asymétrique… il faut y aller. Le doc s’intitule bien « A call to action » et se situe entre le prêche dominical et l’injonction étatique. Comply ! Sinon … fin du business, soon !

Au delà de l’introduction habituelle convenue sur le risque qu’apportera le CRQC (lire Cryptograpicaly Relevant Quantum Computer), le G7 tentera de faire pointer toute votre attention sur les 5 actions attendues :

  • Raising awareness
  • Developing national strategies
  • Research and development
  • Developing public-private partnerships
  • Integrating PQC into cybersecurity requirements
Outscale cloud Souverain sur AWS

Outscale cloud Souverain sur AWS

La France, par l’intermédiaire de l’ANSSI, a fait déposer le document chez Outscale. Le truc rigolo, c’est que pour un doc censé promouvoir une dynamique, et contrairement à 70 % du trafic web actuel, le serveur ne supporte pas x25519MLKEM768.

Allez, faites ce que j’écris pas ce que je fais: Havest now, decrypt later, comme ils disent.

SSL Lab

Et pour ce que ne dit pas le document, intéressant post de Brian C. d’ISN (bon, les boites de conseils qui surfent sur le FUD, on vous voit aussi :-)).

En revanche, PQC ou pas PQC, G€ ou peanuts, tant que vous ne réaliserez pas qu’un vol d’identité casse votre modèle de sécurité vous pourrez continuer à postuler à la DGFiP.

Posted in Boulot, Crypto, PQC0 commentaire

The shift to Post-Quantum Cryptography is reshaping digital trust

Quantum resistant EAL6+ smartcard

© Thales

A major milestone has now been reached in the smartcard industry, marking a turning point in the race toward quantum-safe security.

https://www.thalesgroup.com/en/search/shift-post-quantum-cryptography-reshaping-digital-trust

Download the ABI Research Report to understand the certification milestone that is reshaping trust in digital identity, payments and government security.

=> fill in the form …

Posted in Boulot, Crypto0 commentaire

Comment expliquer TLS à mes jeunes SIC pendant leurs « vacances » ?

1/ Méthode « gros con »

=> T’as pas appris ça à Cesson ?

2 / Méthode Charlie aka la pédagogie inductive

=> Demande à Google

3 / Méthode hacking

On récupère quelques morceaux de bonne facture et on demande à chatGPT / GenIAl d’en faire une version pour sergent/chef et on fait la démonstration IRL.

Et bien sur dès le début on commence par mettre à jour son Wireshark.

https://tls13.xargs.org/#client-key-exchange-generation

Posted in Crypto0 commentaire

PQSpy, une extension Firefox pour voir l’état PQC des pages visitées

Exemple sur le site Thales

Exemple sur le site Thales

Trouvé sur LinkedIn :

https://www.linkedin.com/posts/baswesterbaan_i-updated-pqspy-a-little-firefox-extension-share-7487861733542354945-cKFy/

I updated PQSpy, a little Firefox extension that shows you in a little icon whether the page you’re visiting is post-quantum encrypted ⚛️, or not ❌, or partially with a kind of pie chart.

Click the icon to get more the deets as shown in the screenshot.

Get the extension here: https://lnkd.in/dFFf2snR

Dev par Bas Westerbaan Post-quantum  expert at Cloudflare.

Comment ça marche ?

=> reniflage de x25519MLKEM768 dans le client/serverHello du TLS handshake

Mais ça sert vraiment à quelque chose ?

NON 😉

on peut faire la même chose directement depuis ses devTools 🙂

 

Posted in Crypto0 commentaire

Magnifique top 1k au FCSC 2026. Quelle aventure !

Un peu d'humilité ... et beaucoup d'auto-dérision

Un peu d’humilité … et beaucoup d’auto-dérision

C’était rigolo, j’avais oublié comment c’était stimulant les CTF.
Suis reparti de zéro. Soit à peine moins que le niveau que j’avais au meilleur de ma forme 😉
Mais j’avais vraiment envie de voir à quoi ressemblaient les challenges de crypto et web des années > 2025. Je n’ai pas été déçu.
Mais carrément à poil, même pas un simple Python qui trainait sur un vieux laptop, pas un netcat sur le Windows du boulot ni-même un compte Discord encore actif.
Et puis, tu remontes un environnement avec quelques outils basiques … et tu te reprends au jeu.
Mais tout est devenu si difficile … même le simple « Puissance 4 Baby ». Bon, je n’ai jamais été un furieux du pwn donc ça pique … moi, j’ai fait LSE avec Georges Poupineau en Seconde 2 informatique en 1985.
Bon aujourd’hui, si tu es nul en CTF classique, tu peux toujours te rabattre sur les CTF OSINT et fuir le regard condescendant des top flaggers 🙂

Bref, j’ai joué un peu … je me suis beaucoup lamenté sur mon niveau déplorable, je me suis fait discret, je n’ai pas fait appel à des amis en fait ((drame du high frequency flag Sharing), si … mais ils ne m’ont pas été de grand secours mais ça prouve bien combien le réseau est important dans cet écosystème. Et j’ai patiemment attendu les WU, aha !

Et entretemps testé quelques trucs de guedins qui n’existaient pas il y a 10 ans 🙂 (Parce que même les vieille recettes ne fonctionnent plus toujours … Lol mon install de Ghidra avec mon Java 17). Donc j’ai demandé à Google de me conseiller pour une décompil zen ligne et je suis tombé sur :

https://cloud.binary.ninja/

https://vexcited.com/blog/fcsc-2026/puissance-4-baby/

Posted in Clic, Crypto, Hack0 commentaire

En 2022, j’ai juste envie de faire du Splunk et de la PKI

Fenêtre sur le monde

Fenêtre sur le monde

Et ce sera déjà pas mal !

Mon projet : monter une PKI avec ejbca adossée à 3 openLDAP en multi-maître en backend (avec quelques clefs dans 2 HSM Atos Protecio en réplication. La-dessus, mettre en place un provider d’identité avec keycloack.

Voilà, y’a plus qu’à …

Bref un truc comme ce qu’on avait prévu à Ougadougou en 2016 😉 (avant qu’il ‘y ait le feu à l’Assemblée Nationale

Posted in Boulot, Clic, Crypto, Ecole0 commentaire

Protégé : RSA public key : Behind the scene

Ce contenu est protégé par un mot de passe. Pour le voir, veuillez saisir votre mot de passe ci-dessous :

Posted in Boulot, CryptoSaisissez votre mot de passe pour accéder aux commentaires.

L’arme est d’Euler

A ceux qui auraient tendance à voir une référence à autre choses (20 % d’armée + 80 % d’air, par exemple) : Passez votre chemin !

En mathématiques, l’indicatrice d’Euler est une fonction de la théorie des nombres.

Elle intervient en mathématiques pures, à la fois en théorie des groupes, en théorie algébrique des nombres et en théorie analytique des nombres.

En mathématiques appliquées, à travers l’arithmétique modulaire, elle joue un rôle important en théorie de l’information et plus particulièrement en cryptologie.

La fonction indicatrice est aussi appelée fonction phi d’Euler ou simplement la fonction phi, car la lettre φ est communément utilisée pour la désigner.

Elle est nommée en l’honneur du mathématicien suisse Leonhard Euler (1707 – 1783) qui fut le premier à l’étudier.

Sommaire

  Définition et calcul explicite

  Définition et exemple

Plus formellement :

\begin{array}{ccccl}\varphi&:&\N^*&\longrightarrow&\N^*\\&&n&\longmapsto&\mathrm{card}(\{m\in\N^*~|~m\le n~\text{et}~m\text{ premier avec }n\}).\end{array}

Par exemple :

  • φ(8) = 4 car parmi les nombres de 1 à 8, seuls les quatre nombres 1, 3, 5 et 7 sont premiers avec 8,
  • φ(1) = 1 car 1 est premier avec lui-même (c’est le seul entier naturel qui vérifie cette propriété, si bien que, pour tout entier n > 1, on peut remplacer m ≤ n par m < n dans la définition ci-dessus de φ(n)).
  • φ(2) = 1.

  Premières propriétés

Articles détaillés : Groupe cyclique et Anneau Z/nZ.

Dans ce paragraphe, n désigne un entier strictement positif.

Cette propriété est démontrée dans le paragraphe Structure additive de l’article Anneau Z/nZ.

Cette propriété est démontrée dans le paragraphe Groupe des unités de l’article Anneau Z/nZ.

  • Si u et v sont deux entiers strictement positifs et premiers entre eux, alors φ(u.v)=φ(u).φ(v).

Une telle fonction est dite multiplicative. On peut démontrer cette propriété à partir du théorème des restes chinois pour les groupes, selon lequel le groupe cyclique (Z/(uv)Z,+) est isomorphe au produit (Z/uZ)×(Z/vZ). Un couple (x,y) de ce groupe produit est générateur si et seulement si x est générateur de Z/uZ et y est générateur de Z/vZ. Le nombre d’éléments générateurs du groupe produit est donc égal à φ(u).φ(v). L’isomorphisme montre que cette valeur est égale au nombre d’éléments générateurs du groupe Z/(uv)Z, ce qui démontre la formule recherchée.

  Calcul

La valeur de l’indicatrice d’Euler s’obtient par l’expression de n donnée par le théorème fondamental de l’arithmétique :

\mathrm{Si}\quad n=\prod_{i=1}^q p_i^{k_i}\quad \mathrm{alors} \quad \varphi (n)=\prod_{i=1}^q (p_i-1) p_i^{k_i-1} = n \prod_{i=1}^q {\left( 1- \frac{1}{p_i} \right) }
Dans la formule, pi désigne un nombre premier et ki un entier strictement positif.

En effet, le caractère multiplicatif de l’indicatrice d’Euler et une récurrence montrent que :

\varphi(n) = \prod_{i=1}^q \varphi(p_i^{k_i})
Il suffit alors de dénombrer le nombre d’entiers non premiers avec une puissance d’un nombre premier et plus petit que celui-ci pour remarquer que :

\forall i \in [1, q] \quad \varphi(p_i^{k_i})= p_i^{k_i} - p_i^{k_i - 1}=(p_i-1).p_i^{k_i-1}
Ce qui permet de conclure la démonstration.

  Autres propriétés

  Arithmétique modulaire

L’indicatrice d’Euler est une fonction essentielle de l’arithmétique modulaire, elle est à la base de résultats fondamentaux, à la fois en mathématiques pures et appliquées.

Cette propriété est une conséquence directe du calcul explicite de l’indicatrice.

La cryptologie utilise largement cette fonction. Le code RSA se fonde sur le théorème d’Euler, indiquant que si n est un entier strictement positif et a un entier premier avec n, alors aφ(n) ≡ 1 (mod n).

Une autre branche de la théorie de l’information utilise l’indicatrice : la théorie des codes. C’est les cas des codes correcteurs, et particulièrement des codes cycliques. Ce type de code se construit à l’aide de polynôme cyclotomique et le degré du polynôme cyclotomique Φn d’indice n à coefficients dans les entiers est égal à φ(n). Plus précisément, on dispose des égalités suivantes :

X^n-1 \ = \ \prod_{d\mid n} \Phi_d (X) \quad \mathrm{et} \ \mathrm{donc} \quad \sum_{d\mid n}\varphi(d)=n
La somme et le produit sont étendus à tous les diviseurs positifs d de n.

La formule d’inversion de Möbius permet d’inverser cette somme :

\varphi(n)=\sum_{d\mid n} d \mu(n/d)
Ici, μ désigne la fonction de Möbius usuelle définie sur l’ensemble des entiers strictement positifs, la démonstration est proposée dans l’article associé.

  Théorie analytique des nombres

Les deux fonctions génératices présentées ici sont des conséquences directes du fait que :

\sum_{d|n} \varphi(d) = n.

Une série de Dirichlet utilisant \varphi(n) est

\sum_{n=1}^{\infty} \frac{\varphi(n)}{n^s}=\frac{\zeta(s-1)}{\zeta(s)}.

qui est dérivé depuis :

 \zeta(s) \sum_{n=1}^\infty \frac{\varphi(n)}{n^s} = \sum_{n=1}^\infty \left(\sum_{d|n} \varphi(d)\right) \frac{1}{n^s} = \sum_{n=1}^\infty \frac{n}{n^s} = \zeta(s-1),

ou \zeta(s) est la fonction zêta de Riemann.

Une série de Lambert utilisant \varphi(n) est

\sum_{n=1}^{\infty} \frac{\varphi(n) q^n}{1-q^n}= \frac{q}{(1-q)^2}

qui converge pour |q|<1.

dérivé de :

\sum_{n=1}^{\infty} \frac{\varphi(n) q^n}{1-q^n} = \sum_{n=1}^{\infty} \varphi(n) \sum_{r\ge 1} q^{rn}

avec

 \sum_{k\ge 1} q^k \sum_{n|k} \varphi(n) = \sum_{k\ge 1} k q^k = \frac{q}{(1-q)^2}.

  Croissance de la fonction

La croissance de \varphi(n) comme une fonction de n est une question intéressante. La première impression que l’on a pour les petits n est que \varphi(n) doit être notablement plus petit que n, ce qui est quelque peu erroné. Asymptotiquement, nous avons

n^{1 - \epsilon} < \varphi(n) < n\,

pour n’importe quel \epsilon > 0\, et n > N(\epsilon)\, . En fait, si nous considérons

\frac {\varphi(n)}{n}\,

nous pouvons écrire, à partir de la formule précédente, sous forme de produit de facteurs

1 - p^{-1}\,

où les p sont des nombres premiers divisant n. Par conséquent les valeurs de n correspondantes aux valeurs particulièrement petites du rapport sont les n qui sont le produit d’un segment initial de la suite de tous les nombres premiers. À partir du théorème des nombres premiers il peut être montré qu’une constante ε dans la formule précédente peut par conséquent être remplacée par

C \frac{\log\log {n}}{{\log n}}\, .

  Les 99 premières valeurs de la fonction φ

  Les 100 premières valeurs de la fonction φ
\varphi(n) +0 +1 +2 +3 +4 +5 +6 +7 +8 +9
0+ 1 1 2 2 4 2 6 4 6
10+ 4 10 4 12 6 8 8 16 6 18
20+ 8 12 10 22 8 20 12 18 12 28
30+ 8 30 16 20 16 24 12 36 18 24
40+ 16 40 12 42 20 24 22 46 16 42
50+ 20 32 24 52 18 40 24 36 28 58
60+ 16 60 30 36 32 48 20 66 32 44
70+ 24 70 24 72 36 40 36 60 24 78
80+ 32 54 40 82 24 64 42 56 40 88
90+ 24 72 44 60 46 72 32 96 42 60

On observe que, excepté pour n = 1 ou 2, \varphi(n) est pair, propriété qui est générale. En effet, en notant  n=2^k \prod_{i=1}^q p_i^{k_i} avec les p_i impairs et q éventuellement nul (produit vide), on a :

 \varphi (n)=2^{k - 1} \prod_{i=1}^q (p_i-1) p_i^{k_i-1}
Or si n > 2, alors k > 1 ou q > 0. Dans un cas comme dans l’autre, on obtient bien que \varphi(n) est pair.

  Autres formules impliquant la fonction φ d’Euler

\;\varphi(n^m) = n^{m-1}\varphi(n) pour m\ge 1
\sum_{d \mid n} \frac{\mu^2(d)}{\varphi(d)} = \frac{n}{\varphi(n)}
\sum_{1\le k\le n \atop (k,n)=1}\!\!k = \frac{1}{2}n\varphi(n) pour \;n>1
\sum_{k=1}^n\varphi(k) = \frac{1}{2}\left(1+ \sum_{k=1}^n \mu(k)\left\lfloor\frac{n}{k}\right\rfloor^2\right)
\sum_{k=1}^n\frac{\varphi(k)}{k} = \sum_{k=1}^n\frac{\mu(k)}{k}\left\lfloor\frac{n}{k}\right\rfloor
\sum_{k=1}^n\frac{k}{\varphi(k)} = \mathcal{O}(n)
\sum_{k=1}^n\frac{1}{\varphi(k)} = \mathcal{O}(\log(n))

  Inégalités

Certaines inégalités impliquant la fonction \varphi(n) sont :

 \varphi(n) > \frac {n} {e^\gamma\; \log \log n + \frac {3} {\log \log n}} pour n > 2, où \gamma\, est la constante d’Euler,
 \varphi(n) \ge \sqrt{\frac {n} {2} } pour n > 0,

et

 \varphi(n) \ge \sqrt{n} pour n > 6.

Pour un nombre premier n, clairement \varphi(n) = n-1\,. Pour un nombre composé n, nous avons

 \varphi(n) \le n-\sqrt{n}

Pour tous les n>1  :

0<\frac{\varphi(n)}{n}<1

Pour un grand n aléatoire, ces bornes ne peuvent pas être encore améliorées, en effet :

\liminf \frac{\varphi(n)}{n}=0 \mbox{ et } \limsup \frac{\varphi(n)}{n}=1.

Une paire d’inégalités combinant la fonction \varphi et la fonction diviseur \sigma sont :

 \frac {6 n^2}{\pi^2} < \varphi(n) \sigma(n) < n^2 \mbox{ pour } n>1.

  Conjectures

  Voir aussi

© Copyright auteur(s) de Wikipédia – Cet article est sous licence CC BY-SA 3.0

Posted in Crypto0 commentaire

Mais pourquoi ma clé commence toujours par MIGf… ?

Read that f… RFC 1421 : Privacy Enhancement for Internet Electronic Mail

and follow those precious links :

https://lapo.it/asn1js
https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-encoded-length-and-value-bytes
http://javadoc.iaik.tugraz.at/iaik_jce/current/iaik/x509/PublicKeyInfo.html
https://medium.com/@bn121rajesh/understanding-rsa-public-key-70d900b1033c

# Generate 1024 bit Private key
$ openssl genrsa -out myprivate.pem 1024
# Separate the public part from the Private key file.
$ openssl rsa -in myprivate.pem -pubout > mypublic.pem
# Display the contents of private key
$ cat myprivate.pem

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDRFNU++93aEvz3cV8LSUP9ib3iUxT7SufdVXcgVFK9M3BYzvro
A1uO/parFOJABTkNhTPPP/6mjrU2CPEZJ1zIkpaSNJrrhpp/rNMO9nyLYPGs9Mfd
BiWUPmHW5mY1oD0ye4my0tEsHOlgHC8AhA8OtiHr6IY0agXmH/y5YmSWbwIDAQAB
AoGAAj/IH3pUI6FqqTrF+/gYzCRsL4AXTLC8l8vwkR93GGPyRHJNjqtik8I3WrXJ
zUiBGZ0iNouIsL/+QQuNlGiw/c5i2X3nTntREDS9xs2M0x+MWD/5qI1sn0Qk0HNP
BbDczlvO8wXNFGIHiTiPVEawoeNwhMqJDyGcbsEOZp2pLokCQQDvlMBU6dOeOP9a
jnENFSlrvzNR0nugFeoGmfq6s4Czz2QtUd9baKqBfEBSdJskwFVHgxbFA1Dc7iFu
rJkoQEeFAkEA32j9ibSVryxLvWUZngKNwo2xE+wcYDAYVBMsYC3OBU3FXhVkFD06
ZVnJsY/4bd2VdQI+bI2KV99aHutMJG2WYwJABMn2ZjweTMVa5VZ/kAFiSJMT1Yjd
i7+kY+lkB6Na6T02BWnjixI2hkwThRJrn3pwufM2201Lqn7gEDRHA3T1eQJBAKZG
1RUNo6558HEo8vUIf4vCu33RaJkqkqDYmFmJHeISrQfGMfNiUrkmJ5iRR9w1ZExu
/Bj9C281XDTQ+Z3PNnMCQQCan+pvj0OZH6o0PAMJGBBwRECPpfZ6mUjwA2YD3g61
MHjtIYmKKGmn64Qs8zQ4mNEDboQqyaov3Ij/I6c0ZQlc
-----END RSA PRIVATE KEY-----

Privacy Enhanced Mail (PEM)

Privacy Enhanced Mail (PEM) is a Base64 encoded Distinguished Encoding Rules(DER)
PEM file is human readable as it uses 64 printable characters for encoding.
It is easy to share PEM file.

 

Display the contents of public key PEM file

# Display the contents of public key PEM file
$ cat mypublic.pem

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRFNU++93aEvz3cV8LSUP9ib3i
UxT7SufdVXcgVFK9M3BYzvroA1uO/parFOJABTkNhTPPP/6mjrU2CPEZJ1zIkpaS
NJrrhpp/rNMO9nyLYPGs9MfdBiWUPmHW5mY1oD0ye4my0tEsHOlgHC8AhA8OtiHr
6IY0agXmH/y5YmSWbwIDAQAB
-----END PUBLIC KEY-----

 

Distinguished Encoding Rules (DER) format of public key

DER is encoded in Type-Length-Value (TLV) format.
DER is in binary format for PEM file and follows certain structure for public key.

# Convert PEM file to DER format using openssl rsa
$ openssl rsa -pubin -inform PEM -in mypublic.pem -outform DER -out mypublic.der
# Dump the DER file in hex format.
$ xxd -g 1 -u mypublic.der | cut -c -57
00000000: 30 81 9F 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01
00000010: 05 00 03 81 8D 00 30 81 89 02 81 81 00 D1 14 D5
00000020: 3E FB DD DA 12 FC F7 71 5F 0B 49 43 FD 89 BD E2
00000030: 53 14 FB 4A E7 DD 55 77 20 54 52 BD 33 70 58 CE
00000040: FA E8 03 5B 8E FE 96 AB 14 E2 40 05 39 0D 85 33
00000050: CF 3F FE A6 8E B5 36 08 F1 19 27 5C C8 92 96 92
00000060: 34 9A EB 86 9A 7F AC D3 0E F6 7C 8B 60 F1 AC F4
00000070: C7 DD 06 25 94 3E 61 D6 E6 66 35 A0 3D 32 7B 89
00000080: B2 D2 D1 2C 1C E9 60 1C 2F 00 84 0F 0E B6 21 EB
00000090: E8 86 34 6A 05 E6 1F FC B9 62 64 96 6F 02 03 01
000000a0: 00 01

 

Structured DER file content

1:30 81 9F // Type: 30 (SEQUENCE) Length: 0x9F
2:| 30 0D // Type: 30 (SEQUENCE) Length: 0x0D
3:| | 06 09 // Type: 06 (OBJECT_IDENTIFIER) Length: 0x09
4:| | - 2A 86 48 // 9 bytes OID value. HEX encoding of
5:| | - 86 F7 0D // 1.2.840.113549.1.1.1
6:| | - 01 01 01
7:| | 05 00 // Type: 05 (NULL) Length: 0x00
8:| 03 81 8D // Type: 03 (BIT STRING) Length: 0x8D
9:| | - 00 // Number of unused bits in last content byte
10:| | 30 81 89 // Type: 30 (SEQUENCE) Length: 0x89
11:| | | 02 81 81 // Type: 02 (INTEGER) Length: 0x81
12:| | | - 00 // Leading ZERO of integer
13:| | | - D1 14 D5 3E FB DD DA 12 FC F7 71 5F 0B 49 43 FD
14:| | | - 89 BD E2 53 14 FB 4A E7 DD 55 77 20 54 52 BD 33
15:| | | - 70 58 CE FA E8 03 5B 8E FE 96 AB 14 E2 40 05 39
16:| | | - 0D 85 33 CF 3F FE A6 8E B5 36 08 F1 19 27 5C C8
17:| | | - 92 96 92 34 9A EB 86 9A 7F AC D3 0E F6 7C 8B 60
18:| | | - F1 AC F4 C7 DD 06 25 94 3E 61 D6 E6 66 35 A0 3D
19:| | | - 32 7B 89 B2 D2 D1 2C 1C E9 60 1C 2F 00 84 0F 0E
20:| | | - B6 21 EB E8 86 34 6A 05 E6 1F FC B9 62 64 96 6F
21:| | | 02 03 // Type: 02 (INTEGER) Length: 0x3
22:| | | - 01 00 01 // Public Exponent. Hex for 65537

 

DER file contains Object Identifier, Modulus and Public exponent in HEX format.

Lines 4, 5, 6 is the HEX encoding of OID.
Lines 13 to 20 is the modulus (n).
Line 22 is the public exponent.

You can also have a look at Lapo ASN.1 javascript decoder :

Javascript ASN.1 decoder

Javascript ASN.1 decoder

Modulus and Public exponent from public key using openssl

# Get Modulus and Public exponent from public PEM file
$ openssl rsa -pubin -inform PEM -text -noout < mypublic.pem

Public-Key: (1024 bit)
Modulus:
00:d1:14:d5:3e:fb:dd:da:12:fc:f7:71:5f:0b:49:
43:fd:89:bd:e2:53:14:fb:4a:e7:dd:55:77:20:54:
52:bd:33:70:58:ce:fa:e8:03:5b:8e:fe:96:ab:14:
e2:40:05:39:0d:85:33:cf:3f:fe:a6:8e:b5:36:08:
f1:19:27:5c:c8:92:96:92:34:9a:eb:86:9a:7f:ac:
d3:0e:f6:7c:8b:60:f1:ac:f4:c7:dd:06:25:94:3e:
61:d6:e6:66:35:a0:3d:32:7b:89:b2:d2:d1:2c:1c:
e9:60:1c:2f:00:84:0f:0e:b6:21:eb:e8:86:34:6a:
05:e6:1f:fc:b9:62:64:96:6f
Exponent: 65537 (0x10001)

Exponent and modulus printed by openssl rsa matches with the Public exponent and modulus from DER file content.

More information on recommended syntax for interchanging RSA public keys between implementations is given in Appendix A.1.1 of rfc3447 ( PKCS#1);

RSA key representation

RSA key representation

 

Object Identifier

OID describes the object. It is a series of nodes separated by period.

OID Value: 1.2.840.113549.1.1.1

OID description: Identifier for RSA encryption for use with Public Key Cryptosystem One defined by RSA Inc.

OID Encoding rules:

1 – The first two nodes of the OID are encoded onto a single byte. The first node is multiplied by the decimal 40 and the result is added to the value of the second node.
2 – Node values less than or equal to 127 are encoded on one byte.
3 – Node values greater than or equal to 128 are encoded on multiple bytes. Bit 7 of all bytes except the rightmost byte is set to one. Bits 0 through 6 of each byte contains the encoded value.

OID Encoding Example © Rajesh Bondugula

OID Encoding Example © Rajesh Bondugula

 

Representing length in ASN.1 encoding

If number of value bytes is < 128 (0x80) then length is represented in 1 byte. In this case most significant bit is 0. (Ex: Line 2: 0x81=10000001 => 1 octet, Line 3 in structured DER content above)

If number of value bytes is >= 128 (0x80) then length is represented in multiple bytes. Most significant bit (bit 7) of first byte is 1 indicating multiple byte length. Bits 0–6 represent number of subsequent bytes for length. (Ex:  Line 1: 0x82=10000010 => 2 octets, Line 4 in structured DER content above)

 

References

DER encoding of ASN.1 types (MSDN)
Public Key Info structure (Java doc)

 

[ajout de août 2021 suite plaintes]

– Mais du coup … tu n’as pas répondu  la question ?
[lm] C’est pas faux, mais si tu révises le fonctionnement de l’encodage base 64, à partir d’un contenu DER qui commence toujours par la même syntaxe:

xxd -r -p <<<30819F | base64
MIGf

 

Posted in Crypto, PKI, ICP, IGC1 Commentaire