diff options
author | lloyd <[email protected]> | 2010-03-02 05:08:15 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-03-02 05:08:15 +0000 |
commit | 3c15bd259f0921f1fa08ec91ee3cf2621c64a02d (patch) | |
tree | 54351d5e865a872896c6a95175693cc0ffa9e246 /src/pubkey | |
parent | 5fec937bd0c72858d6cf2f09b58b219294c7d5cc (diff) | |
parent | 54a3c5ae67f8b987d05ffd18e2d49a2da1d5988e (diff) |
propagate from branch 'net.randombit.botan' (head fc86fc4842254088bf820ea6ebf05877aa63fb22)
to branch 'net.randombit.botan.c++0x' (head 77565ff7252df7f8faad86d65075498b0adb93d8)
Diffstat (limited to 'src/pubkey')
23 files changed, 475 insertions, 1926 deletions
diff --git a/src/pubkey/ec_dompar/ec_dompar.cpp b/src/pubkey/ec_dompar/ec_dompar.cpp index 30a121875..7910e898f 100644 --- a/src/pubkey/ec_dompar/ec_dompar.cpp +++ b/src/pubkey/ec_dompar/ec_dompar.cpp @@ -8,587 +8,135 @@ */ #include <botan/ec_dompar.h> -#include <botan/pubkey_enums.h> -#include <botan/parsing.h> -#include <botan/hex.h> -#include <botan/pipe.h> +#include <botan/ber_dec.h> +#include <botan/der_enc.h> +#include <botan/libstate.h> +#include <botan/oids.h> +#include <botan/pem.h> namespace Botan { -namespace { - -std::vector<std::string> get_standard_domain_parameter(const std::string& oid) +EC_Domain_Params::EC_Domain_Params(const OID& domain_oid) { - // using a linear search here is pretty nasty... revisit - - /* SEC2 */ - - if(oid == "1.3.132.0.6") - { - /* secp112r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xdb7c2abf62e35e668076bead208b"); //p - dom_par.push_back("0xDB7C2ABF62E35E668076BEAD2088"); // a - dom_par.push_back("0x659EF8BA043916EEDE8911702B22"); // b - dom_par.push_back("0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0ff77500"); // G - dom_par.push_back("0xDB7C2ABF62E35E7628DFAC6561C5"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.7") - { - /* secp112r2; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xdb7c2abf62e35e668076bead208b"); //p - dom_par.push_back("0x6127C24C05F38A0AAAF65C0EF02C"); // a - dom_par.push_back("0x51DEF1815DB5ED74FCC34C85D709"); // b - dom_par.push_back("044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97"); // G - dom_par.push_back("0x36DF0AAFD8B8D7597CA10520D04B"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.28") - { - /* secp128r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffdffffffffffffffffffffffff"); //p - dom_par.push_back("0xffffffFDffffffffffffffffffffffFC"); // a - dom_par.push_back("0xE87579C11079F43DD824993C2CEE5ED3"); // b - dom_par.push_back("04161ff7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83"); // G - dom_par.push_back("0xffffffFE0000000075A30D1B9038A115"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.29") - { - /* secp128r2; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffdffffffffffffffffffffffff"); //p - dom_par.push_back("0xD6031998D1B3BBFEBF59CC9BBff9AEE1"); // a - dom_par.push_back("0x5EEEFCA380D02919DC2C6558BB6D8A5D"); // b - dom_par.push_back("047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44"); // G - dom_par.push_back("0x3ffffffF7ffffffFBE0024720613B5A3"); // order - dom_par.push_back("4"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.9") - { - /* secp160k1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffeffffac73"); //p - dom_par.push_back("0x0000000000000000000000000000000000000000"); // a - dom_par.push_back("0x0000000000000000000000000000000000000007"); // b - dom_par.push_back("043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE"); // G - dom_par.push_back("0x0100000000000000000001B8FA16DFAB9ACA16B6B3"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.30") - { - /* secp160r2; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffeffffac73"); //p - dom_par.push_back("0xffffffffffffffffffffffffffffffFEffffAC70"); // a - dom_par.push_back("0xB4E134D3FB59EB8BAB57274904664D5AF50388BA"); // b - dom_par.push_back("0452DCB034293A117E1F4ff11B30F7199D3144CE6DFEAffEF2E331F296E071FA0DF9982CFEA7D43F2E"); // G - dom_par.push_back("0x0100000000000000000000351EE786A818F3A1A16B"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.31") - { - /* secp192k1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffffffffffeffffee37"); //p - dom_par.push_back("0x000000000000000000000000000000000000000000000000"); // a - dom_par.push_back("0x000000000000000000000000000000000000000000000003"); // b - dom_par.push_back("04DB4ff10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); // G - dom_par.push_back("0xffffffffffffffffffffffFE26F2FC170F69466A74DEFD8D"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.32") - { - /* secp224k1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffffffffffffffffffeffffe56d"); //p - dom_par.push_back("0x00000000000000000000000000000000000000000000000000000000"); // a - dom_par.push_back("0x00000000000000000000000000000000000000000000000000000005"); // b - dom_par.push_back("04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"); // G - dom_par.push_back("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.33") - { - /* secp224r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xffffffffffffffffffffffffffffffff000000000000000000000001"); //p - dom_par.push_back("0xffffffffffffffffffffffffffffffFEffffffffffffffffffffffFE"); // a - dom_par.push_back("0xB4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355ffB4"); // b - dom_par.push_back("04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); // G - dom_par.push_back("0xffffffffffffffffffffffffffff16A2E0B8F03E13DD29455C5C2A3D"); // order - dom_par.push_back("1"); // cofactor + std::string pem = + global_state().get("ec", OIDS::lookup(domain_oid)); - return dom_par; - } - - if(oid == "1.3.132.0.10") - { - /* secp256k1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"); //p - dom_par.push_back("0x0000000000000000000000000000000000000000000000000000000000000000"); // a - dom_par.push_back("0x0000000000000000000000000000000000000000000000000000000000000007"); // b - dom_par.push_back("0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); // G - dom_par.push_back("0xffffffffffffffffffffffffffffffFEBAAEDCE6AF48A03BBFD25E8CD0364141"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.34") - { - /* secp384r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff"); //p - dom_par.push_back("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFEffffffff0000000000000000ffffffFC"); // a - dom_par.push_back("0xB3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"); // b - dom_par.push_back("04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"); // G - dom_par.push_back("0xffffffffffffffffffffffffffffffffffffffffffffffffC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.132.0.35") - { - /* secp521r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); //p - dom_par.push_back("0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFC"); // a - dom_par.push_back("0x0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"); // b - dom_par.push_back("0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"); // G - dom_par.push_back("0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - /* NIS */ - - if(oid == "1.3.6.1.4.1.8301.3.1.2.9.0.38") - { - /* NIST curve P-521; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); //p - dom_par.push_back("0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFC"); // a - dom_par.push_back("0x051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"); // b - dom_par.push_back("0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"); // G - dom_par.push_back("0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - /* BrainPool */ - - if(oid == "1.3.36.3.3.2.8.1.1.1") - { - /* brainpoolP160r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xE95E4A5F737059DC60DFC7AD95B3D8139515620F"); //p - dom_par.push_back("0x340E7BE2A280EB74E2BE61BADA745D97E8F7C300"); // a - dom_par.push_back("0x1E589A8595423412134FAA2DBDEC95C8D8675E58"); // b - dom_par.push_back("04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321"); // G - dom_par.push_back("0xE95E4A5F737059DC60DF5991D45029409E60FC09"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.36.3.3.2.8.1.1.3") - { - /* brainpoolP192r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xC302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297"); //p - dom_par.push_back("0x6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF"); // a - dom_par.push_back("0x469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9"); // b - dom_par.push_back("04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F"); // G - dom_par.push_back("0xC302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.36.3.3.2.8.1.1.5") - { - /* brainpoolP224r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xD7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF"); //p - dom_par.push_back("0x68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43"); // a - dom_par.push_back("0x2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B"); // b - dom_par.push_back("040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD"); // G - dom_par.push_back("0xD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.36.3.3.2.8.1.1.7") - { - /* brainpoolP256r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xA9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377"); //p - dom_par.push_back("0x7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9"); // a - dom_par.push_back("0x26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6"); // b - dom_par.push_back("048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997"); // G - dom_par.push_back("0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } + if(pem == "") + throw Lookup_Error("No ECC domain data for " + domain_oid.as_string()); - if(oid == "1.3.36.3.3.2.8.1.1.9") - { - /* brainpoolP320r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xD35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27"); //p - dom_par.push_back("0x3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4"); // a - dom_par.push_back("0x520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6"); // b - dom_par.push_back("0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1"); // G - dom_par.push_back("0xD35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } - - if(oid == "1.3.36.3.3.2.8.1.1.11") - { - /* brainpoolP384r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53"); //p - dom_par.push_back("0x7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826"); // a - dom_par.push_back("0x4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11"); // b - dom_par.push_back("041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315"); // G - dom_par.push_back("0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565"); // order - dom_par.push_back("1"); // cofactor - - return dom_par; - } + *this = EC_Domain_Params(pem); + oid = domain_oid.as_string(); + } - if(oid == "1.3.36.3.3.2.8.1.1.13") +EC_Domain_Params::EC_Domain_Params(const std::string& pem) + { + if(pem != "") { - /* brainpoolP512r1; source: Flexiprovider */ - std::vector<std::string> dom_par; - dom_par.push_back("0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"); //p - dom_par.push_back("0x7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA"); // a - dom_par.push_back("0x3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723"); // b - dom_par.push_back("0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892"); // G - dom_par.push_back("0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069"); // order - dom_par.push_back("1"); // cofactor + DataSource_Memory input(pem); - return dom_par; - } - - if(oid == "1.3.132.0.8") - { - std::vector<std::string> dom_par; - dom_par.push_back("0xffffffffffffffffffffffffffffffff7fffffff"); //p - dom_par.push_back("0xffffffffffffffffffffffffffffffff7ffffffc"); // a - dom_par.push_back("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45"); // b - dom_par.push_back("024a96b5688ef573284664698968c38bb913cbfc82"); // G - dom_par.push_back("0x0100000000000000000001f4c8f927aed3ca752257"); // order - dom_par.push_back("1"); // cofactor - return dom_par; + *this = EC_Domain_Params( + PEM_Code::decode_check_label(input, "ECC DOMAIN PARAMETERS")); } + } - if(oid == "1.2.840.10045.3.1.1") // prime192v1 Flexiprovider - { - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); //p - dom_par.push_back("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); // a - dom_par.push_back("0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"); // b - dom_par.push_back("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"); // G - dom_par.push_back("0xffffffffffffffffffffffff99def836146bc9b1b4d22831"); // order - dom_par.push_back("1"); // cofactor - return dom_par; - } +EC_Domain_Params::EC_Domain_Params(const MemoryRegion<byte>& ber_data) + { + BER_Decoder ber(ber_data); + BER_Object obj = ber.get_next_object(); - /* prime192v2; source: Flexiprovider */ - if(oid == "1.2.840.10045.3.1.2") + if(obj.type_tag == NULL_TAG) + throw Decoding_Error("Cannot handle ImplicitCA ECDSA parameters"); + else if(obj.type_tag == OBJECT_ID) { - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); //p - dom_par.push_back("0xffffffffffffffffffffffffffffffFeffffffffffffffFC"); // a - dom_par.push_back("0xcc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"); // b - dom_par.push_back("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a"); // G - dom_par.push_back("0xfffffffffffffffffffffffe5fb1a724dc80418648d8dd31"); // order - dom_par.push_back("1"); // cofactor - return dom_par; + OID dom_par_oid; + BER_Decoder(ber_data).decode(dom_par_oid); + *this = EC_Domain_Params(dom_par_oid); } - - /* prime192v3; source: Flexiprovider */ - if(oid == "1.2.840.10045.3.1.3") + else if(obj.type_tag == SEQUENCE) { - std::vector<std::string> dom_par; - dom_par.push_back("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); //p - dom_par.push_back("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); // a - dom_par.push_back("0x22123dc2395a05caa7423daeccc94760a7d462256bd56916"); // b - dom_par.push_back("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896"); // G - dom_par.push_back("0xffffffffffffffffffffffff7a62d031c83f4294f640ec13"); // order - dom_par.push_back("1"); // cofactor - return dom_par; - } + BigInt ecpVers1(1); + OID curve_type; + SecureVector<byte> sv_a; + SecureVector<byte> sv_b; + BigInt p; + SecureVector<byte> sv_base_point; - /* prime239v1; source: Flexiprovider */ - if(oid == "1.2.840.10045.3.1.4") - { - std::vector<std::string> dom_par; - dom_par.push_back("0x7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff"); //p - dom_par.push_back("0x7ffFffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"); // a - dom_par.push_back("0x6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A"); // b - dom_par.push_back("020ffA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF"); // G - dom_par.push_back("0x7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b"); // order - dom_par.push_back("1"); // cofactor - return dom_par; - } + BER_Decoder(ber_data) + .start_cons(SEQUENCE) + .decode(ecpVers1) + .start_cons(SEQUENCE) + .decode(curve_type) + .decode(p) + .end_cons() + .start_cons(SEQUENCE) + .decode(sv_a, OCTET_STRING) + .decode(sv_b, OCTET_STRING) + .end_cons() + .decode(sv_base_point, OCTET_STRING) + .decode(order) + .decode(cofactor) + .end_cons() + .verify_end(); - /* prime239v2; source: Flexiprovider */ - if(oid == "1.2.840.10045.3.1.5") - { - std::vector<std::string> dom_par; - dom_par.push_back("0x7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff"); //p - dom_par.push_back("0x7ffFffffffffffffffffffff7ffFffffffff8000000000007ffFffffffFC"); // a - dom_par.push_back("0x617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C"); // b - dom_par.push_back("0238AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7"); // G - dom_par.push_back("0x7fffffffffffffffffffffff800000CFA7E8594377D414C03821BC582063"); // order - dom_par.push_back("1"); // cofactor - return dom_par; - } + if(ecpVers1 != 1) + throw Decoding_Error("EC_Domain_Params: Unknown version code"); - /* prime239v3; source: Flexiprovider */ - if(oid == "1.2.840.10045.3.1.6") - { - std::vector<std::string> dom_par; - dom_par.push_back("0x7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff"); //p - dom_par.push_back("0x7ffFffffffffffffffffffff7ffFffffffff8000000000007ffFffffffFC"); // a - dom_par.push_back("0x255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E"); // b - dom_par.push_back("036768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A"); // G - dom_par.push_back("0x7fffffffffffffffffffffff7fffff975DEB41B3A6057C3C432146526551"); // order - dom_par.push_back("1"); // cofactor - return dom_par; - } + // Only prime curves supported + if(curve_type.as_string() != "1.2.840.10045.1.1") + throw Decoding_Error("Unexpected curve type " + curve_type.as_string()); - /* prime256v1; source: Flexiprovider */ - if(oid == "1.2.840.10045.3.1.7") - { - std::vector<std::string> dom_par; - dom_par.push_back("0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff"); //p - dom_par.push_back("0xffffffff00000001000000000000000000000000ffffffffffffffffffffffFC"); // a - dom_par.push_back("0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); // b - dom_par.push_back("036B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"); // G - dom_par.push_back("0xffffffff00000000ffffffffffffffffBCE6FAADA7179E84F3B9CAC2FC632551"); // order - dom_par.push_back("1"); // cofactor - return dom_par; - } + curve = CurveGFp(p, + BigInt::decode(sv_a, sv_a.size()), + BigInt::decode(sv_b, sv_b.size())); - if(oid == "1.2.643.2.2.35.1" || oid == "1.2.643.2.2.36.0") // GostR3410-2001-CryptoPro-A-ParamSet - { - std::vector<std::string> dom_par; - dom_par.push_back("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97"); - dom_par.push_back("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94"); - dom_par.push_back("166"); - dom_par.push_back("0400000000000000000000000000000000000000000000000000000000000000018D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"); - dom_par.push_back("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893"); - dom_par.push_back("1"); - return dom_par; + base_point = OS2ECP(sv_base_point, curve); + base_point.check_invariants(); } - - throw Invalid_Argument("No such ECC curve " + oid); - } - -EC_Domain_Params get_ec_dompar(const std::string& oid) - { - std::vector<std::string> dom_par = get_standard_domain_parameter(oid); - - BigInt p(dom_par[0]); // give as 0x... - BigInt a(dom_par[1]); - BigInt b(dom_par[2]); - BigInt order(dom_par[4]); - BigInt cofactor(dom_par[5]); - - Pipe pipe(new Hex_Decoder); - pipe.process_msg(dom_par[3]); - SecureVector<byte> sv_g = pipe.read_all(); - - CurveGFp curve(p, a, b); - - PointGFp G = OS2ECP(sv_g, curve); - G.check_invariants(); - EC_Domain_Params result(curve, G, order, cofactor); - return result; - } - -} - -EC_Domain_Params get_EC_Dom_Pars_by_oid(std::string oid) - { - EC_Domain_Params result = get_ec_dompar(oid); - result.m_oid = oid; - return result; + else + throw Decoding_Error("Unexpected tag while decoding ECC domain params"); } -EC_Domain_Params::EC_Domain_Params(const CurveGFp& curve, const PointGFp& base_point, - const BigInt& order, const BigInt& cofactor) - : m_curve(curve), - m_base_point(base_point), - m_order(order), - m_cofactor(cofactor), - m_oid("") - { } - -namespace { - -SecureVector<byte> encode_der_ec_dompar_explicit(const EC_Domain_Params& dom_pars) +SecureVector<byte> +EC_Domain_Params::DER_encode(EC_Domain_Params_Encoding form) const { - u32bit ecpVers1 = 1; - OID curve_type_oid("1.2.840.10045.1.1"); + if(form == EC_DOMPAR_ENC_EXPLICIT) + { + u32bit ecpVers1 = 1; + OID curve_type("1.2.840.10045.1.1"); - const u32bit p_bytes = dom_pars.get_curve().get_p().bytes(); + const u32bit p_bytes = curve.get_p().bytes(); - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(ecpVers1) - .start_cons(SEQUENCE) - .encode(curve_type_oid) - .encode(dom_pars.get_curve().get_p()) - .end_cons() + return DER_Encoder() .start_cons(SEQUENCE) - .encode(BigInt::encode_1363(dom_pars.get_curve().get_a(), p_bytes), OCTET_STRING) - .encode(BigInt::encode_1363(dom_pars.get_curve().get_b(), p_bytes), OCTET_STRING) + .encode(ecpVers1) + .start_cons(SEQUENCE) + .encode(curve_type) + .encode(curve.get_p()) + .end_cons() + .start_cons(SEQUENCE) + .encode(BigInt::encode_1363(curve.get_a(), p_bytes), + OCTET_STRING) + .encode(BigInt::encode_1363(curve.get_b(), p_bytes), + OCTET_STRING) + .end_cons() + .encode(EC2OSP(base_point, PointGFp::UNCOMPRESSED), OCTET_STRING) + .encode(order) + .encode(cofactor) .end_cons() - .encode(EC2OSP ( dom_pars.get_base_point(), PointGFp::UNCOMPRESSED), OCTET_STRING) - .encode(dom_pars.get_order()) - .encode(dom_pars.get_cofactor()) - .end_cons() - .get_contents(); - } - -EC_Domain_Params decode_ber_ec_dompar_explicit(const SecureVector<byte>& encoded) - { - BigInt ecpVers1(1); - OID curve_type_oid; - SecureVector<byte> sv_a; - SecureVector<byte> sv_b; - BigInt p; - SecureVector<byte> sv_base_point; - BigInt order; - BigInt cofactor; - - BER_Decoder(encoded) - .start_cons(SEQUENCE) - .decode(ecpVers1) - .start_cons(SEQUENCE) - .decode(curve_type_oid) - .decode(p) - .end_cons() - .start_cons(SEQUENCE) - .decode(sv_a, OCTET_STRING) - .decode(sv_b, OCTET_STRING) - .end_cons() - .decode(sv_base_point, OCTET_STRING) - .decode(order) - .decode(cofactor) - .end_cons() - .verify_end(); - - if(ecpVers1 != 1) - throw Decoding_Error("wrong ecpVers"); - - // Set the domain parameters - if(curve_type_oid.as_string() != "1.2.840.10045.1.1") // NOTE: hardcoded: prime field type - { - throw Decoding_Error("wrong curve type oid where prime field was expected"); + .get_contents(); } + else if(form == EC_DOMPAR_ENC_OID) + return DER_Encoder().encode(get_oid()).get_contents(); + else if(form == EC_DOMPAR_ENC_IMPLICITCA) + return DER_Encoder().encode_null().get_contents(); - CurveGFp curve(p, - BigInt::decode(sv_a, sv_a.size()), - BigInt::decode(sv_b, sv_b.size())); - - PointGFp G = OS2ECP ( sv_base_point, curve ); - G.check_invariants(); - return EC_Domain_Params(curve, G, order, cofactor); + throw Internal_Error("EC_Domain_Params::encode_DER: Unknown encoding"); } -} // end anonymous namespace - -SecureVector<byte> encode_der_ec_dompar(const EC_Domain_Params& dom_pars, EC_dompar_enc enc_type) - { - SecureVector<byte> result; - - if(enc_type == ENC_EXPLICIT) - { - result = encode_der_ec_dompar_explicit(dom_pars); - } - else if(enc_type == ENC_OID) - { - OID dom_par_oid(dom_pars.get_oid()); - result = DER_Encoder().encode(dom_par_oid).get_contents(); - } - else if(enc_type == ENC_IMPLICITCA) - { - result = DER_Encoder().encode_null().get_contents(); - } - else - { - throw Internal_Error("encountered illegal value for ec parameter encoding type"); - } - return result; - } - -EC_Domain_Params decode_ber_ec_dompar(const SecureVector<byte>& encoded) +std::string EC_Domain_Params::PEM_encode() const { - BER_Decoder dec(encoded); - BER_Object obj = dec.get_next_object(); - - if(obj.type_tag == OBJECT_ID) - { - OID dom_par_oid; - BER_Decoder(encoded).decode(dom_par_oid); - return EC_Domain_Params(get_ec_dompar(dom_par_oid.as_string())); - } - else if(obj.type_tag == SEQUENCE) - return EC_Domain_Params(decode_ber_ec_dompar_explicit(encoded)); - else if(obj.type_tag == NULL_TAG) - throw Decoding_Error("cannot decode ECDSA parameters that are ImplicitCA"); - - throw Decoding_Error("encountered unexpected when trying to decode domain parameters"); - } - -bool operator==(const EC_Domain_Params& lhs, const EC_Domain_Params& rhs) - { - return ((lhs.get_curve() == rhs.get_curve()) && - (lhs.get_base_point() == rhs.get_base_point()) && - (lhs.get_order() == rhs.get_order()) && - (lhs.get_cofactor() == rhs.get_cofactor())); + SecureVector<byte> der = DER_encode(EC_DOMPAR_ENC_EXPLICIT); + return PEM_Code::encode(der, "ECC DOMAIN PARAMETERS"); } } - diff --git a/src/pubkey/ec_dompar/ec_dompar.h b/src/pubkey/ec_dompar/ec_dompar.h index f5f573ba9..7da2120cc 100644 --- a/src/pubkey/ec_dompar/ec_dompar.h +++ b/src/pubkey/ec_dompar/ec_dompar.h @@ -2,7 +2,7 @@ * ECC Domain Parameters * * (C) 2007 Falko Strenzke, FlexSecure GmbH -* 2008 Jack Lloyd +* 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -12,16 +12,19 @@ #include <botan/point_gfp.h> #include <botan/curve_gfp.h> -#include <botan/der_enc.h> -#include <botan/ber_dec.h> -#include <botan/alg_id.h> -#include <botan/pubkey_enums.h> +#include <botan/asn1_oid.h> namespace Botan { /** * This class represents elliptic curce domain parameters */ +enum EC_Domain_Params_Encoding { + EC_DOMPAR_ENC_EXPLICIT = 0, + EC_DOMPAR_ENC_IMPLICITCA = 1, + EC_DOMPAR_ENC_OID = 2 +}; + class BOTAN_DLL EC_Domain_Params { public: @@ -36,88 +39,100 @@ class BOTAN_DLL EC_Domain_Params EC_Domain_Params(const CurveGFp& curve, const PointGFp& base_point, const BigInt& order, - const BigInt& cofactor); + const BigInt& cofactor) : + curve(curve), + base_point(base_point), + order(order), + cofactor(cofactor), + oid("") + {} + + /** + * Decode a BER encoded ECC domain parameter set + * @param ber_encoding the bytes of the BER encoding + */ + EC_Domain_Params(const MemoryRegion<byte>& ber_encoding); + + /** + * Create an EC domain by OID (or throw if unknown) + * @param oid the OID of the EC domain to create + */ + EC_Domain_Params(const OID& oid); + + /** + * Create an EC domain from PEM encoding (as from PEM_encode) + * @param pem data + */ + EC_Domain_Params(const std::string& pem = ""); + + /** + * Create the DER encoding of this domain + * @param form of encoding to use + * @returns bytes encododed as DER + */ + SecureVector<byte> DER_encode(EC_Domain_Params_Encoding form) const; + + /** + * Return the PEM encoding (always in explicit form) + * @return string containing PEM data + */ + std::string PEM_encode() const; /** * Return domain parameter curve * @result domain parameter curve */ - const CurveGFp& get_curve() const - { - return m_curve; - } + const CurveGFp& get_curve() const { return curve; } /** * Return domain parameter curve * @result domain parameter curve */ - const PointGFp& get_base_point() const - { - return m_base_point; - } + const PointGFp& get_base_point() const { return base_point; } /** * Return the order of the base point * @result order of the base point */ - const BigInt& get_order() const - { - return m_order; - } + const BigInt& get_order() const { return order; } /** * Return the cofactor * @result the cofactor */ - const BigInt& get_cofactor() const - { - return m_cofactor; - } + const BigInt& get_cofactor() const { return cofactor; } + + bool initialized() const { return !base_point.is_zero(); } /** * Return the OID of these domain parameters * @result the OID */ - std::string get_oid() const { return m_oid; } + std::string get_oid() const { return oid; } + + bool operator==(const EC_Domain_Params& other) const + { + return ((get_curve() == other.get_curve()) && + (get_base_point() == other.get_base_point()) && + (get_order() == other.get_order()) && + (get_cofactor() == other.get_cofactor())); + } private: friend EC_Domain_Params get_EC_Dom_Pars_by_oid(std::string oid); - CurveGFp m_curve; - PointGFp m_base_point; - BigInt m_order; - BigInt m_cofactor; - std::string m_oid; + CurveGFp curve; + PointGFp base_point; + BigInt order, cofactor; + std::string oid; }; -bool BOTAN_DLL operator==(EC_Domain_Params const& lhs, - EC_Domain_Params const& rhs); - inline bool operator!=(const EC_Domain_Params& lhs, const EC_Domain_Params& rhs) { return !(lhs == rhs); } -enum EC_dompar_enc { ENC_EXPLICIT = 0, ENC_IMPLICITCA = 1, ENC_OID = 2 }; - -SecureVector<byte> -BOTAN_DLL encode_der_ec_dompar(EC_Domain_Params const& dom_pars, - EC_dompar_enc enc_type); - -EC_Domain_Params -BOTAN_DLL decode_ber_ec_dompar(SecureVector<byte> const& encoded); - -/** -* Factory function, the only way to obtain EC domain parameters with -* an OID. The demanded OID has to be registered in the InSiTo -* configuration. Consult the file ec_dompar.cpp for the default -* configuration. -* @param oid the oid of the demanded EC domain parameters -* @result the EC domain parameters associated with the OID -*/ -EC_Domain_Params BOTAN_DLL get_EC_Dom_Pars_by_oid(std::string oid); - } #endif diff --git a/src/pubkey/ec_dompar/info.txt b/src/pubkey/ec_dompar/info.txt index fd40b887d..ae6c328e2 100644 --- a/src/pubkey/ec_dompar/info.txt +++ b/src/pubkey/ec_dompar/info.txt @@ -2,7 +2,8 @@ define ECC_DOMAIN_PARAMATERS <requires> asn1 -filters numbertheory -hex +pem +libstate +oid_lookup </requires> diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp index e6d4aeae6..10968fa7e 100644 --- a/src/pubkey/ecc_key/ecc_key.cpp +++ b/src/pubkey/ecc_key/ecc_key.cpp @@ -2,7 +2,7 @@ * ECC Key implemenation * (C) 2007 Manuel Hartl, FlexSecure GmbH * Falko Strenzke, FlexSecure GmbH -* 2008 Jack Lloyd +* 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -17,48 +17,33 @@ namespace Botan { -/* -* EC_PublicKey -*/ -void EC_PublicKey::affirm_init() const // virtual - { - if((mp_dom_pars.get() == 0) || (mp_public_point.get() == 0)) - throw Invalid_State("cannot use uninitialized EC_Key"); - } - -const EC_Domain_Params& EC_PublicKey::domain_parameters() const +EC_PublicKey::EC_PublicKey(const EC_Domain_Params& dom_par, + const PointGFp& pub_point) : + domain_params(dom_par), public_key(pub_point), + domain_encoding(EC_DOMPAR_ENC_EXPLICIT) { - if(!mp_dom_pars.get()) - throw Invalid_State("EC_PublicKey::domain_parameters(): " - "ec domain parameters are not yet set"); - - return *mp_dom_pars; - } - -const PointGFp& EC_PublicKey::public_point() const - { - if(!mp_public_point.get()) - throw Invalid_State("EC_PublicKey::public_point(): public point not set"); - - return *mp_public_point; - } + if(domain().get_curve() != public_point().get_curve()) + throw Invalid_Argument("EC_PublicKey: curve mismatch in constructor"); -bool EC_PublicKey::domain_parameters_set() - { - return mp_dom_pars.get(); + try + { + public_key.check_invariants(); + } + catch(Illegal_Point) + { + throw Invalid_State("Public key failed invariant check"); + } } void EC_PublicKey::X509_load_hook() { try { - // the base point is checked to be on curve already when decoding it - affirm_init(); - mp_public_point->check_invariants(); + public_point().check_invariants(); } catch(Illegal_Point) { - throw Decoding_Error("decoded public point was found not to lie on curve"); + throw Decoding_Error("Invalid public point; not on curve"); } } @@ -69,18 +54,13 @@ X509_Encoder* EC_PublicKey::x509_encoder() const public: AlgorithmIdentifier alg_id() const { - key->affirm_init(); - - SecureVector<byte> params = - encode_der_ec_dompar(key->domain_parameters(), key->m_param_enc); - - return AlgorithmIdentifier(key->get_oid(), params); + return AlgorithmIdentifier(key->get_oid(), + key->domain().DER_encode(key->domain_format())); } MemoryVector<byte> key_bits() const { - key->affirm_init(); - return EC2OSP(*(key->mp_public_point), PointGFp::COMPRESSED); + return EC2OSP(key->public_point(), PointGFp::COMPRESSED); } EC_Key_Encoder(const EC_PublicKey* k): key(k) {} @@ -98,15 +78,13 @@ X509_Decoder* EC_PublicKey::x509_decoder() public: void alg_id(const AlgorithmIdentifier& alg_id) { - key->mp_dom_pars.reset(new EC_Domain_Params(decode_ber_ec_dompar(alg_id.parameters))); + key->domain_params = EC_Domain_Params(alg_id.parameters); } void key_bits(const MemoryRegion<byte>& bits) { - key->mp_public_point.reset( - new PointGFp( - OS2ECP(bits, key->domain_parameters().get_curve()) - )); + key->public_key = PointGFp( + OS2ECP(bits, key->domain().get_curve())); key->X509_load_hook(); } @@ -119,55 +97,58 @@ X509_Decoder* EC_PublicKey::x509_decoder() return new EC_Key_Decoder(this); } -void EC_PublicKey::set_parameter_encoding(EC_dompar_enc type) +void EC_PublicKey::set_parameter_encoding(EC_Domain_Params_Encoding form) { - if((type != ENC_EXPLICIT) && (type != ENC_IMPLICITCA) && (type != ENC_OID)) - throw Invalid_Argument("Invalid encoding type for EC-key object specified"); - - affirm_init(); + if(form != EC_DOMPAR_ENC_EXPLICIT && + form != EC_DOMPAR_ENC_IMPLICITCA && + form != EC_DOMPAR_ENC_OID) + throw Invalid_Argument("Invalid encoding form for EC-key object specified"); - if((type == ENC_OID) && (mp_dom_pars->get_oid() == "")) - throw Invalid_Argument("Invalid encoding type ENC_OID specified for " + if((form == EC_DOMPAR_ENC_OID) && (domain_params.get_oid() == "")) + throw Invalid_Argument("Invalid encoding form OID specified for " "EC-key object whose corresponding domain " "parameters are without oid"); - m_param_enc = type; + domain_encoding = form; } -/* -* EC_PrivateKey -*/ -void EC_PrivateKey::affirm_init() const // virtual +const BigInt& EC_PrivateKey::private_value() const { - if(m_private_value == 0) - throw Invalid_State("cannot use EC_PrivateKey when private key is uninitialized"); + if(private_key == 0) + throw Invalid_State("EC_PrivateKey::private_value - uninitialized"); - EC_PublicKey::affirm_init(); + return private_key; } -const BigInt& EC_PrivateKey::private_value() const +/** +* EC_PrivateKey generator +**/ +EC_PrivateKey::EC_PrivateKey(const EC_Domain_Params& dom_par, + const BigInt& priv_key) : + EC_PublicKey(dom_par, dom_par.get_base_point() * private_key), + private_key(priv_key) { - if(m_private_value == 0) - throw Invalid_State("cannot use EC_PrivateKey when private key is uninitialized"); - - return m_private_value; } /** * EC_PrivateKey generator **/ -void EC_PrivateKey::generate_private_key(RandomNumberGenerator& rng) +EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, + const EC_Domain_Params& dom_par) { - if(mp_dom_pars.get() == 0) - { - throw Invalid_State("cannot generate private key when domain parameters are not set"); - } + domain_params = dom_par; - m_private_value = BigInt::random_integer(rng, 1, mp_dom_pars->get_order()); + private_key = BigInt::random_integer(rng, 1, domain().get_order()); + public_key = domain().get_base_point() * private_key; - mp_public_point = std::unique_ptr<PointGFp>( new PointGFp (mp_dom_pars->get_base_point())); - - *mp_public_point *= m_private_value; + try + { + public_key.check_invariants(); + } + catch(Illegal_Point& e) + { + throw Internal_Error("ECC private key generation failed"); + } } /** @@ -180,24 +161,17 @@ PKCS8_Encoder* EC_PrivateKey::pkcs8_encoder() const public: AlgorithmIdentifier alg_id() const { - key->affirm_init(); - - SecureVector<byte> params = - encode_der_ec_dompar(key->domain_parameters(), ENC_EXPLICIT); - - return AlgorithmIdentifier(key->get_oid(), params); + return AlgorithmIdentifier(key->get_oid(), + key->domain().DER_encode(EC_DOMPAR_ENC_EXPLICIT)); } MemoryVector<byte> key_bits() const { - key->affirm_init(); - SecureVector<byte> octstr_secret = - BigInt::encode_1363(key->m_private_value, key->m_private_value.bytes()); - return DER_Encoder() .start_cons(SEQUENCE) .encode(BigInt(1)) - .encode(octstr_secret, OCTET_STRING) + .encode(BigInt::encode_1363(key->private_key, key->private_key.bytes()), + OCTET_STRING) .end_cons() .get_contents(); } @@ -220,7 +194,7 @@ PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&) public: void alg_id(const AlgorithmIdentifier& alg_id) { - key->mp_dom_pars.reset(new EC_Domain_Params(decode_ber_ec_dompar(alg_id.parameters))); + key->domain_params = EC_Domain_Params(alg_id.parameters); } void key_bits(const MemoryRegion<byte>& bits) @@ -235,7 +209,7 @@ PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&) .verify_end() .end_cons(); - key->m_private_value = BigInt::decode(octstr_secret, octstr_secret.size()); + key->private_key = BigInt::decode(octstr_secret, octstr_secret.size()); if(version != 1) throw Decoding_Error("Wrong PKCS #1 key format version for EC key"); @@ -253,12 +227,7 @@ PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&) void EC_PrivateKey::PKCS8_load_hook(bool) { - // we cannot use affirm_init() here because mp_public_point might still be null - if(mp_dom_pars.get() == 0) - throw Invalid_State("attempt to set public point for an uninitialized key"); - - mp_public_point.reset(new PointGFp(m_private_value * mp_dom_pars->get_base_point())); - mp_public_point->check_invariants(); + public_key = domain().get_base_point() * private_key; } } diff --git a/src/pubkey/ecc_key/ecc_key.h b/src/pubkey/ecc_key/ecc_key.h index f8a419ffe..653f97cab 100644 --- a/src/pubkey/ecc_key/ecc_key.h +++ b/src/pubkey/ecc_key/ecc_key.h @@ -2,7 +2,7 @@ * ECDSA * (C) 2007 Falko Strenzke, FlexSecure GmbH * Manuel Hartl, FlexSecure GmbH -* (C) 2008 Jack Lloyd +* (C) 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -33,18 +33,12 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key public: /** - * Tells whether this key knows his own domain parameters. - * @result true if the domain parameters are set, false otherwise - */ - bool domain_parameters_set(); - - /** * Get the public point of this key. * @throw Invalid_State is thrown if the * domain parameters of this point are not set * @result the public point of this key */ - const PointGFp& public_point() const; + const PointGFp& public_point() const { return public_key; } /** * Get the domain parameters of this key. @@ -52,30 +46,20 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key * domain parameters of this point are not set * @result the domain parameters of this key */ - const EC_Domain_Params& domain_parameters() const; + const EC_Domain_Params& domain() const { return domain_params; } /** * Set the domain parameter encoding to be used when encoding this key. * @param enc the encoding to use */ - void set_parameter_encoding(EC_dompar_enc enc); + void set_parameter_encoding(EC_Domain_Params_Encoding enc); /** * Get the domain parameter encoding to be used when encoding this key. * @result the encoding to use */ - inline int get_parameter_encoding() const - { - return m_param_enc; - } - - //ctors - EC_PublicKey() - : m_param_enc(ENC_EXPLICIT) - { - //assert(mp_dom_pars.get() == 0); - //assert(mp_public_point.get() == 0); - } + EC_Domain_Params_Encoding domain_format() const + { return domain_encoding; } /** * Get an x509_encoder that can be used to encode this key. @@ -90,29 +74,36 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key */ X509_Decoder* x509_decoder(); - /** - * Make sure that the public point and domain parameters of this key are set. - * @throw Invalid_State if either of the two data members is not set - */ - virtual void affirm_init() const; + EC_PublicKey() : domain_encoding(EC_DOMPAR_ENC_EXPLICIT) {} + + EC_PublicKey(const EC_Domain_Params& dom_par, + const PointGFp& pub_point); virtual ~EC_PublicKey() {} protected: virtual void X509_load_hook(); - SecureVector<byte> m_enc_public_point; // stores the public point - - std::unique_ptr<EC_Domain_Params> mp_dom_pars; - std::unique_ptr<PointGFp> mp_public_point; - EC_dompar_enc m_param_enc; + EC_Domain_Params domain_params; + PointGFp public_key; + EC_Domain_Params_Encoding domain_encoding; }; /** * This abstract class represents general EC Private Keys */ -class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, public virtual Private_Key +class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, + public virtual Private_Key { public: + EC_PrivateKey() {} + + EC_PrivateKey(const EC_Domain_Params& domain, + const BigInt& private_key); + + EC_PrivateKey(RandomNumberGenerator& rng, + const EC_Domain_Params& domain); + + virtual ~EC_PrivateKey() {} /** * Get an PKCS#8 encoder that can be used to encoded this key. @@ -132,20 +123,10 @@ class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, public virtual Priv * @result the private key value of this key object */ const BigInt& private_value() const; - - /** - * Make sure that the public key parts of this object are set - * (calls EC_PublicKey::affirm_init()) as well as the private key - * value. - * @throw Invalid_State if the above conditions are not satisfied - */ - virtual void affirm_init() const; - - virtual ~EC_PrivateKey() {} protected: virtual void PKCS8_load_hook(bool = false); - void generate_private_key(RandomNumberGenerator&); - BigInt m_private_value; + + BigInt private_key; }; } diff --git a/src/pubkey/ecdh/ecdh.cpp b/src/pubkey/ecdh/ecdh.cpp new file mode 100644 index 000000000..7577a8569 --- /dev/null +++ b/src/pubkey/ecdh/ecdh.cpp @@ -0,0 +1,51 @@ +/* +* ECDH implemenation +* (C) 2007 Manuel Hartl, FlexSecure GmbH +* 2007 Falko Strenzke, FlexSecure GmbH +* 2008-2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/ecdh.h> + +namespace Botan { + +/** +* Derive a key +*/ +SecureVector<byte> ECDH_PrivateKey::derive_key(const byte key[], + u32bit key_len) const + { + MemoryVector<byte> key_x(key, key_len); // FIXME: nasty/slow + PointGFp point = OS2ECP(key_x, public_point().get_curve()); + + return derive_key(point); + } + +/** +* Derive a key +*/ +SecureVector<byte> ECDH_PrivateKey::derive_key(const ECDH_PublicKey& key) const + { + return derive_key(key.public_point()); + } + +/** +* Derive a key +*/ +SecureVector<byte> ECDH_PrivateKey::derive_key(const PointGFp& point) const + { + const BigInt& cofactor = domain().get_cofactor(); + const BigInt& n = domain().get_order(); + + BigInt l = inverse_mod(cofactor, n); // can precompute this + + PointGFp S = (cofactor * point) * (private_value() * l); + S.check_invariants(); + + return BigInt::encode_1363(S.get_affine_x(), + point.get_curve().get_p().bytes()); + } + +} diff --git a/src/pubkey/ecdh/ecdh.h b/src/pubkey/ecdh/ecdh.h new file mode 100644 index 000000000..630237edf --- /dev/null +++ b/src/pubkey/ecdh/ecdh.h @@ -0,0 +1,102 @@ +/* +* ECDH +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* Manuel Hartl, FlexSecure GmbH +* (C) 2008-2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ECDH_KEY_H__ +#define BOTAN_ECDH_KEY_H__ + +#include <botan/ecc_key.h> + +namespace Botan { + +/** +* This class represents ECDH Public Keys. +*/ +class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey + { + public: + + /** + * Default constructor. Use this one if you want to later fill + * this object with data from an encoded key. + */ + ECDH_PublicKey() {} + + /** + * Construct a public key from a given public point. + * @param dom_par the domain parameters associated with this key + * @param public_point the public point defining this key + */ + ECDH_PublicKey(const EC_Domain_Params& dom_par, + const PointGFp& public_point) : + EC_PublicKey(dom_par, public_point) {} + + /** + * Get this keys algorithm name. + * @result this keys algorithm name + */ + std::string algo_name() const { return "ECDH"; } + + /** + * Get the maximum number of bits allowed to be fed to this key. + * This is the bitlength of the order of the base point. + + * @result the maximum number of input bits + */ + u32bit max_input_bits() const { return domain().get_order().bits(); } + }; + +/** +* This class represents ECDH Private Keys. +*/ +class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, + public EC_PrivateKey, + public PK_Key_Agreement_Key + { + public: + + /** + * Default constructor. Use this one if you want to later fill + * this object with data from an encoded key. + */ + ECDH_PrivateKey() {} + + /** + * Generate a new private key + * @param the domain parameters to used for this key + */ + ECDH_PrivateKey(RandomNumberGenerator& rng, + const EC_Domain_Params& domain) : + EC_PrivateKey(rng, domain) {} + + MemoryVector<byte> public_value() const + { return EC2OSP(public_point(), PointGFp::UNCOMPRESSED); } + + /** + * Derive a shared key with the other parties public key. + * @param key the other partys public key + * @param key_len the other partys public key + */ + SecureVector<byte> derive_key(const byte key[], u32bit key_len) const; + + /** + * Derive a shared key with the other parties public key. + * @param other the other partys public key + */ + SecureVector<byte> derive_key(const ECDH_PublicKey& other) const; + + /** + * Derive a shared key with the other parties public key. + * @param point the public point of the other parties key + */ + SecureVector<byte> derive_key(const PointGFp& point) const; + }; + +} + +#endif diff --git a/src/pubkey/eckaeg/info.txt b/src/pubkey/ecdh/info.txt index cac352a2a..12826c81b 100644 --- a/src/pubkey/eckaeg/info.txt +++ b/src/pubkey/ecdh/info.txt @@ -1,4 +1,4 @@ -define ECKAEG +define ECDH <requires> alloc diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 93c65c3a8..d245543f7 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -2,219 +2,73 @@ * ECDSA implemenation * (C) 2007 Manuel Hartl, FlexSecure GmbH * 2007 Falko Strenzke, FlexSecure GmbH -* 2008 Jack Lloyd +* 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ #include <botan/ecdsa.h> -#include <botan/numthry.h> -#include <botan/der_enc.h> -#include <botan/ber_dec.h> -#include <botan/secmem.h> -#include <botan/point_gfp.h> namespace Botan { -ECDSA_PrivateKey::ECDSA_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& dom_pars) - { - mp_dom_pars = std::unique_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_pars)); - generate_private_key(rng); - - try - { - mp_public_point->check_invariants(); - } - catch(Illegal_Point& e) - { - throw Invalid_State("ECDSA key generation failed"); - } - - m_ecdsa_core = ECDSA_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } - -ECDSA_PrivateKey::ECDSA_PrivateKey(const EC_Domain_Params& domain, - const BigInt& x) - { - mp_dom_pars = std::unique_ptr<EC_Domain_Params>(new EC_Domain_Params(domain)); - - m_private_value = x; - - mp_public_point = std::unique_ptr<PointGFp>(new PointGFp (mp_dom_pars->get_base_point())); - - *mp_public_point *= m_private_value; - - try - { - mp_public_point->check_invariants(); - } - catch(Illegal_Point& e) - { - throw Invalid_State("ECDSA key generation failed"); - } - - m_ecdsa_core = ECDSA_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } - -/* -* ECDSA_PublicKey -*/ -void ECDSA_PublicKey::affirm_init() const // virtual - { - EC_PublicKey::affirm_init(); - } - -void ECDSA_PublicKey::set_domain_parameters(const EC_Domain_Params& dom_pars) - { - if(mp_dom_pars.get()) - { - // they are already set, we must ensure that they are equal to the arg - if(dom_pars != *mp_dom_pars.get()) - throw Invalid_Argument("EC_PublicKey::set_domain_parameters - cannot reset to a new value"); - - return; - } - - if(m_enc_public_point.size() == 0) - throw Invalid_State("EC_PublicKey::set_domain_parameters(): encoded public point isn't set"); - - // now try to decode the public key ... - PointGFp tmp_pp(OS2ECP(m_enc_public_point, dom_pars.get_curve())); - try - { - tmp_pp.check_invariants(); - } - catch(Illegal_Point e) - { - throw Invalid_State("EC_PublicKey::set_domain_parameters(): point does not lie on provided curve"); - } - - mp_dom_pars.reset(new EC_Domain_Params(dom_pars)); - ECDSA_Core tmp_ecdsa_core(*mp_dom_pars, BigInt(0), tmp_pp); - mp_public_point.reset(new PointGFp(tmp_pp)); - m_ecdsa_core = tmp_ecdsa_core; - } - -void ECDSA_PublicKey::set_all_values(const ECDSA_PublicKey& other) - { - m_param_enc = other.m_param_enc; - m_ecdsa_core = other.m_ecdsa_core; - m_enc_public_point = other.m_enc_public_point; - if(other.mp_dom_pars.get()) - mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); - - if(other.mp_public_point.get()) - mp_public_point.reset(new PointGFp(other.public_point())); - } - -ECDSA_PublicKey::ECDSA_PublicKey(const ECDSA_PublicKey& other) - : Public_Key(), - EC_PublicKey(), - PK_Verifying_wo_MR_Key() - { - set_all_values(other); - } - -const ECDSA_PublicKey& ECDSA_PublicKey::operator=(const ECDSA_PublicKey& rhs) - { - set_all_values(rhs); - return *this; - } - bool ECDSA_PublicKey::verify(const byte msg[], u32bit msg_len, const byte sig[], u32bit sig_len) const { - affirm_init(); + const BigInt& n = domain().get_order(); - return m_ecdsa_core.verify(msg, msg_len, sig, sig_len); - } + if(n == 0) + throw Invalid_State("ECDSA_PublicKey::verify: Not initialized"); -ECDSA_PublicKey::ECDSA_PublicKey(const EC_Domain_Params& dom_par, - const PointGFp& public_point) - { - mp_dom_pars = std::unique_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par)); - mp_public_point = std::unique_ptr<PointGFp>(new PointGFp(public_point)); - m_param_enc = ENC_EXPLICIT; - m_ecdsa_core = ECDSA_Core(*mp_dom_pars, BigInt(0), *mp_public_point); - } + if(sig_len != n.bytes()*2) + return false; -void ECDSA_PublicKey::X509_load_hook() - { - EC_PublicKey::X509_load_hook(); - EC_PublicKey::affirm_init(); - m_ecdsa_core = ECDSA_Core ( *mp_dom_pars, BigInt ( 0 ), *mp_public_point ); - } + BigInt e(msg, msg_len); -u32bit ECDSA_PublicKey::max_input_bits() const - { - if(!mp_dom_pars.get()) - { - throw Invalid_State("ECDSA_PublicKey::max_input_bits(): domain parameters not set"); - } - return mp_dom_pars->get_order().bits(); - } + BigInt r(sig, sig_len / 2); + BigInt s(sig + sig_len / 2, sig_len / 2); -/* -* ECDSA_PrivateKey -*/ -void ECDSA_PrivateKey::affirm_init() const // virtual - { - EC_PrivateKey::affirm_init(); - } + if(r < 0 || r >= n || s < 0 || s >= n) + return false; -void ECDSA_PrivateKey::PKCS8_load_hook(bool generated) - { - EC_PrivateKey::PKCS8_load_hook(generated); - EC_PrivateKey::affirm_init(); - m_ecdsa_core = ECDSA_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } + BigInt w = inverse_mod(s, n); -void ECDSA_PrivateKey::set_all_values(const ECDSA_PrivateKey& other) - { - m_private_value = other.m_private_value; - m_param_enc = other.m_param_enc; - m_ecdsa_core = other.m_ecdsa_core; - m_enc_public_point = other.m_enc_public_point; - - if(other.mp_dom_pars.get()) - mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); + PointGFp R = w * (e * domain().get_base_point() + r*public_point()); + if(R.is_zero()) + return false; - if(other.mp_public_point.get()) - mp_public_point.reset(new PointGFp(other.public_point())); - } - -ECDSA_PrivateKey::ECDSA_PrivateKey(ECDSA_PrivateKey const& other) - : Public_Key(), - EC_PublicKey(), - Private_Key(), - ECDSA_PublicKey(), - EC_PrivateKey(), - PK_Signing_Key() - { - set_all_values(other); - } - -const ECDSA_PrivateKey& ECDSA_PrivateKey::operator=(const ECDSA_PrivateKey& rhs) - { - set_all_values(rhs); - return *this; + return (R.get_affine_x() % n == r); } SecureVector<byte> ECDSA_PrivateKey::sign(const byte msg[], u32bit msg_len, RandomNumberGenerator& rng) const { - affirm_init(); + const BigInt& n = domain().get_order(); - const BigInt& n = mp_dom_pars->get_order(); + if(n == 0 || private_value() == 0) + throw Invalid_State("ECDSA_PrivateKey::sign: Not initialized"); BigInt k; do k.randomize(rng, n.bits()-1); while(k >= n); - return m_ecdsa_core.sign(msg, msg_len, k); + BigInt e(msg, msg_len); + + PointGFp k_times_P = domain().get_base_point() * k; + BigInt r = k_times_P.get_affine_x() % n; + + if(r == 0) + throw Internal_Error("Default_ECDSA_Op::sign: r was zero"); + + BigInt k_inv = inverse_mod(k, n); + + BigInt s = (((r * private_value()) + e) * k_inv) % n; + + SecureVector<byte> output(2*n.bytes()); + r.binary_encode(output + (output.size() / 2 - r.bytes())); + s.binary_encode(output + (output.size() - s.bytes())); + return output; } } diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h index ce8c185a5..e7f29b600 100644 --- a/src/pubkey/ecdsa/ecdsa.h +++ b/src/pubkey/ecdsa/ecdsa.h @@ -2,7 +2,7 @@ * ECDSA * (C) 2007 Falko Strenzke, FlexSecure GmbH * Manuel Hartl, FlexSecure GmbH -* (C) 2008 Jack Lloyd +* (C) 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -11,7 +11,6 @@ #define BOTAN_ECDSA_KEY_H__ #include <botan/ecc_key.h> -#include <botan/ecdsa_core.h> namespace Botan { @@ -32,15 +31,14 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey, /** * Get the maximum number of bits allowed to be fed to this key. * This is the bitlength of the order of the base point. - * @result the maximum number of input bits */ - u32bit max_input_bits() const; + u32bit max_input_bits() const { return domain().get_order().bits(); } u32bit message_parts() const { return 2; } u32bit message_part_size() const - { return mp_dom_pars->get_order().bytes(); } + { return domain().get_order().bytes(); } /** * Verify a message with this key. @@ -64,35 +62,9 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey, * @param public_point the public point defining this key */ ECDSA_PublicKey(const EC_Domain_Params& dom_par, - const PointGFp& public_point); // sets core - - ECDSA_PublicKey const& operator=(const ECDSA_PublicKey& rhs); - - ECDSA_PublicKey(const ECDSA_PublicKey& other); - - /** - * Set the domain parameters of this key. This function has to be - * used when a key encoded without domain parameters was decoded into - * this key. Otherwise it will not be able to verify a signature. - * @param dom_pars the domain_parameters associated with this key - * @throw Invalid_Argument if the point was found not to be satisfying the - * curve equation of the provided domain parameters - * or if this key already has domain parameters set - * and these are differing from those given as the parameter - */ - void set_domain_parameters(const EC_Domain_Params& dom_pars); - - /** - * Ensure that the public point and domain parameters of this key are set. - * @throw Invalid_State if either of the two data members is not set - */ - virtual void affirm_init() const; - - protected: - void X509_load_hook(); - void set_all_values(const ECDSA_PublicKey& other); + const PointGFp& public_point) : + EC_PublicKey(dom_par, public_point) {} - ECDSA_Core m_ecdsa_core; }; /** @@ -103,8 +75,6 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, public PK_Signing_Key { public: - //ctors - /** * Default constructor. Use this one if you want to later fill * this object with data from an encoded key. @@ -116,17 +86,16 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, * @param the domain parameters to used for this key */ ECDSA_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& domain); + const EC_Domain_Params& domain) : + EC_PrivateKey(rng, domain) {} /** * Load a private key * @param domain parameters * @param x the private key */ - ECDSA_PrivateKey(const EC_Domain_Params& domain, const BigInt& x); - - ECDSA_PrivateKey(const ECDSA_PrivateKey& other); - ECDSA_PrivateKey const& operator=(const ECDSA_PrivateKey& rhs); + ECDSA_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) : + EC_PrivateKey(domain, x) {} /** * Sign a message with this key. @@ -137,18 +106,6 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, SecureVector<byte> sign(const byte message[], u32bit mess_len, RandomNumberGenerator& rng) const; - - /** - * Make sure that the public key parts of this object are set - * (calls EC_PublicKey::affirm_init()) as well as the private key - * value. - * @throw Invalid_State if the above conditions are not satisfied - */ - virtual void affirm_init() const; - - private: - void set_all_values(const ECDSA_PrivateKey& other); - void PKCS8_load_hook(bool = false); }; } diff --git a/src/pubkey/ecdsa/ecdsa_core.cpp b/src/pubkey/ecdsa/ecdsa_core.cpp deleted file mode 100644 index 78b527786..000000000 --- a/src/pubkey/ecdsa/ecdsa_core.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -* ECDSA Core -* (C) 1999-2007 Jack Lloyd -* (C) 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/ecdsa_core.h> -#include <botan/internal/pk_engine.h> - -namespace Botan { - -/* -* ECDSA Operation -*/ -bool ECDSA_Core::verify(const byte signature[], u32bit sig_len, - const byte message[], u32bit mess_len) const - { - //assert(op.get()); - return op->verify(signature, sig_len, message, mess_len); - } - -SecureVector<byte> ECDSA_Core::sign(const byte message[], - u32bit mess_len, - const BigInt& k) const - { - //assert(op.get()); - return op->sign(message, mess_len, k); - } - -ECDSA_Core& ECDSA_Core::operator=(const ECDSA_Core& core) - { - delete op; - if(core.op) - op = core.op->clone(); - return (*this); - } - -ECDSA_Core::ECDSA_Core(const ECDSA_Core& core) - { - op = 0; - if(core.op) - op = core.op->clone(); - } - -ECDSA_Core::ECDSA_Core(EC_Domain_Params const& dom_pars, const BigInt& priv_key, PointGFp const& pub_key) - { - op = Engine_Core::ecdsa_op(dom_pars, priv_key, pub_key); - } - -} diff --git a/src/pubkey/ecdsa/ecdsa_core.h b/src/pubkey/ecdsa/ecdsa_core.h deleted file mode 100644 index c6583a86f..000000000 --- a/src/pubkey/ecdsa/ecdsa_core.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* ECDSA Core -* (C) 1999-2007 Jack Lloyd -* (C) 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ECDSA_CORE_H__ -#define BOTAN_ECDSA_CORE_H__ - -#include <botan/ecdsa_op.h> -#include <botan/ec_dompar.h> - -namespace Botan { - -/* -* ECDSA Core -*/ -class BOTAN_DLL ECDSA_Core - { - public: - bool verify(const byte signature[], u32bit sig_len, - const byte message[], u32bit mess_len) const; - - SecureVector<byte> sign(const byte message[], u32bit mess_len, - const BigInt& k) const; - - ECDSA_Core& operator=(const ECDSA_Core&); - - ECDSA_Core() { op = 0; } - - ECDSA_Core(const ECDSA_Core&); - - ECDSA_Core(const EC_Domain_Params& dom_pars, - const BigInt& priv_key, - const PointGFp& pub_key); - - ~ECDSA_Core() { delete op; } - private: - ECDSA_Operation* op; - }; - -} - -#endif diff --git a/src/pubkey/ecdsa/ecdsa_op.cpp b/src/pubkey/ecdsa/ecdsa_op.cpp deleted file mode 100644 index dd92ac5c0..000000000 --- a/src/pubkey/ecdsa/ecdsa_op.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* -* ECDSA Operation -* (C) 2007 FlexSecure GmbH -* 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/ecdsa_op.h> -#include <botan/numthry.h> - -namespace Botan { - -Default_ECDSA_Op::Default_ECDSA_Op(const EC_Domain_Params& domain, - const BigInt& priv, - const PointGFp& pub) : - dom_pars(domain), mod_n(dom_pars.get_order()), - pub_key(pub), priv_key(priv) - { - } - -bool Default_ECDSA_Op::verify(const byte msg[], u32bit msg_len, - const byte sig[], u32bit sig_len) const - { - const BigInt& n = dom_pars.get_order(); - - if(sig_len != n.bytes()*2) - return false; - - BigInt e(msg, msg_len); - - BigInt r(sig, sig_len / 2); - BigInt s(sig + sig_len / 2, sig_len / 2); - - if(r < 0 || r >= n || s < 0 || s >= n) - return false; - - BigInt w = inverse_mod(s, n); - - PointGFp R = w * (e * dom_pars.get_base_point() + r*pub_key); - if(R.is_zero()) - return false; - - return (mod_n.reduce(R.get_affine_x()) == r); - } - -SecureVector<byte> Default_ECDSA_Op::sign(const byte msg[], u32bit msg_len, - const BigInt& k) const - { - if(priv_key == 0) - throw Internal_Error("Default_ECDSA_Op::sign(): no private key"); - - const BigInt& n = dom_pars.get_order(); - - BigInt e(msg, msg_len); - - PointGFp k_times_P = dom_pars.get_base_point() * k; - BigInt r = mod_n.reduce(k_times_P.get_affine_x()); - - if(r == 0) - throw Internal_Error("Default_ECDSA_Op::sign: r was zero"); - - BigInt k_inv = inverse_mod(k, n); - - BigInt s = mod_n.reduce(mod_n.multiply(r, priv_key) + e); - s = mod_n.multiply(s, k_inv); - - SecureVector<byte> output(2*n.bytes()); - r.binary_encode(output + (output.size() / 2 - r.bytes())); - s.binary_encode(output + (output.size() - s.bytes())); - return output; - } - -} diff --git a/src/pubkey/ecdsa/ecdsa_op.h b/src/pubkey/ecdsa/ecdsa_op.h deleted file mode 100644 index 3a492ccf4..000000000 --- a/src/pubkey/ecdsa/ecdsa_op.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* ECDSA Operations -* (C) 1999-2008 Jack Lloyd -* (C) 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ECDSA_OPERATIONS_H__ -#define BOTAN_ECDSA_OPERATIONS_H__ - -#include <botan/ec_dompar.h> -#include <botan/reducer.h> - -namespace Botan { - -/* -* ECDSA Operation -*/ -class BOTAN_DLL ECDSA_Operation - { - public: - virtual bool verify(const byte msg[], u32bit msg_len, - const byte sig[], u32bit sig_len) const = 0; - - virtual SecureVector<byte> sign(const byte msg[], u32bit msg_len, - const BigInt& k) const = 0; - - virtual ECDSA_Operation* clone() const = 0; - - virtual ~ECDSA_Operation() {} - }; - -/* -* Default ECDSA operation -*/ -class BOTAN_DLL Default_ECDSA_Op : public ECDSA_Operation - { - public: - bool verify(const byte sig[], u32bit sig_len, - const byte msg[], u32bit msg_len) const; - - SecureVector<byte> sign(const byte msg[], u32bit msg_len, - const BigInt& k) const; - - ECDSA_Operation* clone() const - { - return new Default_ECDSA_Op(*this); - } - - Default_ECDSA_Op(const EC_Domain_Params& dom_pars, - const BigInt& priv_key, - const PointGFp& pub_key); - private: - EC_Domain_Params dom_pars; - Modular_Reducer mod_n; - - PointGFp pub_key; - BigInt priv_key; - }; - -} - -#endif diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt index 799fff32f..ca2694ad1 100644 --- a/src/pubkey/ecdsa/info.txt +++ b/src/pubkey/ecdsa/info.txt @@ -1,11 +1,9 @@ define ECDSA <requires> -alloc asn1 ec_dompar ecc_key -libstate numbertheory rng </requires> diff --git a/src/pubkey/eckaeg/eckaeg.cpp b/src/pubkey/eckaeg/eckaeg.cpp deleted file mode 100644 index 15c817fa7..000000000 --- a/src/pubkey/eckaeg/eckaeg.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* -* ECKAEG implemenation -* (C) 2007 Manuel Hartl, FlexSecure GmbH -* 2007 Falko Strenzke, FlexSecure GmbH -* 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/eckaeg.h> -#include <botan/numthry.h> -#include <botan/der_enc.h> -#include <botan/ber_dec.h> -#include <botan/secmem.h> -#include <botan/point_gfp.h> - -namespace Botan { - -/* -* ECKAEG_PublicKey -*/ - -void ECKAEG_PublicKey::affirm_init() const // virtual - { - EC_PublicKey::affirm_init(); - } - -void ECKAEG_PublicKey::set_all_values(ECKAEG_PublicKey const& other) - { - m_param_enc = other.m_param_enc; - m_eckaeg_core = other.m_eckaeg_core; - m_enc_public_point = other.m_enc_public_point; - if(other.mp_dom_pars.get()) - { - mp_dom_pars.reset(new EC_Domain_Params(*(other.mp_dom_pars))); - } - if(other.mp_public_point.get()) - { - mp_public_point.reset(new PointGFp(*(other.mp_public_point))); - } - } - -ECKAEG_PublicKey::ECKAEG_PublicKey(ECKAEG_PublicKey const& other) - : Public_Key(), - EC_PublicKey() - { - set_all_values(other); - } - -ECKAEG_PublicKey const& ECKAEG_PublicKey::operator=(ECKAEG_PublicKey const& rhs) - { - set_all_values(rhs); - return *this; - } - -void ECKAEG_PublicKey::X509_load_hook() - { - EC_PublicKey::X509_load_hook(); - EC_PublicKey::affirm_init(); - m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, BigInt(0), *mp_public_point); - } - -ECKAEG_PublicKey::ECKAEG_PublicKey(EC_Domain_Params const& dom_par, PointGFp const& public_point) - { - mp_dom_pars = std::unique_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par)); - mp_public_point = std::unique_ptr<PointGFp>(new PointGFp(public_point)); - if(mp_public_point->get_curve() != mp_dom_pars->get_curve()) - { - throw Invalid_Argument("ECKAEG_PublicKey(): curve of arg. point and curve of arg. domain parameters are different"); - } - EC_PublicKey::affirm_init(); - m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, BigInt(0), *mp_public_point); - } - -/* -* ECKAEG_PrivateKey -*/ -void ECKAEG_PrivateKey::affirm_init() const // virtual - { - EC_PrivateKey::affirm_init(); - } - -void ECKAEG_PrivateKey::PKCS8_load_hook(bool generated) - { - EC_PrivateKey::PKCS8_load_hook(generated); - EC_PrivateKey::affirm_init(); - m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } - -void ECKAEG_PrivateKey::set_all_values(ECKAEG_PrivateKey const& other) - { - m_private_value = other.m_private_value; - m_param_enc = other.m_param_enc; - m_eckaeg_core = other.m_eckaeg_core; - m_enc_public_point = other.m_enc_public_point; - if(other.mp_dom_pars.get()) - { - mp_dom_pars.reset(new EC_Domain_Params(*(other.mp_dom_pars))); - } - if(other.mp_public_point.get()) - { - mp_public_point.reset(new PointGFp(*(other.mp_public_point))); - } - } - -ECKAEG_PrivateKey::ECKAEG_PrivateKey(ECKAEG_PrivateKey const& other) - : Public_Key(), - EC_PublicKey(), - Private_Key(), - ECKAEG_PublicKey(), - EC_PrivateKey(), - PK_Key_Agreement_Key() - { - set_all_values(other); - } - -ECKAEG_PrivateKey const& ECKAEG_PrivateKey::operator= (ECKAEG_PrivateKey const& rhs) - { - set_all_values(rhs); - return *this; - } - -MemoryVector<byte> ECKAEG_PrivateKey::public_value() const - { - return EC2OSP(public_point(), PointGFp::UNCOMPRESSED); - } - -/** -* Derive a key -*/ -SecureVector<byte> ECKAEG_PrivateKey::derive_key(const byte key[], - u32bit key_len) const - { - MemoryVector<byte> key_x(key, key_len); // FIXME: nasty/slow - PointGFp point = OS2ECP(key_x, public_point().get_curve()); - - return m_eckaeg_core.agree(point); - } - -/** -* Derive a key -*/ -SecureVector<byte> ECKAEG_PrivateKey::derive_key(const ECKAEG_PublicKey& key) const - { - affirm_init(); - key.affirm_init(); - - return m_eckaeg_core.agree(key.public_point()); - } - -} diff --git a/src/pubkey/eckaeg/eckaeg.h b/src/pubkey/eckaeg/eckaeg.h deleted file mode 100644 index b8c164967..000000000 --- a/src/pubkey/eckaeg/eckaeg.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -* ECKAEG -* (C) 2007 Falko Strenzke, FlexSecure GmbH -* Manuel Hartl, FlexSecure GmbH -* (C) 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ECKAEG_KEY_H__ -#define BOTAN_ECKAEG_KEY_H__ - -#include <botan/ecc_key.h> -#include <botan/eckaeg_core.h> - -namespace Botan { - -/** -* This class represents ECKAEG Public Keys. -*/ -class BOTAN_DLL ECKAEG_PublicKey : public virtual EC_PublicKey - { - public: - - /** - * Default constructor. Use this one if you want to later fill - * this object with data from an encoded key. - */ - ECKAEG_PublicKey() {} - - /** - * Construct a public key from a given public point. - * @param dom_par the domain parameters associated with this key - * @param public_point the public point defining this key - */ - ECKAEG_PublicKey(const EC_Domain_Params& dom_par, - const PointGFp& public_point); - - /** - * Get this keys algorithm name. - * @result this keys algorithm name - */ - std::string algo_name() const { return "ECKAEG"; } - - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - - * @result the maximum number of input bits - */ - u32bit max_input_bits() const - { - if(!mp_dom_pars.get()) - throw Invalid_State("ECKAEG_PublicKey::max_input_bits(): domain parameters not set"); - - return mp_dom_pars->get_order().bits(); - } - - ECKAEG_PublicKey(ECKAEG_PublicKey const& other); - ECKAEG_PublicKey const& operator= (ECKAEG_PublicKey const& rhs); - - /** - * Make sure that the public point and domain parameters of this - * key are set. - * @throw Invalid_State if either of the two data members is not set - */ - virtual void affirm_init() const; - - protected: - void X509_load_hook(); - - ECKAEG_Core m_eckaeg_core; - private: - void set_all_values(const ECKAEG_PublicKey& other); - }; - -/** -* This class represents ECKAEG Private Keys. -*/ -class BOTAN_DLL ECKAEG_PrivateKey : public ECKAEG_PublicKey, - public EC_PrivateKey, - public PK_Key_Agreement_Key - { - public: - - /** - * Generate a new private key - * @param the domain parameters to used for this key - */ - ECKAEG_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& dom_pars) - { - mp_dom_pars = std::unique_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_pars)); - generate_private_key(rng); - mp_public_point->check_invariants(); - m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } - - /** - * Default constructor. Use this one if you want to later fill this object with data - * from an encoded key. - */ - ECKAEG_PrivateKey() {} - ECKAEG_PrivateKey(ECKAEG_PrivateKey const& other); - ECKAEG_PrivateKey const& operator=(ECKAEG_PrivateKey const& rhs); - - MemoryVector<byte> public_value() const; - - void PKCS8_load_hook(bool = false); - - /** - * Derive a shared key with the other partys public key. - * @param key the other partys public key - * @param key_len the other partys public key - */ - SecureVector<byte> derive_key(const byte key[], u32bit key_len) const; - - /** - * Derive a shared key with the other partys public key. - * @param other the other partys public key - */ - SecureVector<byte> derive_key(const ECKAEG_PublicKey& other) const; - - /** - * Make sure that the public key parts of this object are set - * (calls EC_PublicKey::affirm_init()) as well as the private key - * value. - * @throw Invalid_State if the above conditions are not satisfied - */ - virtual void affirm_init() const; - - private: - void set_all_values(const ECKAEG_PrivateKey& other); - }; - -} - -#endif diff --git a/src/pubkey/eckaeg/eckaeg_core.cpp b/src/pubkey/eckaeg/eckaeg_core.cpp deleted file mode 100644 index eaf467933..000000000 --- a/src/pubkey/eckaeg/eckaeg_core.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -* ECKAEG Core -* (C) 1999-2007 Jack Lloyd -* (C) 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/eckaeg_core.h> -#include <botan/numthry.h> -#include <botan/internal/pk_engine.h> -#include <botan/parsing.h> -#include <algorithm> - -namespace Botan { - -/* -* ECKAEG_Core Constructor -*/ -ECKAEG_Core::ECKAEG_Core(const EC_Domain_Params& dom_pars, - const BigInt& priv_key, - const PointGFp& pub_key) - { - op = Engine_Core::eckaeg_op(dom_pars, priv_key, pub_key); - } - -/* -* ECKAEG_Core Copy Constructor -*/ -ECKAEG_Core::ECKAEG_Core(const ECKAEG_Core& core) - { - op = 0; - if(core.op) - op = core.op->clone(); - blinder = core.blinder; - } - -/* -* ECKAEG_Core Assignment Operator -*/ -ECKAEG_Core& ECKAEG_Core::operator=(const ECKAEG_Core& core) - { - delete op; - if(core.op) - op = core.op->clone(); - blinder = core.blinder; - return (*this); - } - -/* -* ECKAEG Operation -*/ -SecureVector<byte> ECKAEG_Core::agree(const PointGFp& otherKey) const - { - //assert(op.get()); - return op->agree(otherKey); - } - -} diff --git a/src/pubkey/eckaeg/eckaeg_core.h b/src/pubkey/eckaeg/eckaeg_core.h deleted file mode 100644 index d632c9451..000000000 --- a/src/pubkey/eckaeg/eckaeg_core.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* ECKAEG Core -* (C) 1999-2007 Jack Lloyd -* (C) 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ECKAEG_CORE_H__ -#define BOTAN_ECKAEG_CORE_H__ - -#include <botan/eckaeg_op.h> -#include <botan/blinding.h> -#include <botan/ec_dompar.h> - -namespace Botan { - -/* -* ECKAEG Core -*/ -class BOTAN_DLL ECKAEG_Core - { - public: - SecureVector<byte> agree(const PointGFp&) const; - - ECKAEG_Core& operator=(const ECKAEG_Core&); - - ECKAEG_Core() { op = 0; } - - ECKAEG_Core(const ECKAEG_Core&); - - ECKAEG_Core(const EC_Domain_Params& dom_pars, - const BigInt& priv_key, - PointGFp const& pub_key); - - ~ECKAEG_Core() { delete op; } - private: - ECKAEG_Operation* op; - Blinder blinder; - }; - -} - -#endif diff --git a/src/pubkey/eckaeg/eckaeg_op.cpp b/src/pubkey/eckaeg/eckaeg_op.cpp deleted file mode 100644 index 4fb0a23eb..000000000 --- a/src/pubkey/eckaeg/eckaeg_op.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* -* ECKAEG Operation -* (C) 2007 FlexSecure GmbH -* 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/eckaeg_op.h> -#include <botan/numthry.h> - -namespace Botan { - -Default_ECKAEG_Op::Default_ECKAEG_Op(const EC_Domain_Params& dom_pars, - const BigInt& priv_key, - const PointGFp& pub_key) - : m_dom_pars(dom_pars), - m_pub_key(pub_key), - m_priv_key(priv_key) - { - } - -SecureVector<byte> Default_ECKAEG_Op::agree(const PointGFp& i) const - { - BigInt cofactor = m_dom_pars.get_cofactor(); - BigInt n = m_dom_pars.get_order(); - - BigInt l = inverse_mod(cofactor, n); - - PointGFp S = cofactor * i; - S *= (m_priv_key * l) % n; - - S.check_invariants(); - - return BigInt::encode_1363(S.get_affine_x(), - S.get_curve().get_p().bytes()); - } - -} diff --git a/src/pubkey/eckaeg/eckaeg_op.h b/src/pubkey/eckaeg/eckaeg_op.h deleted file mode 100644 index 27cf4f367..000000000 --- a/src/pubkey/eckaeg/eckaeg_op.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* ECKAEG Operations -* (C) 1999-2008 Jack Lloyd -* 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ECKAEG_OPERATIONS_H__ -#define BOTAN_ECKAEG_OPERATIONS_H__ - -#include <botan/ec_dompar.h> - -namespace Botan { - -/* -* ECKAEG Operation -*/ -class BOTAN_DLL ECKAEG_Operation - { - public: - virtual SecureVector<byte> agree(const PointGFp&) const = 0; - virtual ECKAEG_Operation* clone() const = 0; - virtual ~ECKAEG_Operation() {} - }; - -/* -* Default ECKAEG operation -*/ -class BOTAN_DLL Default_ECKAEG_Op : public ECKAEG_Operation - { - public: - SecureVector<byte> agree(const PointGFp& i) const; - - ECKAEG_Operation* clone() const { return new Default_ECKAEG_Op(*this); } - - Default_ECKAEG_Op(const EC_Domain_Params& dom_pars, - const BigInt& priv_key, - const PointGFp& pub_key); - private: - EC_Domain_Params m_dom_pars; - PointGFp m_pub_key; - BigInt m_priv_key; - }; - - -} - -#endif diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp index d3e98665d..8dd72dfc1 100644 --- a/src/pubkey/gost_3410/gost_3410.cpp +++ b/src/pubkey/gost_3410/gost_3410.cpp @@ -16,42 +16,6 @@ namespace Botan { -GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& dom_pars) - { - mp_dom_pars = std::unique_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_pars)); - generate_private_key(rng); - - try - { - mp_public_point->check_invariants(); - } - catch(Illegal_Point& e) - { - throw Invalid_State("GOST_3410 key generation failed"); - } - } - -GOST_3410_PrivateKey::GOST_3410_PrivateKey(const EC_Domain_Params& domain, - const BigInt& x) - { - mp_dom_pars = std::unique_ptr<EC_Domain_Params>(new EC_Domain_Params(domain)); - - m_private_value = x; - mp_public_point = std::unique_ptr<PointGFp>(new PointGFp (mp_dom_pars->get_base_point())); - - *mp_public_point *= m_private_value; - - try - { - mp_public_point->check_invariants(); - } - catch(Illegal_Point) - { - throw Invalid_State("GOST_3410 key generation failed"); - } - } - X509_Encoder* GOST_3410_PublicKey::x509_encoder() const { class GOST_3410_Key_Encoder : public X509_Encoder @@ -59,21 +23,15 @@ X509_Encoder* GOST_3410_PublicKey::x509_encoder() const public: AlgorithmIdentifier alg_id() const { - key->affirm_init(); - - SecureVector<byte> params = - encode_der_ec_dompar(key->domain_parameters(), key->m_param_enc); - - return AlgorithmIdentifier(key->get_oid(), params); + return AlgorithmIdentifier(key->get_oid(), + key->domain().DER_encode(key->domain_format())); } MemoryVector<byte> key_bits() const { - key->affirm_init(); - // Trust CryptoPro to come up with something obnoxious - const BigInt x = key->mp_public_point->get_affine_x(); - const BigInt y = key->mp_public_point->get_affine_y(); + const BigInt x = key->public_point().get_affine_x(); + const BigInt y = key->public_point().get_affine_y(); SecureVector<byte> bits(2*std::max(x.bytes(), y.bytes())); @@ -104,9 +62,7 @@ X509_Decoder* GOST_3410_PublicKey::x509_decoder() BER_Decoder ber(alg_id.parameters); ber.start_cons(SEQUENCE).decode(ecc_param_id); - EC_Domain_Params ecc_params = get_EC_Dom_Pars_by_oid(ecc_param_id.as_string()); - - key->mp_dom_pars.reset(new EC_Domain_Params(ecc_params)); + key->domain_params = EC_Domain_Params(ecc_param_id); } void key_bits(const MemoryRegion<byte>& bits) @@ -121,11 +77,9 @@ X509_Decoder* GOST_3410_PublicKey::x509_decoder() BigInt y(key_bits, part_size); BigInt x(key_bits + part_size, part_size); - const BigInt p = key->domain_parameters().get_curve().get_p(); + const BigInt p = key->domain().get_curve().get_p(); - key->mp_public_point.reset( - new PointGFp(key->domain_parameters().get_curve(), - x, y)); + key->public_key = PointGFp(key->domain().get_curve(), x, y); key->X509_load_hook(); } @@ -138,80 +92,16 @@ X509_Decoder* GOST_3410_PublicKey::x509_decoder() return new GOST_3410_Key_Decoder(this); } -/* -* GOST_3410_PublicKey -*/ -void GOST_3410_PublicKey::affirm_init() const // virtual - { - EC_PublicKey::affirm_init(); - } - -void GOST_3410_PublicKey::set_domain_parameters(const EC_Domain_Params& dom_pars) - { - if(mp_dom_pars.get()) - { - // they are already set, we must ensure that they are equal to the arg - if(dom_pars != *mp_dom_pars.get()) - throw Invalid_Argument("EC_PublicKey::set_domain_parameters - cannot reset to a new value"); - - return; - } - - if(m_enc_public_point.size() == 0) - throw Invalid_State("EC_PublicKey::set_domain_parameters(): encoded public point isn't set"); - - // now try to decode the public key ... - PointGFp tmp_pp(OS2ECP(m_enc_public_point, dom_pars.get_curve())); - try - { - tmp_pp.check_invariants(); - } - catch(Illegal_Point e) - { - throw Invalid_State("EC_PublicKey::set_domain_parameters(): point does not lie on provided curve"); - } - - mp_public_point.reset(new PointGFp(tmp_pp)); - mp_dom_pars.reset(new EC_Domain_Params(dom_pars)); - } - -void GOST_3410_PublicKey::set_all_values(const GOST_3410_PublicKey& other) - { - m_param_enc = other.m_param_enc; - m_enc_public_point = other.m_enc_public_point; - if(other.mp_dom_pars.get()) - mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); - - if(other.mp_public_point.get()) - mp_public_point.reset(new PointGFp(other.public_point())); - } - -GOST_3410_PublicKey::GOST_3410_PublicKey(const GOST_3410_PublicKey& other) - : Public_Key(), - EC_PublicKey(), - PK_Verifying_wo_MR_Key() - { - set_all_values(other); - } - -const GOST_3410_PublicKey& GOST_3410_PublicKey::operator=(const GOST_3410_PublicKey& rhs) - { - set_all_values(rhs); - return *this; - } - bool GOST_3410_PublicKey::verify(const byte msg[], u32bit msg_len, const byte sig[], u32bit sig_len) const { - affirm_init(); - - const BigInt& n = mp_dom_pars->get_order(); + const BigInt& n = domain().get_order(); if(sig_len != n.bytes()*2) return false; // NOTE: it is not checked whether the public point is set - if(mp_dom_pars->get_curve().get_p() == 0) + if(domain().get_curve().get_p() == 0) throw Internal_Error("domain parameters not set"); BigInt e(msg, msg_len); @@ -231,76 +121,17 @@ bool GOST_3410_PublicKey::verify(const byte msg[], u32bit msg_len, BigInt z1 = (s*v) % n; BigInt z2 = (-r*v) % n; - PointGFp R = (z1 * mp_dom_pars->get_base_point() + z2 * *mp_public_point); + PointGFp R = (z1 * domain().get_base_point() + z2 * public_point()); return (R.get_affine_x() == r); } GOST_3410_PublicKey::GOST_3410_PublicKey(const EC_Domain_Params& dom_par, - const PointGFp& public_point) - { - mp_dom_pars = std::unique_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par)); - mp_public_point = std::unique_ptr<PointGFp>(new PointGFp(public_point)); - m_param_enc = ENC_EXPLICIT; - } - -void GOST_3410_PublicKey::X509_load_hook() - { - EC_PublicKey::X509_load_hook(); - EC_PublicKey::affirm_init(); - } - -u32bit GOST_3410_PublicKey::max_input_bits() const - { - if(!mp_dom_pars.get()) - { - throw Invalid_State("GOST_3410_PublicKey::max_input_bits(): domain parameters not set"); - } - return mp_dom_pars->get_order().bits(); - } - -/************************* -* GOST_3410_PrivateKey -*************************/ -void GOST_3410_PrivateKey::affirm_init() const // virtual - { - EC_PrivateKey::affirm_init(); - } - -void GOST_3410_PrivateKey::PKCS8_load_hook(bool generated) + const PointGFp& pub_point) { - EC_PrivateKey::PKCS8_load_hook(generated); - EC_PrivateKey::affirm_init(); - } - -void GOST_3410_PrivateKey::set_all_values(const GOST_3410_PrivateKey& other) - { - m_private_value = other.m_private_value; - m_param_enc = other.m_param_enc; - m_enc_public_point = other.m_enc_public_point; - - if(other.mp_dom_pars.get()) - mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); - - if(other.mp_public_point.get()) - mp_public_point.reset(new PointGFp(other.public_point())); - } - -GOST_3410_PrivateKey::GOST_3410_PrivateKey(GOST_3410_PrivateKey const& other) - : Public_Key(), - EC_PublicKey(), - Private_Key(), - GOST_3410_PublicKey(), - EC_PrivateKey(), - PK_Signing_Key() - { - set_all_values(other); - } - -const GOST_3410_PrivateKey& GOST_3410_PrivateKey::operator=(const GOST_3410_PrivateKey& rhs) - { - set_all_values(rhs); - return *this; + domain_params = dom_par; + public_key = pub_point; + domain_encoding = EC_DOMPAR_ENC_EXPLICIT; } SecureVector<byte> @@ -308,16 +139,14 @@ GOST_3410_PrivateKey::sign(const byte msg[], u32bit msg_len, RandomNumberGenerator& rng) const { - affirm_init(); - - const BigInt& n = mp_dom_pars->get_order(); + const BigInt& n = domain().get_order(); BigInt k; do k.randomize(rng, n.bits()-1); while(k >= n); - if(m_private_value == 0) + if(private_value() == 0) throw Internal_Error("GOST_3410::sign(): no private key"); if(n == 0) @@ -329,7 +158,7 @@ GOST_3410_PrivateKey::sign(const byte msg[], if(e == 0) e = 1; - PointGFp k_times_P = mp_dom_pars->get_base_point() * k; + PointGFp k_times_P = domain().get_base_point() * k; k_times_P.check_invariants(); BigInt r = k_times_P.get_affine_x() % n; @@ -337,7 +166,7 @@ GOST_3410_PrivateKey::sign(const byte msg[], if(r == 0) throw Internal_Error("GOST_3410::sign: r was zero"); - BigInt s = (r*m_private_value + k*e) % n; + BigInt s = (r*private_value() + k*e) % n; SecureVector<byte> output(2*n.bytes()); r.binary_encode(output + (output.size() / 2 - r.bytes())); diff --git a/src/pubkey/gost_3410/gost_3410.h b/src/pubkey/gost_3410/gost_3410.h index 460aca9bf..8104cbb75 100644 --- a/src/pubkey/gost_3410/gost_3410.h +++ b/src/pubkey/gost_3410/gost_3410.h @@ -34,12 +34,12 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, * @result the maximum number of input bits */ - u32bit max_input_bits() const; + u32bit max_input_bits() const { return domain().get_order().bits(); } u32bit message_parts() const { return 2; } u32bit message_part_size() const - { return mp_dom_pars->get_order().bytes(); } + { return domain().get_order().bytes(); } /** * Verify a message with this key. @@ -63,29 +63,7 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, * @param public_point the public point defining this key */ GOST_3410_PublicKey(const EC_Domain_Params& dom_par, - const PointGFp& public_point); // sets core - - GOST_3410_PublicKey const& operator=(const GOST_3410_PublicKey& rhs); - - GOST_3410_PublicKey(const GOST_3410_PublicKey& other); - - /** - * Set the domain parameters of this key. This function has to be - * used when a key encoded without domain parameters was decoded into - * this key. Otherwise it will not be able to verify a signature. - * @param dom_pars the domain_parameters associated with this key - * @throw Invalid_Argument if the point was found not to be satisfying the - * curve equation of the provided domain parameters - * or if this key already has domain parameters set - * and these are differing from those given as the parameter - */ - void set_domain_parameters(const EC_Domain_Params& dom_pars); - - /** - * Ensure that the public point and domain parameters of this key are set. - * @throw Invalid_State if either of the two data members is not set - */ - virtual void affirm_init() const; + const PointGFp& public_point); /** * Get an x509_encoder that can be used to encode this key. @@ -99,10 +77,6 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, * @result an x509_decoder for this key */ X509_Decoder* x509_decoder(); - - protected: - void X509_load_hook(); - void set_all_values(const GOST_3410_PublicKey& other); }; /** @@ -124,17 +98,16 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, * @param the domain parameters to used for this key */ GOST_3410_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& domain); + const EC_Domain_Params& domain) : + EC_PrivateKey(rng, domain) {} /** * Load a private key * @param domain parameters * @param x the private key */ - GOST_3410_PrivateKey(const EC_Domain_Params& domain, const BigInt& x); - - GOST_3410_PrivateKey(const GOST_3410_PrivateKey& other); - GOST_3410_PrivateKey const& operator=(const GOST_3410_PrivateKey& rhs); + GOST_3410_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) : + EC_PrivateKey(domain, x) {} /** * Sign a message with this key. @@ -142,21 +115,8 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, * @param mess_len the length of the message byte array * @result the signature */ - SecureVector<byte> sign(const byte message[], u32bit mess_len, RandomNumberGenerator& rng) const; - - /** - * Make sure that the public key parts of this object are set - * (calls EC_PublicKey::affirm_init()) as well as the private key - * value. - * @throw Invalid_State if the above conditions are not satisfied - */ - virtual void affirm_init() const; - - private: - void set_all_values(const GOST_3410_PrivateKey& other); - void PKCS8_load_hook(bool = false); }; } |