diff --git a/src/apps/monero/xmr/bulletproof.py b/src/apps/monero/xmr/bulletproof.py index 3c94b7c8a..34c9274a0 100644 --- a/src/apps/monero/xmr/bulletproof.py +++ b/src/apps/monero/xmr/bulletproof.py @@ -246,12 +246,16 @@ def hash_to_scalar(dst, data): return dst -def hash_vct_to_scalar(dst, data): # TODO: frag-optim +def hash_vct_to_scalar(dst, data): dst = _ensure_dst_key(dst) ctx = crypto.get_keccak() for x in data: ctx.update(x) - crypto.encodeint_into(crypto.decodeint(ctx.digest()), dst) + hsh = ctx.digest() + + crypto.decodeint_into(tmp_sc_1, hsh) + crypto.encodeint_into(tmp_sc_1, tmp_bf_1) + copy_key(dst, tmp_bf_1) return dst @@ -287,7 +291,7 @@ def idxize(self, idx): if idx < 0: idx = self.size + idx if idx >= self.size: - raise ValueError("Index out of bounds") + raise IndexError("Index out of bounds") return idx def __getitem__(self, item): @@ -466,6 +470,28 @@ def resize(self, nsize, chop=False): raise ValueError("Not supported") +class KeyVPowers(KeyVBase): + def __init__(self, size, x): + super().__init__(size) + self.x = x + self.cur = bytearray(32) + self.last_idx = 0 + + def __getitem__(self, item): + prev = self.last_idx + item = self.idxize(item) + self.last_idx = item + + if item == 0: + return copy_key(self.cur, ONE) + elif item == 1: + return copy_key(self.cur, self.x) + elif item == prev + 1: + return sc_mul(self.cur, self.cur, self.x) + else: + IndexError('Only linear scan allowed') + + def _ensure_dst_keyvect(dst=None, size=None): if dst is None: dst = KeyV(elems=size) @@ -506,7 +532,7 @@ def vector_powers(x, n, dst=None): return dst -def vector_power_sum(x, n, dst=None): # TODO: frag-optim +def vector_power_sum(x, n, dst=None): dst = _ensure_dst_key(dst) if n == 0: return copy_key(dst, ZERO) @@ -1216,7 +1242,7 @@ def _prove_batch_main(self, V, gamma, aL, aR, hash_cache, logM, logN, M, N): r0 = vector_add(aR, zMN) del (zMN, twoN) - yMN = vector_powers(y, MN) + yMN = KeyVPowers(MN, y) # full: vector_powers(y, MN) hadamard(r0, yMN, dst=r0) vector_add(r0, zero_twos, dst=r0) del (zero_twos)