/**
 *
 * Une générateur de clefs publiques et privées pour RSA.
 *
 */
public abstract class RSA
{
  /********************************* méthodes publiques de classe *********************************/

  /**
   * Génère les nombres aléatoires <i>p</i> et <i>q</i> et calcule/génère les valeurs dérivées
   * <i>n</i>, <i>b</i> <i>a</i>.
   *
   * @return       Le tableau formé des nombres (n,b,a).
   */
  public static EPA[] génèreClés( final int  nbrdigits,
                                  final int  margeprimalité )
  {
    final EPA      p= EPA.créerAléatoirementPremier( nbrdigits, margeprimalité );
    final EPA      q= EPA.créerAléatoirementPremier( nbrdigits, margeprimalité );
    final EPA      n= p.multipliéPar( q );
    final EPA      pMoinsUn= p.moins( EPA.UN );
    final EPA      qMoinsUn= q.moins( EPA.UN );
    final EPA      phi_n= pMoinsUn.multipliéPar( qMoinsUn );
    final EPA      b= petitPremierAvec( phi_n, nbrdigits );
    final EPA      a= b.inverseModulo( phi_n );
    final EPA[]    result= { n, b, a };

    return result;
  }


  /********************************** méthodes privées de classe **********************************/

  /**
   * Renvoie un EPA de <i>nbrdigits</i> en base 10, premier avec l'EPA <i>gros</i>, et inférieur à
   * celui-ci.
   */
  private static EPA petitPremierAvec( final EPA  gros,
                                       final int  nbrdigits )
  {
    while (true)
    {
      final EPA    petit= EPA.créerAléatoirement( nbrdigits );

      if (   (petit.compareTo( gros ) < 0)
          && (gros.pgcd( petit ).compareTo( EPA.UN ) == 0))
        return petit;
    }
  }
}
