mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-11 06:27:56 -05:00
170 lines
4.8 KiB
Plaintext
170 lines
4.8 KiB
Plaintext
from Compiler import library as lib, path_oblivious_heap as poh, util
|
|
from Compiler.path_oram import OptimalORAM, RecursivePathORAM
|
|
from Compiler import dijkstra
|
|
from Compiler.types import sint
|
|
|
|
### SETUP ###
|
|
|
|
# Which tests are we running?
|
|
SCRATCHPAD = False
|
|
UNIT = True
|
|
DIJKSTRA = True
|
|
|
|
# Module settings
|
|
from Compiler import oram, path_oblivious_heap
|
|
|
|
oram.crash_on_overflow = False
|
|
poh.CRASH_ON_EMPTY = True
|
|
poh.TRACE = False
|
|
poh.DEBUG = True
|
|
|
|
### UTILITY ###
|
|
|
|
# Timing with consecutive ids
|
|
|
|
timer_offset = 1000 # Hopefully run timers in an unused range
|
|
|
|
|
|
def start_fancy_timer(id: int | None = None) -> int:
|
|
global timer_offset
|
|
_id = id if id is not None else timer_offset
|
|
lib.start_timer(_id)
|
|
if id is None:
|
|
timer_offset += 1
|
|
return _id
|
|
|
|
|
|
def stop_fancy_timer(id):
|
|
lib.stop_timer(id)
|
|
|
|
|
|
if SCRATCHPAD:
|
|
q = poh.UniquePOHToHeapQAdapter(3)
|
|
q.insert(0, 10)
|
|
q.insert(1, 1)
|
|
q.insert(2, 1)
|
|
|
|
lib.print_ln("%s", q.extract_min().reveal())
|
|
lib.print_ln("%s", q.extract_min().reveal())
|
|
lib.print_ln("%s", q.extract_min().reveal())
|
|
|
|
if UNIT:
|
|
# POH
|
|
lib.print_ln("Testing PathObliviousHeap.__init__...")
|
|
q = poh.PathObliviousHeap(10)
|
|
lib.print_ln("Initialization was successful!")
|
|
|
|
lib.print_ln("Testing PathObliviousHeap.insert of two identical entries...")
|
|
lib.print_ln("Inserting {value: 5, priority: 10}...")
|
|
q.insert(5, 10)
|
|
lib.print_ln("Inserting {value: 5, priority: 10}...")
|
|
q.insert(5, 10)
|
|
lib.print_ln("Inserts were successful!")
|
|
|
|
lib.print_ln("Testing PathObliviousHeap.extract_min of two identical entries...")
|
|
lib.print_ln("Extracted values should be 5, 5.")
|
|
v = q.extract_min()
|
|
lib.print_ln("Extracted value %s", v.reveal())
|
|
v = q.extract_min()
|
|
lib.print_ln("Extracted value %s", v.reveal())
|
|
|
|
# UniquePOH
|
|
lib.print_ln("Testing UniquePathObliviousHeap.__init__...")
|
|
q = poh.UniquePathObliviousHeap(4)
|
|
lib.print_ln("Initialization was successful!")
|
|
lib.print_ln("Testing UniquePathObliviousHeap.insert...")
|
|
lib.print_ln("Inserting {value: 5, priority: 10}...")
|
|
q.insert(5, 10)
|
|
lib.print_ln("Inserting {value: 5, priority: 10}...")
|
|
q.insert(5, 10)
|
|
lib.print_ln("Inserting {value: 6, priority: 11}...")
|
|
q.insert(6, 11)
|
|
lib.print_ln("Inserts were successful!")
|
|
|
|
lib.print_ln("Testing UniquePathObliviousHeap.extract_min twice...")
|
|
lib.print_ln("Extracted values should be 5, 6.")
|
|
v = q.extract_min()
|
|
lib.print_ln("Extracted value %s", v.reveal())
|
|
v = q.extract_min()
|
|
lib.print_ln("Extracted value %s", v.reveal())
|
|
|
|
lib.print_ln("Testing UniquePathObliviousHeap.insert and update...")
|
|
lib.print_ln("Inserting {value: 7, priority: 14}...")
|
|
q.insert(7, 14)
|
|
lib.print_ln("Updating {value: 7, priority: 1}...")
|
|
q.update(7, 1)
|
|
lib.print_ln("Inserting {value: 2, priority: 10}...")
|
|
q.update(7, 1)
|
|
lib.print_ln("Inserts and updates were successful!")
|
|
|
|
lib.print_ln("Testing UniquePathObliviousHeap.find_min...")
|
|
v = q.find_min()
|
|
lib.print_ln("Found value should be 7.")
|
|
lib.print_ln("Found value %s", v.reveal())
|
|
|
|
# SubtreeMinEntry
|
|
lib.print_ln("Testing SubtreeMinEntry comparisons...")
|
|
id = start_fancy_timer()
|
|
poh.test_SubtreeMinEntry_cmp()
|
|
stop_fancy_timer(id)
|
|
|
|
if DIJKSTRA:
|
|
dijkstra.HeapQ = poh.POHToHeapQAdapter
|
|
|
|
# example code for graph with vertices 0,1,2 and with following weights
|
|
# 0 -> 1: 5
|
|
# 0 -> 2: 20
|
|
# 1 -> 2: 10
|
|
|
|
lib.print_ln("Testing dijkstra on Path Oblivious Heap...")
|
|
lib.print_ln("Output should be the following:")
|
|
lib.print_ln("from 0 to 0 at cost 0 via vertex 0")
|
|
lib.print_ln("from 0 to 1 at cost 5 via vertex 0")
|
|
lib.print_ln("from 0 to 2 at cost 15 via vertex 1")
|
|
|
|
# structure for edges
|
|
# contains tuples of form (neighbor, cost, last neighbor bit)
|
|
edges = OptimalORAM(
|
|
4, # number of edges
|
|
entry_size=(
|
|
2, # enough bits for vertices
|
|
5, # enough bits for costs
|
|
1,
|
|
), # always one
|
|
)
|
|
|
|
# first edge from vertex 0
|
|
edges[0] = (1, 5, 0)
|
|
# second and last edge from vertex 0
|
|
edges[1] = (2, 20, 1)
|
|
# edge from vertex 1
|
|
edges[2] = (2, 10, 1)
|
|
# dummy edge from vertex 2 to itself
|
|
edges[3] = (2, 0, 1)
|
|
|
|
# structure assigning edge list indices to vertices
|
|
e_index = OptimalORAM(
|
|
3, entry_size=2 # number vertices
|
|
) # enough bits for edge indices
|
|
|
|
# edges from 0 start at 0
|
|
e_index[0] = 0
|
|
# edges from 1 start at 2
|
|
e_index[1] = 2
|
|
# edges from 2 start at 3
|
|
e_index[2] = 3
|
|
|
|
source = sint(0)
|
|
|
|
res = dijkstra.dijkstra(source, edges, e_index, OptimalORAM)
|
|
|
|
@lib.for_range(res.size)
|
|
def _(i):
|
|
lib.print_ln(
|
|
"from %s to %s at cost %s via vertex %s",
|
|
source.reveal(),
|
|
i,
|
|
res[i][0].reveal(),
|
|
res[i][1].reveal(),
|
|
)
|