Botan  1.11.15
src/lib/pubkey/if_algo/if_algo.cpp
Go to the documentation of this file.
00001 /*
00002 * IF Scheme
00003 * (C) 1999-2007 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/if_algo.h>
00009 #include <botan/numthry.h>
00010 #include <botan/workfactor.h>
00011 #include <botan/der_enc.h>
00012 #include <botan/ber_dec.h>
00013 
00014 namespace Botan {
00015 
00016 size_t IF_Scheme_PublicKey::estimated_strength() const
00017    {
00018    return dl_work_factor(n.bits());
00019    }
00020 
00021 AlgorithmIdentifier IF_Scheme_PublicKey::algorithm_identifier() const
00022    {
00023    return AlgorithmIdentifier(get_oid(),
00024                               AlgorithmIdentifier::USE_NULL_PARAM);
00025    }
00026 
00027 std::vector<byte> IF_Scheme_PublicKey::x509_subject_public_key() const
00028    {
00029    return DER_Encoder()
00030       .start_cons(SEQUENCE)
00031          .encode(n)
00032          .encode(e)
00033       .end_cons()
00034       .get_contents_unlocked();
00035    }
00036 
00037 IF_Scheme_PublicKey::IF_Scheme_PublicKey(const AlgorithmIdentifier&,
00038                                          const secure_vector<byte>& key_bits)
00039    {
00040    BER_Decoder(key_bits)
00041       .start_cons(SEQUENCE)
00042         .decode(n)
00043         .decode(e)
00044       .verify_end()
00045       .end_cons();
00046    }
00047 
00048 /*
00049 * Check IF Scheme Public Parameters
00050 */
00051 bool IF_Scheme_PublicKey::check_key(RandomNumberGenerator&, bool) const
00052    {
00053    if(n < 35 || n.is_even() || e < 2)
00054       return false;
00055    return true;
00056    }
00057 
00058 secure_vector<byte> IF_Scheme_PrivateKey::pkcs8_private_key() const
00059    {
00060    return DER_Encoder()
00061       .start_cons(SEQUENCE)
00062          .encode(static_cast<size_t>(0))
00063          .encode(n)
00064          .encode(e)
00065          .encode(d)
00066          .encode(p)
00067          .encode(q)
00068          .encode(d1)
00069          .encode(d2)
00070          .encode(c)
00071       .end_cons()
00072    .get_contents();
00073    }
00074 
00075 IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng,
00076                                            const AlgorithmIdentifier&,
00077                                            const secure_vector<byte>& key_bits)
00078    {
00079    BER_Decoder(key_bits)
00080       .start_cons(SEQUENCE)
00081          .decode_and_check<size_t>(0, "Unknown PKCS #1 key format version")
00082          .decode(n)
00083          .decode(e)
00084          .decode(d)
00085          .decode(p)
00086          .decode(q)
00087          .decode(d1)
00088          .decode(d2)
00089          .decode(c)
00090       .end_cons();
00091 
00092    load_check(rng);
00093    }
00094 
00095 IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng,
00096                                            const BigInt& prime1,
00097                                            const BigInt& prime2,
00098                                            const BigInt& exp,
00099                                            const BigInt& d_exp,
00100                                            const BigInt& mod)
00101    {
00102    p = prime1;
00103    q = prime2;
00104    e = exp;
00105    d = d_exp;
00106    n = mod.is_nonzero() ? mod : p * q;
00107 
00108    if(d == 0)
00109       {
00110       BigInt inv_for_d = lcm(p - 1, q - 1);
00111       if(e.is_even())
00112          inv_for_d >>= 1;
00113 
00114       d = inverse_mod(e, inv_for_d);
00115       }
00116 
00117    d1 = d % (p - 1);
00118    d2 = d % (q - 1);
00119    c = inverse_mod(q, p);
00120 
00121    load_check(rng);
00122    }
00123 
00124 /*
00125 * Check IF Scheme Private Parameters
00126 */
00127 bool IF_Scheme_PrivateKey::check_key(RandomNumberGenerator& rng,
00128                                      bool strong) const
00129    {
00130    if(n < 35 || n.is_even() || e < 2 || d < 2 || p < 3 || q < 3 || p*q != n)
00131       return false;
00132 
00133    if(d1 != d % (p - 1) || d2 != d % (q - 1) || c != inverse_mod(q, p))
00134       return false;
00135 
00136    const size_t prob = (strong) ? 56 : 12;
00137 
00138    if(!is_prime(p, rng, prob) || !is_prime(q, rng, prob))
00139       return false;
00140    return true;
00141    }
00142 
00143 }