-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathperm.c
92 lines (74 loc) · 1.74 KB
/
perm.c
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "perm.h"
#include "tables.h"
#include "rand.h"
uint32_t keytoperm(uint64_t key) {
uint32_t level1 = key ^ (key >> 32);
key &= 0x8040201008040201UL;
uint32_t level2 = key | (key>>32);
level2 |= level2>>16;
level2 |= level2>>8;
uint32_t t = tables->mod6[level1>>16];
return (t<<13) + (t<<10) + (tables->mod6[level1 & 0xffff]<<8) + (level2& 0xff);
}
uint64_t permtokey(uint32_t permid) {
uint64_t key = 0;
uint32_t level1 = permid>>8;
key += level1 % 6;
key += ((level1/6)%6) << 8;
key += ((level1/36)%6) << 16;
key += ((level1/216)%6) << 24;
for (int i = 0; i < 8; i++)
key ^= (0x100000001UL * ((permid^(key>>8*i))&(1<<i))) << (8*(i&3));
return key;
}
/*
static inline uint32_t rdrand32(void) {
uint32_t r;
asm __volatile__ ("rdrand %0":"=r" (r));
return r;
}
static inline uint64_t rdrand64(void) {
uint64_t r;
asm __volatile__ ("rdrand %0":"=r" (r));
return r;
}
*/
static struct randstate rs;
uint8_t randkey(uint64_t key[2]) {
uint64_t keyl, keyh;
uint8_t map, column;
uint32_t perml, permh;
uint8_t lpreserves,nextpreserves;
uint8_t valid;
do {
valid = 0;
keyl = prand(&rs);
perml = keytoperm(keyl);
for (int i = 0; i < 4; i++)
if (PRESERVES(perml, i))
valid |= 1<<i;
if (valid == 0)
continue;
} while (!valid);
do {
valid = 0;
keyh = prand(&rs);
permh = keytoperm(keyh);
if (!VALID34(permh))
continue;
for (int i = 0; i < 4; i++) {
if (PRESERVES(perml, i)) {
for (int j = 0; j < 4; j++)
if (MAP12(perml, i) == MAP34(permh, j))
valid |= 1 << j;
}
}
} while (!valid);
key[0] = keyl;
key[1] = keyh;
return valid;
}