Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
random.c
Go to the documentation of this file.
1
#include <assert.h>
2
3
#include "
random.h
"
4
// #include "randombytes.h"
5
#include "../common/rng.h"
6
// #include "crypto_declassify.h"
7
8
#include "
int32_sort.h
"
9
#include "
int32mask.h
"
10
11
#ifdef ENABLE_CT_TESTING
12
#include <valgrind/memcheck.h>
13
#endif
14
15
void
random_wombats
(
uint8_t
*key,
const
long
long
numkeys
,
const
long
long
batch_start
,
const
long
long
batch_stop
,
const
long
long
batch_sumykeys
)
16
{
17
int32_t
batch_len
=
batch_stop
-
batch_start
;
18
int32_t
r
[4 *
batch_len
];
19
uint8_t
ells[
numkeys
];
20
for
(;;)
21
{
/* rejection-sampling loop */
22
randombytes
(
r
, 4 *
batch_len
);
23
for
(
long
long
j
= 0;
j
<
batch_len
; ++
j
)
24
r
[
j
] &= ~1;
25
for
(
long
long
j
= 0;
j
<
numkeys
; ++
j
)
26
r
[
j
] |= 1;
27
int32_sort
(
r
,
batch_len
);
28
29
long
long
collision
= 0;
30
for
(
long
long
j
= 1;
j
<
numkeys
; ++
j
)
31
collision
|= int32mask_zero((
r
[
j
] ^
r
[
j
- 1]) & ~1);
32
33
#ifdef ENABLE_CT_TESTING
34
VALGRIND_MAKE_MEM_DEFINED
(&
collision
,
sizeof
(
collision
));
35
#endif
36
if
(
collision
)
37
continue
;
38
39
for
(
int32_t
j
= 0;
j
<
numkeys
; ++
j
)
40
ells[
j
] = 0;
41
42
for
(
int32_t
j
= 0;
j
<
batch_len
; ++
j
)
43
r
[
j
] &= 1;
44
45
for
(
int32_t
i
= 0;
i
<
numkeys
; ++
i
)
46
{
47
for
(
int32_t
j
=
i
;
j
<
batch_len
; ++
j
)
48
{
49
// r[j] &= 1;
50
int32_t
updatemask
= int32mask_zero(ells[
i
]) & int32mask_nonzero(
r
[
j
]);
51
r
[
j
] ^= (1 &
updatemask
);
52
ells[
i
] |= (
updatemask
& (
j
+ 1));
53
}
54
}
55
56
for
(
int32_t
i
= 0;
i
<
numkeys
; ++
i
)
57
key[
batch_sumykeys
+
i
] =
batch_start
+ ells[
i
] - 1;
58
59
return
;
60
}
61
}
62
63
void
random_boundedl1
(
int8_t
*
e
,
const
long
long
w
,
const
long
long
S
)
64
{
65
// standard correspondences:
66
// e[0],e[1],...,e[w-1] are w nonnegative integers
67
// with sum at most S
68
// <=> 1+e[0],1+e[1],...,1+e[w-1] are w positive integers
69
// with sum at most S+w
70
// <=> 1+e[0],1+e[0]+1+e[1],... are w integers
71
// in strictly increasing order
72
// between 1 and S+w
73
// <=> e[0],1+e[0]+e[1],... are w integers
74
// in strictly increasing order
75
// between 0 and S+w-1
76
77
assert
(
w
>= 0);
78
assert
(
w
< 128);
79
assert
(
S
>= 0);
80
assert
(
S
< 128);
81
if
(!
w
)
82
return
;
83
84
const
long
long
rnum
=
S
+
w
;
85
assert
(
rnum
<= 254);
86
/* XXX: Microsoft compiler doesn't handle int32_t r[S+w] */
87
int32_t
r
[254];
88
89
for
(;;)
90
{
/* rejection-sampling loop */
91
randombytes
(
r
, 4 *
rnum
);
92
for
(
long
long
j
= 0;
j
<
rnum
; ++
j
)
93
r
[
j
] &= ~1;
94
for
(
long
long
j
= 0;
j
<
w
; ++
j
)
95
r
[
j
] |= 1;
96
int32_sort
(
r
,
rnum
);
97
long
long
collision
= 0;
98
for
(
long
long
j
= 1;
j
<
w
; ++
j
)
99
collision
|= int32mask_zero((
r
[
j
] ^
r
[
j
- 1]) & ~1);
100
101
// crypto_declassify(&collision,sizeof collision);
102
if
(
collision
)
103
continue
;
104
105
for
(
long
long
j
= 0;
j
<
rnum
; ++
j
)
106
r
[
j
] &= 1;
107
// now r has Hamming weight w
108
109
for
(
long
long
j
= 1;
j
<
rnum
; ++
j
)
110
r
[
j
] +=
r
[
j
- 1];
111
// now r has >=0 copies of 0,
112
// >=1 copies of 1, >=1 copies of 2, ..., >=1 copies of w
113
114
for
(
long
long
i
= 0;
i
<
w
; ++
i
)
115
{
116
long
long
numi
= 0;
117
for
(
long
long
j
= 0;
j
<
rnum
; ++
j
)
118
numi
-= int32mask_equal(
r
[
j
],
i
);
119
e
[
i
] =
numi
;
120
}
121
// now e[0]>=0, e[1]>=1, e[2]>=1, ..., e[w-1]>=1
122
// and ghost e[w]>=1, not stored
123
// e[0]+e[1]+...+e[w] = rnum
124
// so e[0]+e[1]+...+e[w-1] <= rnum-1
125
126
for
(
long
long
i
= 1;
i
<
w
; ++
i
)
127
--
e
[
i
];
128
// now e[0]>=0, e[1]>=0, e[2]>=0, ..., e[w-1]>=0
129
// sum <= (rnum-1)-(w-1)
130
// i.e. sum <= S
131
132
// not done yet: want to allow negative e
133
134
// but simply negating will give zeros too much weight
135
// for uniformity, keep e with probability 1/2^z
136
// where z is the number of zeros in e
137
138
// speedup: actually keep e with probability 2^zmin/2^z
139
// where zmin is minimum possible value of z
140
141
// strategy: start counter at w-S
142
// and decrease by 1 for each zero bit
143
// and, if negative, flip coin for each zero bit
144
long
long
counter
=
w
-
S
;
145
146
randombytes
(
r
, 4 * ((
w
+ 31) / 32));
147
long
long
reject
= 0;
148
for
(
long
long
i
= 0;
i
<
w
; ++
i
)
149
{
150
int32_t
rbit
= 1 & (
r
[
i
/ 32] >> (
i
& 31));
151
int32_t
eizeromask
= int32mask_zero(
e
[
i
]);
152
counter
+=
eizeromask
;
153
reject
|= int32mask_negative(
counter
) &
eizeromask
&
rbit
;
154
}
155
156
// crypto_declassify(&reject,sizeof reject);
157
if
(
reject
)
158
continue
;
159
160
// ok to reuse randomness in r:
161
// bits used here are for e[i] nonzero,
162
// bits used above are for e[i] zero
163
for
(
long
long
i
= 0;
i
<
w
; ++
i
)
164
{
165
int32_t
rbit
= 1 & (
r
[
i
/ 32] >> (
i
& 31));
166
e
[
i
] ^= -
rbit
;
167
e
[
i
] +=
rbit
;
168
}
169
170
#if defined(RVRSIDH)
171
// RiverSIDH ###########################
172
int
negative
= 0,
positive
= 0;
173
for
(
long
long
i
= 0;
i
<
w
; ++
i
)
174
{
175
negative
+= int32mask_negative(
e
[
i
]) &
e
[
i
];
176
positive
+=
~int32mask_negative
(
e
[
i
]) &
e
[
i
];
177
}
178
179
if
((
negative
< -(
S
>> 1)) || (
positive
> (
S
>> 1)))
180
continue
;
181
// #####################################
182
#endif
183
184
return
;
185
}
186
}
187
188
// -1 if x < y, else 0
189
static
int64_t
uint64mask_lessthan(
uint64_t
x,
uint64_t
y)
190
{
191
int64_t
xy
=
x
^ y;
192
int64_t
c
=
x
- y;
193
const
int64_t
flip
= ((
uint64_t
)1) << 63;
194
c
^=
xy
& (
c
^
x
^
flip
);
195
return
c
>> 63;
196
}
197
198
int64_t
random_coin
(
uint64_t
num
,
uint64_t
den
)
199
{
200
uint8_t
buf
[32];
201
uint64_t
r
= 0;
202
203
randombytes
(
buf
,
sizeof
buf
);
204
205
for
(
long
long
i
= 0;
i
< 256; ++
i
)
206
{
207
uint64_t
bit = 1 & (
buf
[
i
/ 8] >> (
i
& 7));
208
r
<<= 1;
209
r
+= bit;
210
r
^= (
~uint64mask_lessthan
(
r
,
den
)) & (
r
^ (
r
-
den
));
211
}
212
// XXX: speed this up
213
214
return
uint64mask_lessthan(
r
,
num
);
215
}
randombytes
void randombytes(void *x, size_t l)
Definition
rng.c:8
int32_sort.h
int32_sort
#define int32_sort
Definition
int32_sort.h:6
int32mask.h
assert
assert(var1 eq var2)
num
num
Definition
j-invariants.m:29
analyze_bench.x
dict x
Definition
analyze_bench.py:83
pip._vendor.pygments.unistring.c
c
Definition
unistring.py:122
i
for i
Definition
prime_search.m:10
j
for j
Definition
prime_search.m:12
batch_start
#define batch_start
Definition
primes.h:55
batch_stop
#define batch_stop
Definition
primes.h:56
random_wombats
void random_wombats(uint8_t *key, const long long numkeys, const long long batch_start, const long long batch_stop, const long long batch_sumykeys)
Definition
random.c:15
random.h
random_boundedl1
#define random_boundedl1
Definition
random.h:7
random_coin
#define random_coin
Definition
random.h:8
dCTIDH
src
common
random.c
Generated by
1.9.8