def traverse(self, s): """Returns the auth nodes for leaf s + 1.""" for h in range(H): if not ((s >> h) & 1): tau = h break if tau > 0: tempkeep = self.keep[(tau - 1) >> 1] # prevent overwriting if not ((s >> (tau+1)) & 1) and tau < H - 1: self.keep[tau >> 1] = self.auth[tau] if tau == 0: self.auth[0] = Node(h=0, v=leafcalc(s)) else: self.auth[tau] = Node(h=0, v=g(self.auth[tau - 1].v + tempkeep.v)) for h in range(tau): if h < H - K: self.auth[h] = self.treehash[h].node else: offset = (1 << (H - 1 - h)) + h - H rowidx = ((s >> h) - 1) >> 1 self.auth[h] = self.retain[offset + rowidx] for h in range(tau if (tau < H - K) else H - K): startidx = s + 1 + 3 * (1 << h) if startidx < 1 << H: self.treehash[h].restart(startidx) return self.auth
def traverse(self, s): """Returns the auth nodes for leaf s + 1.""" for h in range(H): if not ((s >> h) & 1): tau = h break if tau > 0: tempkeep = self.keep[(tau - 1) >> 1] # prevent overwriting if not ((s >> (tau + 1)) & 1) and tau < H - 1: self.keep[tau >> 1] = self.auth[tau] if tau == 0: self.auth[0] = Node(h=0, v=leafcalc(s)) else: self.auth[tau] = Node(h=0, v=g(self.auth[tau - 1].v + tempkeep.v)) for h in range(tau): if h < H - K: self.auth[h] = self.treehash[h].node else: offset = (1 << (H - 1 - h)) + h - H rowidx = ((s >> h) - 1) >> 1 self.auth[h] = self.retain[offset + rowidx] for h in range(tau if (tau < H - K) else H - K): startidx = s + 1 + 3 * (1 << h) if startidx < 1 << H: self.treehash[h].restart(startidx) return self.auth
def update(self): """Performs one unit of computation on the stack. This can imply either the introduction a new leaf node or the computation of a parent node""" if self.completed: return if len(self.stack) >= 2 and self.stack[-1].h == self.stack[-2].h: node_r = self.stack.pop() node_l = self.stack.pop() self.stack.append(Node(h=node_l.h + 1, v=g(node_l.v + node_r.v))) else: self.stack.append(Node(h=0, v=leafcalc(self.next_idx))) self.next_idx += 1 if self.stack[-1].h == self.h: self.completed = True return
def update(self): """Performs one iteration of Treehash, i.e. adds one leaf node. Note that this is different from Treehash.update() in the classic traversal algorithm, where only one computational unit is performed.""" node1 = Node(h=0, v=leafcalc(self.next_idx)) while self.stackusage > 0 and STACK[-1].h == node1.h: node2 = STACK.pop() self.stackusage -= 1 node1 = Node(h=node1.h + 1, v=g(node2.v + node1.v)) STACK.append(node1) self.stackusage += 1 self.next_idx += 1 if self.stackusage == 1 and STACK[-1].h == self.h: self.completed = True self.node = STACK.pop() self.stackusage -= 1
def update(self): """Performs one iteration of Treehash, i.e. adds one leaf node. Note that this is different from Treehash.update() in the classic traversal algorithm, where only one computational unit is performed.""" node1 = Node(h=0, v=leafcalc(self.next_idx)) while self.stackusage > 0 and self.stack[-1].h == node1.h: node2 = self.stack.pop() self.stackusage -= 1 node1 = Node(h=node1.h + 1, v=g(node2.v + node1.v)) self.stack.append(node1) self.stackusage += 1 self.next_idx += 1 if self.stackusage == 1 and self.stack[-1].h == self.h: self.completed = True self.node = self.stack.pop() self.stackusage -= 1
def traverse(s): """Returns the auth nodes for leaf s + 1.""" for h in range(H): if not ((s >> h) & 1): tau = h break if tau > 0: tempKEEP = KEEP[(tau - 1) >> 1] # prevent overwriting too soon if not ((s >> (tau + 1)) & 1) and tau < H - 1: KEEP[tau >> 1] = AUTH[tau] if tau == 0: AUTH[0] = Node(h=0, v=leafcalc(s)) else: AUTH[tau] = Node(h=0, v=g(AUTH[tau - 1].v + tempKEEP.v)) for h in range(tau): if h < H - K: AUTH[h] = TREEHASH[h].node else: offset = (1 << (H - 1 - h)) + h - H rowidx = ((s >> h) - 1) >> 1 AUTH[h] = RETAIN[offset + rowidx] for h in range(tau if (tau < H - K) else H - K): startidx = s + 1 + 3 * (1 << h) if startidx < 1 << H: TREEHASH[h].__init__(h, startidx) for _ in range((H - K) >> 1): l_min = H h = H - K for j in range(H - K): if TREEHASH[j].completed: low = H elif TREEHASH[j].stackusage == 0: low = j else: low = TREEHASH[j].height() if low < l_min: h = j l_min = low if h != H - K: TREEHASH[h].update() return AUTH
def stack_update(self, idx): node1 = Node(h=0, v=leafcalc(idx)) if node1.h < H - K and idx == 3: self.treehash[0].node = node1 while self.stack and self.stack[-1].h == node1.h: if idx >> node1.h == 1: self.auth[node1.h] = node1 else: # node1 is a right-node with row-index 2idx + 3 if node1.h < H - K and idx >> node1.h == 3: self.treehash[node1.h].node = node1 elif node1.h >= H - K: offset = (1 << (H - 1 - node1.h)) + node1.h - H rowidx = ((idx >> node1.h) - 3) >> 1 self.retain[offset + rowidx] = node1 node2 = self.stack.pop() node1 = Node(h=node1.h + 1, v=g(node2.v + node1.v)) self.stack.append(node1)
def keygen_and_setup(): """Sets up TREEHASH and AUTH for the start of classic Merkle traversal.""" for h in range(H): TREEHASH[h] = Treehash(h, completed=True) stack = [] for j in range(2 ** H): node1 = Node(h=0, v=leafcalc(j)) if j == 0: TREEHASH[0].stack = [node1] while stack and stack[-1].h == node1.h: if not AUTH[node1.h]: AUTH[node1.h] = node1 node2 = stack.pop() node1 = Node(h=node1.h+1, v=g(node2.v + node1.v)) if node1.h < H and not TREEHASH[node1.h].stack: TREEHASH[node1.h].stack.append(node1) stack.append(node1) return stack.pop()
def keygen_and_setup(): """Sets up TREEHASH and AUTH for the start of classic Merkle traversal.""" for h in range(H): TREEHASH[h] = Treehash(h, completed=True) stack = [] for j in range(2**H): node1 = Node(h=0, v=leafcalc(j)) if j == 0: TREEHASH[0].stack = [node1] while stack and stack[-1].h == node1.h: if not AUTH[node1.h]: AUTH[node1.h] = node1 node2 = stack.pop() node1 = Node(h=node1.h + 1, v=g(node2.v + node1.v)) if node1.h < H and not TREEHASH[node1.h].stack: TREEHASH[node1.h].stack.append(node1) stack.append(node1) return stack.pop()
def traverse(s): """Returns the auth nodes for leaf s + 1.""" tau = next(h for h in range(H) if not (s >> h) & 1) if not (s >> (tau + 1)) & 1 and tau < H - 1: KEEP[tau] = AUTH[tau] if tau == 0: AUTH[0] = Node(h=0, v=leafcalc(s)) else: AUTH[tau] = Node(h=tau, v=g(AUTH[tau - 1].v + KEEP[tau - 1].v)) KEEP[tau - 1] = None for h in range(tau): if h < H - K: AUTH[h] = TREEHASH[h].node TREEHASH[h].node = None else: AUTH[h] = RETAIN[h].pop() for h in range(min(tau, H - K)): startidx = s + 1 + 3 * 2**h if startidx < 2**H: TREEHASH[h].__init__(h, startidx) for _ in range((H - K) // 2): l_min = float('inf') h = None for j in range(H - K): if TREEHASH[j].completed: low = float('inf') elif TREEHASH[j].stackusage == 0: low = j else: low = TREEHASH[j].height() if low < l_min: h = j l_min = low if h is not None: TREEHASH[h].update() return AUTH
def traverse(s): """Returns the auth nodes for leaf s + 1.""" tau = next(h for h in range(H) if not (s >> h) & 1) if not (s >> (tau+1)) & 1 and tau < H - 1: KEEP[tau] = AUTH[tau] if tau == 0: AUTH[0] = Node(h=0, v=leafcalc(s)) else: AUTH[tau] = Node(h=tau, v=g(AUTH[tau - 1].v + KEEP[tau - 1].v)) KEEP[tau - 1] = None for h in range(tau): if h < H - K: AUTH[h] = TREEHASH[h].node TREEHASH[h].node = None else: AUTH[h] = RETAIN[h].pop() for h in range(min(tau, H - K)): startidx = s + 1 + 3 * 2**h if startidx < 2 ** H: TREEHASH[h].__init__(h, startidx) for _ in range((H - K) // 2): l_min = float('inf') h = None for j in range(H - K): if TREEHASH[j].completed: low = float('inf') elif TREEHASH[j].stackusage == 0: low = j else: low = TREEHASH[j].height() if low < l_min: h = j l_min = low if h is not None: TREEHASH[h].update() return AUTH
def keygen_and_setup(): """Sets up TREEHASH, RETAIN and AUTH for the start of BDS traversal.""" for h in range(H - K): TREEHASH[h] = Treehash(h, completed=True) stack = [] for j in range(2**H): node1 = Node(h=0, v=leafcalc(j)) if node1.h < H - K and j == 3: TREEHASH[0].node = node1 while stack and stack[-1].h == node1.h: if not AUTH[node1.h]: AUTH[node1.h] = node1 else: # in this case node1 is a right-node with row-index 2j + 3 if node1.h < H - K and TREEHASH[node1.h].node is None: TREEHASH[node1.h].node = node1 elif node1.h >= H - K: RETAIN[node1.h].appendleft(node1) node2 = stack.pop() node1 = Node(h=node1.h + 1, v=g(node2.v + node1.v)) stack.append(node1) return stack.pop()
def keygen_and_setup(): """Sets up TREEHASH, RETAIN and AUTH for the start of BDS traversal.""" for h in range(H - K): TREEHASH[h] = Treehash(h, completed=True) stack = [] for j in range(2 ** H): node1 = Node(h=0, v=leafcalc(j)) if node1.h < H - K and j == 3: TREEHASH[0].node = node1 while stack and stack[-1].h == node1.h: if not AUTH[node1.h]: AUTH[node1.h] = node1 else: # in this case node1 is a right-node with row-index 2j + 3 if node1.h < H - K and TREEHASH[node1.h].node is None: TREEHASH[node1.h].node = node1 elif node1.h >= H - K: RETAIN[node1.h].appendleft(node1) node2 = stack.pop() node1 = Node(h=node1.h + 1, v=g(node2.v + node1.v)) stack.append(node1) return stack.pop()
def keygen_and_setup(): """Sets up TREEHASH, RETAIN and AUTH for the start of BDS traversal.""" for h in range(H - K): TREEHASH[h] = Treehash(h, completed=True) stack = [] for j in range(1 << H): node1 = Node(h=0, v=leafcalc(j)) if node1.h < H - K and j == 3: TREEHASH[0].node = node1 while stack and stack[-1].h == node1.h: if j >> node1.h == 1: AUTH[node1.h] = node1 else: # in this case node1 is a right-node with row-index 2j + 3 if node1.h < H - K and j >> node1.h == 3: TREEHASH[node1.h].node = node1 elif node1.h >= H - K: offset = (1 << (H - 1 - node1.h)) + node1.h - H rowidx = ((j >> node1.h) - 3) >> 1 RETAIN[offset + rowidx] = node1 node2 = stack.pop() node1 = Node(h=node1.h + 1, v=g(node2.v + node1.v)) stack.append(node1) return stack.pop()