/* PIP - Platform Independent Primitives Digest algorithms Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "pidigest.h" #include "pidigest_blake2_p.h" #include "pidigest_md2_p.h" #include "pidigest_md4_p.h" #include "pidigest_md5_p.h" #include "pidigest_sha1_p.h" #include "pidigest_sha2_p.h" #include "pidigest_siphash_p.h" int PIDigest::hashLength(Type type) { switch (type) { case Type::MD2: return 16; case Type::MD4: return 16; case Type::MD5: return 16; case Type::SHA1: return 20; case Type::SHA2_224: return 28; case Type::SHA2_256: return 32; case Type::SHA2_384: return 48; case Type::SHA2_512: return 64; case Type::SHA2_512_224: return 28; case Type::SHA2_512_256: return 32; case Type::BLAKE2s_128: return 16; case Type::BLAKE2s_160: return 20; case Type::BLAKE2s_224: return 28; case Type::BLAKE2s_256: return 32; case Type::BLAKE2b_128: return 16; case Type::BLAKE2b_160: return 20; case Type::BLAKE2b_224: return 28; case Type::BLAKE2b_256: return 32; case Type::BLAKE2b_384: return 48; case Type::BLAKE2b_512: return 64; case Type::SipHash_2_4_64: return 8; case Type::SipHash_2_4_128: return 16; case Type::HalfSipHash_2_4_32: return 4; case Type::HalfSipHash_2_4_64: return 8; default: break; } return 0; } int PIDigest::blockLength(Type type) { switch (type) { case Type::MD2: return 16; case Type::MD4: case Type::MD5: return 64; case Type::SHA1: return 64; case Type::SHA2_224: case Type::SHA2_256: return 64; case Type::SHA2_384: case Type::SHA2_512: case Type::SHA2_512_224: case Type::SHA2_512_256: return 128; case Type::BLAKE2s_128: case Type::BLAKE2s_160: case Type::BLAKE2s_224: case Type::BLAKE2s_256: return 64; case Type::BLAKE2b_128: case Type::BLAKE2b_160: case Type::BLAKE2b_224: case Type::BLAKE2b_256: case Type::BLAKE2b_384: case Type::BLAKE2b_512: return 128; case Type::SipHash_2_4_64: return 8; case Type::SipHash_2_4_128: return 16; case Type::HalfSipHash_2_4_32: return 4; case Type::HalfSipHash_2_4_64: return 8; default: break; } return 0; } PIConstChars PIDigest::typeName(Type type) { switch (type) { case Type::MD2: return "MD2"; case Type::MD4: return "MD4"; case Type::MD5: return "MD5"; case Type::SHA1: return "SHA1"; case Type::SHA2_224: return "SHA2_224"; case Type::SHA2_256: return "SHA2_256"; case Type::SHA2_384: return "SHA2_384"; case Type::SHA2_512: return "SHA2_512"; case Type::SHA2_512_224: return "SHA2_512_224"; case Type::SHA2_512_256: return "SHA2_512_256"; case Type::BLAKE2s_128: return "BLAKE2s_128"; case Type::BLAKE2s_160: return "BLAKE2s_160"; case Type::BLAKE2s_224: return "BLAKE2s_224"; case Type::BLAKE2s_256: return "BLAKE2s_256"; case Type::BLAKE2b_128: return "BLAKE2b_128"; case Type::BLAKE2b_160: return "BLAKE2b_160"; case Type::BLAKE2b_224: return "BLAKE2b_224"; case Type::BLAKE2b_256: return "BLAKE2b_256"; case Type::BLAKE2b_384: return "BLAKE2b_384"; case Type::BLAKE2b_512: return "BLAKE2b_512"; case Type::SipHash_2_4_64: return "SipHash_2_4_64"; case Type::SipHash_2_4_128: return "SipHash_2_4_128"; case Type::HalfSipHash_2_4_32: return "HalfSipHash_2_4_32"; case Type::HalfSipHash_2_4_64: return "HalfSipHash_2_4_64"; default: break; } return "Unknown"; } PIByteArray PIDigest::calculate(const PIByteArray & msg, Type type) { switch (type) { case Type::MD2: return MD2::md2(msg); case Type::MD4: return MD4::md4(msg); case Type::MD5: return MD5::md5(msg); case Type::SHA1: return SHA1::sha1(msg); case Type::SHA2_224: return SHA2::sha2xx(msg, SHA2::initial_224, 28); case Type::SHA2_256: return SHA2::sha2xx(msg, SHA2::initial_256, 32); case Type::SHA2_384: return SHA2::sha5xx(msg, SHA2::initial_384, 48); case Type::SHA2_512: return SHA2::sha5xx(msg, SHA2::initial_512, 64); case Type::SHA2_512_224: return SHA2::sha5xx(msg, SHA2::initial_512_224, 28); case Type::SHA2_512_256: return SHA2::sha5xx(msg, SHA2::initial_512_256, 32); case Type::BLAKE2s_128: return BLAKE2::blake2s(msg, {}, 16); case Type::BLAKE2s_160: return BLAKE2::blake2s(msg, {}, 20); case Type::BLAKE2s_224: return BLAKE2::blake2s(msg, {}, 28); case Type::BLAKE2s_256: return BLAKE2::blake2s(msg, {}, 32); case Type::BLAKE2b_128: return BLAKE2::blake2b(msg, {}, 16); case Type::BLAKE2b_160: return BLAKE2::blake2b(msg, {}, 20); case Type::BLAKE2b_224: return BLAKE2::blake2b(msg, {}, 28); case Type::BLAKE2b_256: return BLAKE2::blake2b(msg, {}, 32); case Type::BLAKE2b_384: return BLAKE2::blake2b(msg, {}, 48); case Type::BLAKE2b_512: return BLAKE2::blake2b(msg, {}, 64); case Type::SipHash_2_4_64: return SipHash::siphash(msg, {}, 8); case Type::SipHash_2_4_128: return SipHash::siphash(msg, {}, 16); case Type::HalfSipHash_2_4_32: return SipHash::halfsiphash(msg, {}, 4); case Type::HalfSipHash_2_4_64: return SipHash::halfsiphash(msg, {}, 8); default: break; } return {}; } PIByteArray PIDigest::calculateWithKey(const PIByteArray & msg, const PIByteArray & key, Type type) { switch (type) { case Type::BLAKE2s_128: return BLAKE2::blake2s(msg, key, 16); case Type::BLAKE2s_160: return BLAKE2::blake2s(msg, key, 20); case Type::BLAKE2s_224: return BLAKE2::blake2s(msg, key, 28); case Type::BLAKE2s_256: return BLAKE2::blake2s(msg, key, 32); case Type::BLAKE2b_128: return BLAKE2::blake2b(msg, key, 16); case Type::BLAKE2b_160: return BLAKE2::blake2b(msg, key, 20); case Type::BLAKE2b_224: return BLAKE2::blake2b(msg, key, 28); case Type::BLAKE2b_256: return BLAKE2::blake2b(msg, key, 32); case Type::BLAKE2b_384: return BLAKE2::blake2b(msg, key, 48); case Type::BLAKE2b_512: return BLAKE2::blake2b(msg, key, 64); case Type::SipHash_2_4_64: return SipHash::siphash(msg, key, 8); case Type::SipHash_2_4_128: return SipHash::siphash(msg, key, 16); case Type::HalfSipHash_2_4_32: return SipHash::halfsiphash(msg, key, 4); case Type::HalfSipHash_2_4_64: return SipHash::halfsiphash(msg, key, 8); default: break; } return {}; } PIByteArray PIDigest::HMAC(const PIByteArray & msg, const PIByteArray & key, Type type) { int b = PIDigest::blockLength(type); auto ipad = PIByteArray(b, uchar(0x36)); auto opad = PIByteArray(b, uchar(0x5C)); PIByteArray k0; if (key.size_s() > b) k0 = PIDigest::calculate(key, type); else k0 = key; k0.resize(b); return PIDigest::calculate((k0 ^ opad).append(PIDigest::calculate((k0 ^ ipad).append(msg), type)), type); }