diff --git a/src/_zkapauthorizer/controller.py b/src/_zkapauthorizer/controller.py index 61399a15f29c3c6b1a293948755310976758d3e6..693e3eb18956d6147a3777c014f747b88f3941c0 100644 --- a/src/_zkapauthorizer/controller.py +++ b/src/_zkapauthorizer/controller.py @@ -41,6 +41,15 @@ from base64 import ( b64encode, b64decode, ) +from contextlib import ( + contextmanager, +) +from resource import ( + RLIMIT_STACK, + getrlimit, + setrlimit, +) + import attr from zope.interface import ( @@ -469,12 +478,14 @@ class RistrettoRedeemer(object): clients_proof = privacypass.BatchDLEQProof.decode_base64( marshaled_proof.encode("ascii"), ) - clients_unblinded_tokens = clients_proof.invalid_or_unblind( - random_tokens, - blinded_tokens, - clients_signed_tokens, - public_key, - ) + with unlimited_stack(): + self._log.info("Decoded batch proof") + clients_unblinded_tokens = clients_proof.invalid_or_unblind( + random_tokens, + blinded_tokens, + clients_signed_tokens, + public_key, + ) self._log.info("Validated proof") returnValue(list( UnblindedToken(token.encode_base64().decode("ascii")) @@ -795,3 +806,16 @@ def bracket(first, last, between): else: yield last() returnValue(result) + + +@contextmanager +def unlimited_stack(): + """ + A context manager which removes the resource limit on stack size for + execution of the context. + """ + soft, hard = getrlimit(RLIMIT_STACK) + # We can raise the soft limit to the hard limit and no higher. + setrlimit(RLIMIT_STACK, (hard, hard)) + yield + setrlimit(RLIMIT_STACK, (soft, hard))