diff options
author | Lauri Kasanen <curaga@operamail.com> | 2013-01-14 05:20:50 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-01-14 05:20:50 +0100 |
commit | b8173b603f57dcf918a67f1ec00763ab5f4e1cf8 (patch) | |
tree | 726549290ba408cf68561c4c1c2d591a80ded319 /libbb | |
parent | b7841cf7b919b16d1bd4619154bf7cb4c22b4ccd (diff) | |
download | busybox-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.c | 194 |
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 */ | ||
35 | static 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 | |||
921 | enum { | ||
922 | cKeccakR_SizeInBytes = 576 / 8, | ||
923 | cKeccakNumberOfRounds = 24, | ||
924 | }; | ||
925 | |||
926 | static 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 | |||
953 | static 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 | |||
958 | static 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 | |||
963 | static const uint8_t KeccakF_Mod5[10] = { | ||
964 | 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 | ||
965 | }; | ||
966 | |||
967 | static 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 | |||
1029 | void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) | ||
1030 | { | ||
1031 | memset(ctx, 0, sizeof(*ctx)); | ||
1032 | } | ||
1033 | |||
1034 | void 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 | |||
1078 | void 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 | } | ||