Source file vdf_self_contained.ml
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
module Random = Random4
let discriminant_size_bytes = 128
let form_size_bytes = 100
type form = Bytes.t
type discriminant = Bytes.t
type challenge = form
type result = form
type proof = form
type difficulty = int64
let discriminant_to_bytes x = x
let discriminant_of_bytes_opt x =
if Bytes.length x = discriminant_size_bytes then Some x else None
let challenge_to_bytes x = x
let challenge_of_bytes_opt x =
if Bytes.length x = form_size_bytes then Some x else None
let result_to_bytes x = x
let result_of_bytes_opt x =
if Bytes.length x = form_size_bytes then Some x else None
let proof_to_bytes x = x
let proof_of_bytes_opt x =
if Bytes.length x = form_size_bytes then Some x else None
let invalid_discriminant_size =
Invalid_argument
(Printf.sprintf
"Invalid discriminant: discriminant must be %d byte long."
discriminant_size_bytes)
let check_discriminant_size size =
if size != discriminant_size_bytes then raise invalid_discriminant_size
let generate_discriminant ?(seed = Bytes.empty) form_size_bytes =
check_discriminant_size form_size_bytes ;
let result = Bytes.create form_size_bytes in
Utils.Stubs.create_discriminant
seed
(Bytes.length seed)
form_size_bytes
result ;
result
let random discriminant seed =
let () =
let state_seed = Array.(map int_of_char (of_seq (Bytes.to_seq seed))) in
Random.(State.make state_seed |> set_state)
in
let discriminant_size_int = Bytes.length discriminant in
let discriminant_size = discriminant_size_int |> Unsigned.Size_t.of_int in
let mul_bytes form exp_bits exp_len =
let buffer = Bytes.create form_size_bytes in
let status =
Class_group.Stubs.mul
discriminant
discriminant_size
form
exp_bits
exp_len
buffer
in
match status with
| x when x = 0 -> buffer
| x when x = 2 -> raise Utils.invalid_group_element
| _ -> raise Utils.unknown_error
in
let one =
let buffer = Bytes.create form_size_bytes in
Class_group.Stubs.one discriminant discriminant_size buffer ;
buffer
in
let len_exp = discriminant_size_int / 2 in
let random_exp =
Bytes.init len_exp (fun _ -> Random.int 256 |> char_of_int)
in
mul_bytes one random_exp len_exp
let generate_challenge = random
let prove discriminant challenge difficulty =
let discriminant_size_int = Bytes.length discriminant in
check_discriminant_size discriminant_size_int ;
let discriminant_size = discriminant_size_int |> Unsigned.Size_t.of_int in
let difficulty_uint = Unsigned.UInt64.of_int64 difficulty in
let result = Bytes.create form_size_bytes in
let proof = Bytes.create form_size_bytes in
let status =
Vdf.Stubs.prove
discriminant
discriminant_size
challenge
difficulty_uint
result
proof
in
match status with
| x when x = 0 -> (result, proof)
| x when x = 2 -> raise Utils.invalid_group_element
| _ -> raise Utils.unknown_error
let verify discriminant challenge difficulty result proof =
let discriminant_size_int = Bytes.length discriminant in
check_discriminant_size discriminant_size_int ;
let status =
Vdf.Stubs.verify
discriminant
(Unsigned.Size_t.of_int discriminant_size_int)
challenge
result
proof
(Unsigned.UInt64.of_int64 difficulty)
in
match status with
| x when x = 0 -> false
| x when x = 1 -> true
| x when x = 2 -> raise Utils.invalid_group_element
| _ -> raise Utils.unknown_error