Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
ram_examples.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for a RAM example, as well as functions to sample
5  RAM examples with prescribed parameters (according to some distribution).
6 
7  See ram_examples.hpp .
8 
9  *****************************************************************************
10  * @author This file is part of libsnark, developed by SCIPR Lab
11  * and contributors (see AUTHORS).
12  * @copyright MIT license (see LICENSE file)
13  *****************************************************************************/
14 
15 #ifndef RAM_EXAMPLES_TCC_
16 #define RAM_EXAMPLES_TCC_
17 
18 #include <libsnark/relations/ram_computations/rams/tinyram/tinyram_aux.hpp>
19 
20 namespace libsnark
21 {
22 
23 template<typename ramT>
24 ram_example<ramT> gen_ram_example_simple(
25  const ram_architecture_params<ramT> &ap,
26  const size_t boot_trace_size_bound,
27  const size_t time_bound,
28  const bool satisfiable)
29 {
30  libff::enter_block("Call to gen_ram_example_simple");
31 
32  const size_t program_size = boot_trace_size_bound / 2;
33  const size_t input_size = boot_trace_size_bound - program_size;
34 
35  ram_example<ramT> result;
36 
37  result.ap = ap;
38  result.boot_trace_size_bound = boot_trace_size_bound;
39  result.time_bound = time_bound;
40 
41  tinyram_program prelude;
42  prelude.instructions = generate_tinyram_prelude(ap);
43 
44  size_t boot_pos = 0;
45  for (size_t i = 0; i < prelude.instructions.size(); ++i) {
46  result.boot_trace.set_trace_entry(
47  boot_pos++,
48  std::make_pair(i, prelude.instructions[i].as_dword(ap)));
49  }
50 
51  result.boot_trace[boot_pos] = std::make_pair(
52  boot_pos++,
53  tinyram_instruction(
54  tinyram_opcode_ANSWER, true, 0, 0, satisfiable ? 0 : 1)
55  .as_dword(ap)); /* answer 0/1 depending on satisfiability */
56 
57  while (boot_pos < program_size) {
58  result.boot_trace.set_trace_entry(
59  boot_pos++, random_tinyram_instruction(ap).as_dword(ap));
60  }
61 
62  for (size_t i = 0; i < input_size; ++i) {
63  result.boot_trace.set_trace_entry(
64  boot_pos++,
65  std::make_pair(
66  (1ul << (ap.dwaddr_len() - 1)) + i,
67  std::rand() % (1ul << (2 * ap.w))));
68  }
69 
70  assert(boot_pos == boot_trace_size_bound);
71 
72  libff::leave_block("Call to gen_ram_example_simple");
73  return result;
74 }
75 
76 template<typename ramT>
77 ram_example<ramT> gen_ram_example_complex(
78  const ram_architecture_params<ramT> &ap,
79  const size_t boot_trace_size_bound,
80  const size_t time_bound,
81  const bool satisfiable)
82 {
83  libff::enter_block("Call to gen_ram_example_complex");
84 
85  const size_t program_size = boot_trace_size_bound / 2;
86  const size_t input_size = boot_trace_size_bound - program_size;
87 
88  assert(2 * ap.w / 8 * program_size < 1ul << (ap.w - 1));
89  assert(ap.w / 8 * input_size < 1ul << (ap.w - 1));
90 
91  ram_example<ramT> result;
92 
93  result.ap = ap;
94  result.boot_trace_size_bound = boot_trace_size_bound;
95  result.time_bound = time_bound;
96 
97  tinyram_program prelude;
98  prelude.instructions = generate_tinyram_prelude(ap);
99 
100  size_t boot_pos = 0;
101  for (size_t i = 0; i < prelude.instructions.size(); ++i) {
102  result.boot_trace.set_trace_entry(
103  boot_pos++,
104  std::make_pair(i, prelude.instructions[i].as_dword(ap)));
105  }
106 
107  const size_t prelude_len = prelude.instructions.size();
108  const size_t instr_addr = (prelude_len + 4) * (2 * ap.w / 8);
109  const size_t input_addr =
110  (1ul << (ap.w - 1)) +
111  (ap.w / 8); // byte address of the first input word
112 
113  result.boot_trace.set_trace_entry(
114  boot_pos,
115  std::make_pair(
116  boot_pos,
117  tinyram_instruction(tinyram_opcode_LOADB, true, 1, 0, instr_addr)
118  .as_dword(ap)));
119  ++boot_pos;
120  result.boot_trace.set_trace_entry(
121  boot_pos,
122  std::make_pair(
123  boot_pos,
124  tinyram_instruction(tinyram_opcode_LOADW, true, 2, 0, input_addr)
125  .as_dword(ap)));
126  ++boot_pos;
127  result.boot_trace.set_trace_entry(
128  boot_pos,
129  std::make_pair(
130  boot_pos,
131  tinyram_instruction(tinyram_opcode_SUB, false, 1, 1, 2)
132  .as_dword(ap)));
133  ++boot_pos;
134  result.boot_trace.set_trace_entry(
135  boot_pos,
136  std::make_pair(
137  boot_pos,
138  tinyram_instruction(tinyram_opcode_STOREB, true, 1, 0, instr_addr)
139  .as_dword(ap)));
140  ++boot_pos;
141  result.boot_trace.set_trace_entry(
142  boot_pos,
143  std::make_pair(
144  boot_pos,
145  tinyram_instruction(tinyram_opcode_ANSWER, true, 0, 0, 1)
146  .as_dword(ap)));
147  ++boot_pos;
148 
149  while (boot_pos < program_size) {
150  result.boot_trace.set_trace_entry(
151  boot_pos,
152  std::make_pair(
153  boot_pos, random_tinyram_instruction(ap).as_dword(ap)));
154  ++boot_pos;
155  }
156 
157  result.boot_trace.set_trace_entry(
158  boot_pos++,
159  std::make_pair(
160  1ul << (ap.dwaddr_len() - 1), satisfiable ? 1ul << ap.w : 0));
161 
162  for (size_t i = 1; i < input_size; ++i) {
163  result.boot_trace.set_trace_entry(
164  boot_pos++,
165  std::make_pair(
166  (1ul << (ap.dwaddr_len() - 1)) + i + 1,
167  std::rand() % (1ul << (2 * ap.w))));
168  }
169 
170  libff::leave_block("Call to gen_ram_example_complex");
171  return result;
172 }
173 
174 } // namespace libsnark
175 
176 #endif // RAM_EXAMPLES_TCC_