# pike.git/lib/modules/Crypto.pmod/RSA.pike

Branch: Tag:

## 2013-11-24

#### 2013-11-24 22:43:38 by Martin Nilsson <nilsson@opera.com>

• d5f6893886644e23a58722744f2f38a782ddf256 (50 lines) (+41/-9) [ Show | Annotate ]
Branch: 8.0
Added support for Nettle RSA/DSA key generation to Nettle. Added code in Crypto.RSA to use it, but currently not active due to CPP strangenewss. Speeds up key generation by 75%.

107: Inside #if constant(Crypto.Hash)
// --- Key generation   //    + #if constant(Nettle.rsa_generate_key) +  + this_program generate_key(int bits, void|int e) + { +  // While a smaller e is possible, and more efficient, using 0x10001 +  // has become standard and is the only value supported by several +  // TLS implementations. +  if(!e) +  e = 0x10001; +  else +  { +  if(!(e&1)) error("e needs to be odd.\n"); +  if(e<3) error("e is too small.\n"); +  if(e->size()>bits) error("e has to be smaller in size than the key.\n"); +  } +  +  if(bits<89) error("Too small key length.\n"); +  +  array(Gmp.mpz) key = Nettle.rsa_generate_keypair(bits, e, +  random); +  if(!key) error("Error generating key.\n"); +  [ n, d, p, q ] = key; +  this_program::e = Gmp.mpz(e); +  size = n->size(256); +  return this; + } +  + #else +    // Generate a prime with @[bits] number of bits using random function   // @[r].   protected Gmp.mpz get_prime(int bits, function(int:string) r)
126: Inside #if constant(Crypto.Hash)
return p;   }    - //! Generate a valid RSA key pair with the size @[bits]. A random - //! function may be provided as arguemnt @[r], otherwise the default - //! random function set in the object will be used. Keys must be at - //! least 128 bits. - this_program generate_key(int(128..) bits, function(int:string)|void r) + //! Generate a valid RSA key pair with the size @[bits] using the + //! random function set with @[set_random()]. The public exponent @[e] + //! will be used, which defaults to 65537. Keys must be at least 89 + //! bits. + this_program generate_key(int(128..) bits, void|int e)   { -  if (!r) r = random; +     if (bits < 128)    error( "Ridiculously small key.\n" );
154: Inside #if constant(Crypto.Hash)
Gmp.mpz q;    Gmp.mpz mod;    do { -  p = get_prime(s1, r); -  q = get_prime(s2, r); +  p = get_prime(s1, random); +  q = get_prime(s2, random);    mod = [object(Gmp.mpz)](p * q);    } while (mod->size() != bits);    Gmp.mpz phi = [object(Gmp.mpz)](Gmp.mpz([object(Gmp.mpz)](p-1))*
167: Inside #if constant(Crypto.Hash)
// problem, but turned out was a padding problem. The exponent    // 0x10001 has however become common practice, although a smaller    // value would be more efficient. -  Gmp.mpz pub = Gmp.mpz(0x10001); +  Gmp.mpz pub = Gmp.mpz(e || 0x10001);       // For security reason we need to ensure no common denominator    // between n and phi. We could create a different exponent, but
186: Inside #if constant(Crypto.Hash)
return this;   }    + #endif +  +    //   // --- PKCS methods   //