File: siphash.c

package info (click to toggle)
dq 20230101-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,020 kB
  • sloc: ansic: 8,269; makefile: 363; sh: 176; python: 82
file content (60 lines) | stat: -rw-r--r-- 1,442 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
- based on crypto_auth/siphash24/little2 from supercop-20140622
*/

#include "uint64_pack.h"
#include "uint64_unpack.h"
#include "siphash.h"

#define ROTATE(x,b) x = (x << b) | (x >> (64 - b))

#define ROUND \
  do { \
  v0 += v1; v2 += v3; \
  ROTATE(v1,13); ROTATE(v3,16); \
  v1 ^= v0; v3 ^= v2; \
  ROTATE(v0,32); \
  v2 += v1; v0 += v3; \
  ROTATE(v1,17); ROTATE(v3,21); \
  v1 ^= v2; v3 ^= v0; \
  ROTATE(v2,32); \
  } while(0);

int siphash(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k, long long rounds, long long finalrounds) {

    crypto_uint64 v0, v1, v2, v3, lastblock = inlen;
    unsigned char block[8];
    long long i;

    v0 = v2 = uint64_unpack(k + 0);
    v1 = v3 = uint64_unpack(k + 8);

    v0 ^= 0x736f6d6570736575;
    v1 ^= 0x646f72616e646f6d;
    v2 ^= 0x6c7967656e657261;
    v3 ^= 0x7465646279746573;

    while (inlen >= 8) {
        crypto_uint64 mi = uint64_unpack(in);
        in += 8;
        v3 ^= mi;
        for (i = 0; i < rounds; ++i) ROUND
        v0 ^= mi;
        inlen -= 8;
    }

    for (i = 0; i < 7;     ++i) block[i] = 0;
    for (i = 0; i < inlen; ++i) block[i] = in[i];
    block[7] = lastblock;
    lastblock = uint64_unpack(block);

    v3 ^= lastblock;
    for (i = 0; i < rounds; ++i) ROUND
    v0 ^= lastblock;

    v2 ^= 0xff;
    for (i = 0; i < finalrounds; ++i) ROUND

    uint64_pack(out, (v0 ^ v1) ^ (v2 ^ v3));
    return 0;
}