Botan  1.11.15
src/lib/pk_pad/emsa1/emsa1.cpp
Go to the documentation of this file.
00001 /*
00002 * EMSA1
00003 * (C) 1999-2007 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/pad_utils.h>
00009 #include <botan/emsa1.h>
00010 
00011 namespace Botan {
00012 
00013 BOTAN_REGISTER_EMSA_1HASH(EMSA1, "EMSA1");
00014 
00015 namespace {
00016 
00017 secure_vector<byte> emsa1_encoding(const secure_vector<byte>& msg,
00018                                   size_t output_bits)
00019    {
00020    if(8*msg.size() <= output_bits)
00021       return msg;
00022 
00023    size_t shift = 8*msg.size() - output_bits;
00024 
00025    size_t byte_shift = shift / 8, bit_shift = shift % 8;
00026    secure_vector<byte> digest(msg.size() - byte_shift);
00027 
00028    for(size_t j = 0; j != msg.size() - byte_shift; ++j)
00029       digest[j] = msg[j];
00030 
00031    if(bit_shift)
00032       {
00033       byte carry = 0;
00034       for(size_t j = 0; j != digest.size(); ++j)
00035          {
00036          byte temp = digest[j];
00037          digest[j] = (temp >> bit_shift) | carry;
00038          carry = (temp << (8 - bit_shift));
00039          }
00040       }
00041    return digest;
00042    }
00043 
00044 }
00045 
00046 void EMSA1::update(const byte input[], size_t length)
00047    {
00048    m_hash->update(input, length);
00049    }
00050 
00051 secure_vector<byte> EMSA1::raw_data()
00052    {
00053    return m_hash->final();
00054    }
00055 
00056 secure_vector<byte> EMSA1::encoding_of(const secure_vector<byte>& msg,
00057                                        size_t output_bits,
00058                                        RandomNumberGenerator&)
00059    {
00060    if(msg.size() != hash_output_length())
00061       throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
00062    return emsa1_encoding(msg, output_bits);
00063    }
00064 
00065 bool EMSA1::verify(const secure_vector<byte>& coded,
00066                    const secure_vector<byte>& raw, size_t key_bits)
00067    {
00068    try {
00069       if(raw.size() != m_hash->output_length())
00070          throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
00071 
00072       secure_vector<byte> our_coding = emsa1_encoding(raw, key_bits);
00073 
00074       if(our_coding == coded) return true;
00075       if(our_coding.empty() || our_coding[0] != 0) return false;
00076       if(our_coding.size() <= coded.size()) return false;
00077 
00078       size_t offset = 0;
00079       while(offset < our_coding.size() && our_coding[offset] == 0)
00080          ++offset;
00081       if(our_coding.size() - offset != coded.size())
00082          return false;
00083 
00084       for(size_t j = 0; j != coded.size(); ++j)
00085          if(coded[j] != our_coding[j+offset])
00086             return false;
00087 
00088       return true;
00089       }
00090    catch(Invalid_Argument)
00091       {
00092       return false;
00093       }
00094    }
00095 
00096 }