package class_group_vdf

  1. Overview
  2. Docs

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
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