I notice that at least one place we return erlang:error({missing_required_data, {BodyHash, UserId, Time}}) for a failed verification.
Wondering if replacing the match of Plain = decrypt_sig, and ContentHash = BodyHash with 
case decrypt_sig(...) of
   Plain -> ok
   Bad -> erlang:error({bad_signature, {Plain, Bad}})  
end 
(And a similar construct for ContentHash)
would be more helpful