aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorLauri Kasanen <curaga@operamail.com>2013-01-14 05:20:50 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2013-01-14 05:20:50 +0100
commitb8173b603f57dcf918a67f1ec00763ab5f4e1cf8 (patch)
tree726549290ba408cf68561c4c1c2d591a80ded319 /libbb
parentb7841cf7b919b16d1bd4619154bf7cb4c22b4ccd (diff)
downloadbusybox-w32-b8173b603f57dcf918a67f1ec00763ab5f4e1cf8.tar.gz
busybox-w32-b8173b603f57dcf918a67f1ec00763ab5f4e1cf8.tar.bz2
busybox-w32-b8173b603f57dcf918a67f1ec00763ab5f4e1cf8.zip
sha3sum: new applet
function old new delta KeccakF - 496 +496 KeccakF_RoundConstants - 192 +192 sha3_hash - 171 +171 sha3_end - 40 +40 hash_file 274 299 +25 KeccakF_RotationConstants - 25 +25 KeccakF_PiLane - 25 +25 packed_usage 29213 29232 +19 sha3_begin - 18 +18 KeccakF_Mod5 - 10 +10 applet_names 2445 2453 +8 applet_main 1420 1424 +4 applet_nameofs 710 712 +2 ------------------------------------------------------------------------------ (add/remove: 8/0 grow/shrink: 9/7 up/down: 1049/-54) Total: ~995 bytes Signed-off-by: Lauri Kasanen <curaga@operamail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/hash_md5_sha.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c
index a313c2a65..06a2400b5 100644
--- a/libbb/hash_md5_sha.c
+++ b/libbb/hash_md5_sha.c
@@ -31,6 +31,11 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n)
31 return (x >> n) | (x << (64 - n)); 31 return (x >> n) | (x << (64 - n));
32} 32}
33 33
34/* rotl64 only used for sha3 currently */
35static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n)
36{
37 return (x << n) | (x >> (64 - n));
38}
34 39
35/* Feed data through a temporary buffer. 40/* Feed data through a temporary buffer.
36 * The internal buffer remembers previous data until it has 64 41 * The internal buffer remembers previous data until it has 64
@@ -896,3 +901,192 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
896 } 901 }
897 memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); 902 memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
898} 903}
904
905
906/*
907 * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
908 * Michael Peeters and Gilles Van Assche. For more information, feedback or
909 * questions, please refer to our website: http://keccak.noekeon.org/
910 *
911 * Implementation by Ronny Van Keer,
912 * hereby denoted as "the implementer".
913 *
914 * To the extent possible under law, the implementer has waived all copyright
915 * and related or neighboring rights to the source code in this file.
916 * http://creativecommons.org/publicdomain/zero/1.0/
917 *
918 * Busybox modifications (C) Lauri Kasanen, under the GPLv2.
919 */
920
921enum {
922 cKeccakR_SizeInBytes = 576 / 8,
923 cKeccakNumberOfRounds = 24,
924};
925
926static const uint64_t KeccakF_RoundConstants[cKeccakNumberOfRounds] = {
927 0x0000000000000001ULL,
928 0x0000000000008082ULL,
929 0x800000000000808aULL,
930 0x8000000080008000ULL,
931 0x000000000000808bULL,
932 0x0000000080000001ULL,
933 0x8000000080008081ULL,
934 0x8000000000008009ULL,
935 0x000000000000008aULL,
936 0x0000000000000088ULL,
937 0x0000000080008009ULL,
938 0x000000008000000aULL,
939 0x000000008000808bULL,
940 0x800000000000008bULL,
941 0x8000000000008089ULL,
942 0x8000000000008003ULL,
943 0x8000000000008002ULL,
944 0x8000000000000080ULL,
945 0x000000000000800aULL,
946 0x800000008000000aULL,
947 0x8000000080008081ULL,
948 0x8000000000008080ULL,
949 0x0000000080000001ULL,
950 0x8000000080008008ULL
951};
952
953static const uint8_t KeccakF_RotationConstants[25] = {
954 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62,
955 18, 39, 61, 20, 44
956};
957
958static const uint8_t KeccakF_PiLane[25] = {
959 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20,
960 14, 22, 9, 6, 1
961};
962
963static const uint8_t KeccakF_Mod5[10] = {
964 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
965};
966
967static void KeccakF(uint64_t *state)
968{
969 uint8_t x, y;
970 uint64_t temp;
971 uint64_t BC[5];
972 int round;
973
974 if (BB_BIG_ENDIAN) {
975 for (x = 0; x < 25; x++) {
976 state[x] = SWAP_LE64(state[x]);
977 }
978 }
979
980 for (round = 0; round < cKeccakNumberOfRounds; ++round) {
981 /* Theta */
982 for (x = 0; x < 5; ++x) {
983 BC[x] = state[x] ^ state[5 + x] ^ state[10 + x] ^
984 state[15 + x] ^ state[20 + x];
985 }
986 for (x = 0; x < 5; ++x) {
987 temp = BC[KeccakF_Mod5[x + 4]] ^
988 rotl64(BC[KeccakF_Mod5[x + 1]], 1);
989
990 for (y = 0; y <= 20; y += 5) {
991 state[y + x] ^= temp;
992 }
993 }
994
995 /* Rho Pi */
996 temp = state[1];
997 for (x = 0; x < 24; ++x) {
998 BC[0] = state[KeccakF_PiLane[x]];
999 state[KeccakF_PiLane[x]] =
1000 rotl64(temp, KeccakF_RotationConstants[x]);
1001 temp = BC[0];
1002 }
1003
1004 /* Chi */
1005 for (y = 0; y < 25; y += 5) {
1006 BC[0] = state[y + 0];
1007 BC[1] = state[y + 1];
1008 BC[2] = state[y + 2];
1009 BC[3] = state[y + 3];
1010 BC[4] = state[y + 4];
1011 for (x = 0; x < 5; ++x) {
1012 state[y + x] =
1013 BC[x] ^ ((~BC[KeccakF_Mod5[x + 1]]) &
1014 BC[KeccakF_Mod5[x + 2]]);
1015 }
1016 }
1017
1018 /* Iota */
1019 state[0] ^= KeccakF_RoundConstants[round];
1020 }
1021
1022 if (BB_BIG_ENDIAN) {
1023 for (x = 0; x < 25; x++) {
1024 state[x] = SWAP_LE64(state[x]);
1025 }
1026 }
1027}
1028
1029void FAST_FUNC sha3_begin(sha3_ctx_t *ctx)
1030{
1031 memset(ctx, 0, sizeof(*ctx));
1032}
1033
1034void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buf, size_t bytes)
1035{
1036 const uint8_t *data = buf;
1037
1038 /* If already data in queue, continue queuing first */
1039 while (bytes != 0 && ctx->bytes_queued != 0) {
1040 uint8_t *buffer = (uint8_t*)ctx->state;
1041 buffer[ctx->bytes_queued] ^= *data++;
1042 bytes--;
1043 ctx->bytes_queued++;
1044 if (ctx->bytes_queued == cKeccakR_SizeInBytes) {
1045 KeccakF(ctx->state);
1046 ctx->bytes_queued = 0;
1047 }
1048 }
1049
1050 /* Absorb complete blocks */
1051 while (bytes >= cKeccakR_SizeInBytes) {
1052 /* XOR data onto beginning of state[].
1053 * We try to be efficient - operate on word at a time, not byte.
1054 * Yet safe wrt unaligned access: can't just use "*(long*)data"...
1055 */
1056 unsigned count = cKeccakR_SizeInBytes / sizeof(long);
1057 long *buffer = (long*)ctx->state;
1058 do {
1059 long v;
1060 move_from_unaligned_long(v, (long*)data);
1061 *buffer++ ^= v;
1062 data += sizeof(long);
1063 } while (--count);
1064
1065 KeccakF(ctx->state);
1066 bytes -= cKeccakR_SizeInBytes;
1067 }
1068
1069 /* Queue remaining data bytes */
1070 while (bytes != 0) {
1071 uint8_t *buffer = (uint8_t*)ctx->state;
1072 buffer[ctx->bytes_queued] ^= *data++;
1073 ctx->bytes_queued++;
1074 bytes--;
1075 }
1076}
1077
1078void FAST_FUNC sha3_end(sha3_ctx_t *ctx, uint8_t *hashval)
1079{
1080 /* Padding */
1081 uint8_t *buffer = (uint8_t*)ctx->state;
1082 /* 0 is the number of bits in last, incomplete byte
1083 * (that is, zero: we never have incomplete bytes):
1084 */
1085 buffer[ctx->bytes_queued] ^= 1 << 0;
1086 buffer[cKeccakR_SizeInBytes - 1] ^= 0x80;
1087
1088 KeccakF(ctx->state);
1089
1090 /* Output */
1091 memcpy(hashval, ctx->state, 64);
1092}