class SignatureFragmentGenerator(Iterator[TryteString]): """ Used to generate signature fragments progressively. Each instance can generate 1 signature per fragment in the private key. """ def __init__(self, private_key: PrivateKey, hash_: Hash) -> None: super(SignatureFragmentGenerator, self).__init__() self._key_chunks = private_key.iter_chunks(FRAGMENT_LENGTH) self._iteration = -1 self._normalized_hash = normalize(hash_) self._sponge = Kerl() def __iter__(self) -> 'SignatureFragmentGenerator': return self def __len__(self) -> int: """ Returns the number of fragments this generator can create. Note: This method always returns the same result, no matter how many iterations have been completed. """ return len(self._key_chunks) def __next__(self) -> TryteString: """ Returns the next signature fragment. """ key_trytes: TryteString = next(self._key_chunks) self._iteration += 1 # If the key is long enough, loop back around to the start. normalized_chunk = ( self._normalized_hash[self._iteration % len(self._normalized_hash)] ) signature_fragment = key_trytes.as_trits() # Build the signature, one hash at a time. for i in range(key_trytes.count_chunks(Hash.LEN)): hash_start = i * HASH_LENGTH hash_end = hash_start + HASH_LENGTH buffer: List[int] = signature_fragment[hash_start:hash_end] for _ in range(13 - normalized_chunk[i]): self._sponge.reset() self._sponge.absorb(buffer) self._sponge.squeeze(buffer) signature_fragment[hash_start:hash_end] = buffer return TryteString.from_trits(signature_fragment)
def _create_sponge(self, index: int) -> Kerl: """ Prepares the hash sponge for the generator. """ seed = self.seed_as_trits[:] sponge = Kerl() sponge.absorb(add_trits(seed, trits_from_int(index))) # Squeeze all of the trits out of the sponge and re-absorb them. # Note that the sponge transforms several times per operation, # so this sequence is not as redundant as it looks at first # glance. sponge.squeeze(seed) sponge.reset() sponge.absorb(seed) return sponge
def _create_sponge(self, index): # type: (int) -> Kerl """ Prepares the hash sponge for the generator. """ seed = self.seed_as_trits[:] sponge = Kerl() sponge.absorb(add_trits(seed, trits_from_int(index))) # Squeeze all of the trits out of the sponge and re-absorb them. # Note that the sponge transforms several times per operation, so # this sequence is not as redundant as it looks at first glance. sponge.squeeze(seed) sponge.reset() sponge.absorb(seed) return sponge
class SignatureFragmentGenerator(Iterator[TryteString]): """ Used to generate signature fragments progressively. Each instance can generate 1 signature per fragment in the private key. """ def __init__(self, private_key, hash_): # type: (PrivateKey, Hash) -> None super(SignatureFragmentGenerator, self).__init__() self._key_chunks = private_key.iter_chunks(FRAGMENT_LENGTH) self._iteration = -1 self._normalized_hash = normalize(hash_) self._sponge = Kerl() def __iter__(self): # type: () -> SignatureFragmentGenerator return self def __len__(self): # type: () -> int """ Returns the number of fragments this generator can create. Note: This method always returns the same result, no matter how many iterations have been completed. """ return len(self._key_chunks) def __next__(self): # type: () -> TryteString """ Returns the next signature fragment. """ key_trytes = next(self._key_chunks) # type: TryteString self._iteration += 1 # If the key is long enough, loop back around to the start. normalized_chunk =\ self._normalized_hash[self._iteration % len(self._normalized_hash)] signature_fragment = key_trytes.as_trits() # Build the signature, one hash at a time. for i in range(key_trytes.count_chunks(Hash.LEN)): hash_start = i * HASH_LENGTH hash_end = hash_start + HASH_LENGTH buffer = signature_fragment[hash_start:hash_end] # type: MutableSequence[int] for _ in range(13 - normalized_chunk[i]): self._sponge.reset() self._sponge.absorb(buffer) self._sponge.squeeze(buffer) signature_fragment[hash_start:hash_end] = buffer return TryteString.from_trits(signature_fragment) if PY2: next = __next__