Botan
1.11.15
|
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 }