{-# LANGUAGE RecordWildCards, MultiWayIf, NamedFieldPuns #-} module Bulletproofs.MultiRangeProof.Verifier ( verifyProof, verifyTPoly, verifyLRCommitment, ) where import Protolude import Data.Curve.Weierstrass.SECP256K1 (PA, Fr, mul, gen) import Bulletproofs.RangeProof.Internal import Bulletproofs.Utils import Bulletproofs.InnerProductProof as IPP hiding (verifyProof) import qualified Bulletproofs.InnerProductProof as IPP -- | Verify that a commitment was computed from a value in a given range verifyProof :: Integer -- ^ Range upper bound -> [PA] -- ^ Commitments of in-range values -> RangeProof Fr PA -- ^ Proof that a secret committed value lies in a certain interval -> Bool verifyProof upperBound vCommits proof@RangeProof{..} = and [ verifyTPoly n vCommitsExp2 proof x y z , verifyLRCommitment n mExp2 proof x y z ] where x = shamirX aCommit sCommit t1Commit t2Commit y z y = shamirY aCommit sCommit z = shamirZ aCommit sCommit y n = logBase2 upperBound m = length vCommits -- Vector of values passed must be of length 2^x vCommitsExp2 = vCommits ++ residueCommits residueCommits = replicate (2 ^ log2Ceil m - m) mempty mExp2 = fromIntegral $ length vCommitsExp2 -- | Verify the constant term of the polynomial t -- t = t(x) = t0 + t1*x + t2*x^2 -- This is what binds the proof to the actual original Pedersen commitment V to the actual value verifyTPoly :: Integer -- ^ Dimension n of the vectors -> [PA] -- ^ Commitments of in-range values -> RangeProof Fr PA -- ^ Proof that a secret committed value lies in a certain interval -> Fr -- ^ Challenge x -> Fr -- ^ Challenge y -> Fr -- ^ Challenge z -> Bool verifyTPoly n vCommits proof@RangeProof{..} x y z = lhs == rhs where m = fromIntegral $ length vCommits lhs = commit t tBlinding rhs = sumExps ((*) (z ^ 2) <$> powerVector z m) vCommits <> (gen `mul` delta n m y z) <> (t1Commit `mul` x) <> (t2Commit `mul` (x ^ 2)) -- | Verify the inner product argument for the vectors l and r that form t verifyLRCommitment :: Integer -- ^ Dimension n of the vectors -> Integer -> RangeProof Fr PA -- ^ Proof that a secret committed value lies in a certain interval -> Fr -- ^ Challenge x -> Fr -- ^ Challenge y -> Fr -- ^ Challenge z -> Bool verifyLRCommitment n m proof@RangeProof{..} x y z = IPP.verifyProof nm IPP.InnerProductBase { bGs = gs, bHs = hs', bH = u } commitmentLR productProof where commitmentLR = computeLRCommitment n m aCommit sCommit t tBlinding mu x y z hs' hs' = zipWith (\yi hi-> hi `mul` recip yi) (powerVector y nm) hs uChallenge = shamirU tBlinding mu t u = gen `mul` uChallenge nm = n * m