packages feed

bulletproofs 0.3.0 → 0.4.0

raw patch · 12 files changed

+172/−67 lines, 12 filesdep +criteriondep ~arithmoidep ~basedep ~protoludePVP ok

version bump matches the API change (PVP)

Dependencies added: criterion

Dependency ranges changed: arithmoi, base, protolude

API changes (from Hackage documentation)

+ Bulletproofs.RangeProof.Internal: instance Control.DeepSeq.NFData Bulletproofs.RangeProof.Internal.RangeProofError
+ Bulletproofs.RangeProof.Internal: instance Control.DeepSeq.NFData f => Control.DeepSeq.NFData (Bulletproofs.RangeProof.Internal.RangeProof f)
+ Bulletproofs.RangeProof.Internal: instance GHC.Generics.Generic (Bulletproofs.RangeProof.Internal.RangeProof f)
+ Bulletproofs.RangeProof.Internal: instance GHC.Generics.Generic Bulletproofs.RangeProof.Internal.RangeProofError
+ Bulletproofs.Utils: addTwoMulP :: AsInteger f => f -> Point -> f -> Point -> Point
+ Bulletproofs.Utils: sumExps :: AsInteger f => [f] -> [Point] -> Point
- Bulletproofs.ArithmeticCircuit.Internal: commitBitVector :: (AsInteger f) => f -> [f] -> [f] -> Point
+ Bulletproofs.ArithmeticCircuit.Internal: commitBitVector :: AsInteger f => f -> [f] -> [f] -> Point
- Bulletproofs.ArithmeticCircuit.Internal: evaluatePolynomial :: (Num f) => Integer -> [[f]] -> f -> [f]
+ Bulletproofs.ArithmeticCircuit.Internal: evaluatePolynomial :: Num f => Integer -> [[f]] -> f -> [f]
- Bulletproofs.ArithmeticCircuit.Internal: genIdenMatrix :: (Num f) => Integer -> [[f]]
+ Bulletproofs.ArithmeticCircuit.Internal: genIdenMatrix :: Num f => Integer -> [[f]]
- Bulletproofs.ArithmeticCircuit.Internal: genZeroMatrix :: (Num f) => Integer -> Integer -> [[f]]
+ Bulletproofs.ArithmeticCircuit.Internal: genZeroMatrix :: Num f => Integer -> Integer -> [[f]]
- Bulletproofs.ArithmeticCircuit.Internal: matrixVectorProduct :: (Num f) => [[f]] -> [f] -> [f]
+ Bulletproofs.ArithmeticCircuit.Internal: matrixVectorProduct :: Num f => [[f]] -> [f] -> [f]
- Bulletproofs.ArithmeticCircuit.Internal: powerMatrix :: (Num f) => [[f]] -> Integer -> [[f]]
+ Bulletproofs.ArithmeticCircuit.Internal: powerMatrix :: Num f => [[f]] -> Integer -> [[f]]
- Bulletproofs.ArithmeticCircuit.Internal: vectorMatrixProduct :: (Num f) => [f] -> [[f]] -> [f]
+ Bulletproofs.ArithmeticCircuit.Internal: vectorMatrixProduct :: Num f => [f] -> [[f]] -> [f]
- Bulletproofs.ArithmeticCircuit.Internal: vectorMatrixProductT :: (Num f) => [f] -> [[f]] -> [f]
+ Bulletproofs.ArithmeticCircuit.Internal: vectorMatrixProductT :: Num f => [f] -> [[f]] -> [f]
- Bulletproofs.Fq: euclidean :: (Integral a) => a -> a -> a
+ Bulletproofs.Fq: euclidean :: Integral a => a -> a -> a
- Bulletproofs.Fq: inv' :: (Integral a) => a -> a -> (a, a)
+ Bulletproofs.Fq: inv' :: Integral a => a -> a -> (a, a)

Files

Bulletproofs/ArithmeticCircuit/Internal.hs view
@@ -110,8 +110,8 @@ commitBitVector vBlinding vL vR = vLG `addP` vRH `addP` vBlindingH   where     vBlindingH = vBlinding `mulP` h-    vLG = foldl' addP Crypto.PointO ( zipWith mulP vL gs )-    vRH = foldl' addP Crypto.PointO ( zipWith mulP vR hs )+    vLG = sumExps vL gs+    vRH = sumExps vR hs  shamirGxGxG :: (Show f, Num f) => Crypto.Point -> Crypto.Point -> Crypto.Point -> f shamirGxGxG p1 p2 p3@@ -187,7 +187,10 @@  generateGateWeights :: (Crypto.MonadRandom m, Num f) => Integer -> Integer -> m (GateWeights f) generateGateWeights lConstraints n = do-  [wL, wR, wO] <- replicateM 3 ((\i -> insertAt (fromIntegral i) (oneVector n) (replicate (fromIntegral lConstraints - 1) (zeroVector n))) <$> generateMax (fromIntegral lConstraints))+  let genVec = ((\i -> insertAt (fromIntegral i) (oneVector n) (replicate (fromIntegral lConstraints - 1) (zeroVector n))) <$> generateMax (fromIntegral lConstraints))+  wL <- genVec+  wR <- genVec+  wO <- genVec   pure $ GateWeights wL wR wO   where     zeroVector x = replicate (fromIntegral x) 0
Bulletproofs/ArithmeticCircuit/Prover.hs view
@@ -23,8 +23,11 @@   -> m (ArithCircuitProof f) generateProof (padCircuit -> ArithCircuit{..}) ArithWitness{..} = do   let GateWeights{..} = weights-  let Assignment{..} = padAssignment assignment-  [aiBlinding, aoBlinding, sBlinding] <- replicateM 3 ((fromInteger :: Integer -> f) <$> generateMax q)+      Assignment{..} = padAssignment assignment+      genBlinding = (fromInteger :: Integer -> f) <$> generateMax q+  aiBlinding <- genBlinding+  aoBlinding <- genBlinding+  sBlinding <- genBlinding   let n = fromIntegral $ length aL       aiCommit = commitBitVector aiBlinding aL aR  -- commitment to aL, aR       aoCommit = commitBitVector aoBlinding aO []  -- commitment to aO@@ -42,7 +45,7 @@       zwO = zs `vectorMatrixProduct` wO        -- Polynomials-      [lPoly, rPoly] = computePolynomials n aL aR aO sL sR y zwL zwR zwO+      (lPoly, rPoly) = computePolynomials n aL aR aO sL sR y zwL zwR zwO       tPoly = multiplyPoly lPoly rPoly        w = (aL `vectorMatrixProductT` wL)@@ -58,7 +61,7 @@   let tCommits = zipWith commit tPoly tBlindings    let x = shamirGs tCommits-      evalTCommit = foldl' addP Crypto.PointO (zipWith mulP (powerVector x 7) tCommits)+      evalTCommit = sumExps (powerVector x 7) tCommits    let ls = evaluatePolynomial n lPoly x       rs = evaluatePolynomial n rPoly x@@ -79,8 +82,8 @@       commitmentLR = (x `mulP` aiCommit)                    `addP` (fSquare x `mulP` aoCommit)                    `addP` ((x ^ 3)`mulP` sCommit)-                   `addP` foldl' addP Crypto.PointO (zipWith mulP gExp gs)-                   `addP` foldl' addP Crypto.PointO (zipWith mulP hExp hs')+                   `addP` sumExps gExp gs+                   `addP` sumExps hExp hs'                    `addP` Crypto.pointNegate curve (mu `mulP` h)                    `addP` (t `mulP` u) @@ -102,9 +105,9 @@   where     qLen = fromIntegral $ length commitmentWeights     computePolynomials n aL aR aO sL sR y zwL zwR zwO-      = [ [l0, l1, l2, l3]+      = ( [l0, l1, l2, l3]         , [r0, r1, r2, r3]-        ]+        )       where         l0 = replicate (fromIntegral n) 0         l1 = aL ^+^ (powerVector (recip y) n `hadamardp` zwR)
Bulletproofs/ArithmeticCircuit/Verifier.hs view
@@ -41,9 +41,9 @@      hs' = zipWith mulP (powerVector (recip y) n) hs -    wLCommit = foldl' addP Crypto.PointO (zipWith mulP (zs `vectorMatrixProduct` wL) hs')-    wRCommit = foldl' addP Crypto.PointO (zipWith mulP wRExp gs)-    wOCommit = foldl' addP Crypto.PointO (zipWith mulP (zs `vectorMatrixProduct` wO) hs')+    wLCommit = sumExps (zs `vectorMatrixProduct` wL) hs'+    wRCommit = sumExps wRExp gs+    wOCommit = sumExps (zs `vectorMatrixProduct` wO) hs'     wRExp = powerVector (recip y) n `hadamardp` (zs `vectorMatrixProduct` wL)      uChallenge = shamirU tBlinding mu t@@ -54,13 +54,13 @@         lhs = commit t tBlinding         rhs = (gExp `mulP` g)             `addP` tCommitsExpSum-            `addP` foldl' addP Crypto.PointO ( zipWith mulP vExp vCommits )+            `addP` sumExps vExp vCommits         gExp = fSquare x * (k + cQ)         cQ = zs `dot` cs         vExp = (*) (fSquare x) <$> (zs `vectorMatrixProduct` commitmentWeights)         k = delta n y zwL zwR         xs = 0 : x : 0 : (((^) x) <$> [3..6])-        tCommitsExpSum = foldl' addP Crypto.PointO (zipWith mulP xs tCommits)+        tCommitsExpSum = sumExps xs tCommits      verifyLRCommitment       = IPP.verifyProof@@ -74,7 +74,7 @@         commitmentLR = (x `mulP` aiCommit)                      `addP` (fSquare x `mulP` aoCommit)                      `addP` ((x ^ 3) `mulP` sCommit)-                     `addP` foldl' addP Crypto.PointO (zipWith mulP gExp gs)-                     `addP` foldl' addP Crypto.PointO (zipWith mulP hExp hs')+                     `addP` sumExps gExp gs+                     `addP` sumExps hExp hs'                      `addP` Crypto.pointNegate curve (mu `mulP` h)                      `addP` (t `mulP` u)
Bulletproofs/InnerProductProof/Prover.hs view
@@ -6,6 +6,7 @@  import Protolude +import Control.Exception (assert) import qualified Data.List as L import qualified Data.Map as Map @@ -47,17 +48,13 @@   = case (ls, rs) of     ([], [])   -> InnerProductProof [] [] 0 0     ([l], [r]) -> InnerProductProof (reverse lCommits) (reverse rCommits) l r-    _          -> if | not checkLGs -> panic "Error in: l' * Gs' == l * Gs + x^2 * A_L + x^(-2) * A_R"-                     | not checkRHs -> panic "Error in: r' * Hs' == r * Hs + x^2 * B_L + x^(-2) * B_R"-                     | not checkLBs -> panic "Error in: l' * r' == l * r + x^2 * (lsLeft * rsRight) + x^-2 * (lsRight * rsLeft)"-                     | not checkC -> panic "Error in: C == zG + aG + bH'"-                     | not checkC' -> panic "Error in: C' = C + x^2 L + x^-2 R == z'G + a'G + b'H'"-                     | otherwise -> generateProof'-                         InnerProductBase { bGs = gs'', bHs = hs'', bH = bH }-                         commitmentLR'-                         InnerProductWitness { ls = ls', rs = rs' }-                         (lCommit:lCommits)-                         (rCommit:rCommits)+    _          -> assert (checkLGs && checkRHs && checkLBs && checkC && checkC')+                $ generateProof'+                    InnerProductBase { bGs = gs'', bHs = hs'', bH = bH }+                    commitmentLR'+                    InnerProductWitness { ls = ls', rs = rs' }+                    (lCommit:lCommits)+                    (rCommit:rCommits)   where     n' = fromIntegral $ length ls     nPrime = n' `div` 2@@ -70,15 +67,15 @@     cL = dot lsLeft rsRight     cR = dot lsRight rsLeft -    lCommit = foldl' addP Crypto.PointO (zipWith mulP lsLeft gsRight)+    lCommit = sumExps lsLeft gsRight          `addP`-         foldl' addP Crypto.PointO (zipWith mulP rsRight hsLeft)+         sumExps rsRight hsLeft          `addP`          (cL `mulP` bH) -    rCommit = foldl' addP Crypto.PointO (zipWith mulP lsRight gsLeft)+    rCommit = sumExps lsRight gsLeft          `addP`-         foldl' addP Crypto.PointO (zipWith mulP rsLeft hsRight)+         sumExps rsLeft hsRight          `addP`          (cR `mulP` bH) @@ -88,8 +85,8 @@     xs = replicate nPrime x     xsInv = replicate nPrime xInv -    gs'' = zipWith addP (zipWith mulP xsInv gsLeft) (zipWith mulP xs gsRight)-    hs'' = zipWith addP (zipWith mulP xs hsLeft) (zipWith mulP xsInv hsRight)+    gs'' = zipWith (\(exp0, pt0) (exp1, pt1) -> addTwoMulP exp0 pt0 exp1 pt1) (zip xsInv gsLeft) (zip xs gsRight)+    hs'' = zipWith (\(exp0, pt0) (exp1, pt1) -> addTwoMulP exp0 pt0 exp1 pt1) (zip xs hsLeft) (zip xsInv hsRight)      ls' = ((*) x <$> lsLeft) ^+^ ((*) xInv <$> lsRight)     rs' = ((*) xInv <$> rsLeft) ^+^ ((*) x <$> rsRight)@@ -105,25 +102,25 @@     -- Checks     ----------------------------- -    aL' = foldl' addP Crypto.PointO (zipWith mulP lsLeft gsRight)-    aR' = foldl' addP Crypto.PointO (zipWith mulP lsRight gsLeft)+    aL' = sumExps lsLeft gsRight+    aR' = sumExps lsRight gsLeft -    bL' = foldl' addP Crypto.PointO (zipWith mulP rsLeft hsRight)-    bR' = foldl' addP Crypto.PointO (zipWith mulP rsRight hsLeft)+    bL' = sumExps rsLeft hsRight+    bR' = sumExps rsRight hsLeft      z = dot ls rs     z' = dot ls' rs' -    lGs = foldl' addP Crypto.PointO (zipWith mulP ls bGs)-    rHs = foldl' addP Crypto.PointO (zipWith mulP rs bHs)+    lGs = sumExps ls bGs+    rHs = sumExps rs bHs -    lGs' = foldl' addP Crypto.PointO (zipWith mulP ls' gs'')-    rHs' = foldl' addP Crypto.PointO (zipWith mulP rs' hs'')+    lGs' = sumExps ls' gs''+    rHs' = sumExps rs' hs''      checkLGs       = lGs'         ==-        foldl' addP Crypto.PointO (zipWith mulP ls bGs)+        sumExps ls bGs         `addP`         (fSquare x `mulP` aL')         `addP`@@ -132,7 +129,7 @@     checkRHs       = rHs'         ==-        foldl' addP Crypto.PointO (zipWith mulP rs bHs)+        sumExps rs bHs         `addP`         (fSquare x `mulP` bR')         `addP`@@ -160,5 +157,3 @@         lGs'         `addP`         rHs'--
Bulletproofs/InnerProductProof/Verifier.hs view
@@ -37,8 +37,8 @@         `addP`         ((l * r) `mulP` bH) -    gsCommit = foldl' addP Crypto.PointO (zipWith mulP otherExponents bGs)-    hsCommit = foldl' addP Crypto.PointO (zipWith mulP (reverse otherExponents) bHs)+    gsCommit = sumExps otherExponents bGs+    hsCommit = sumExps (reverse otherExponents) bHs  mkChallenges :: (AsInteger f, Field f) => InnerProductProof f -> Crypto.Point -> ([f], [f], Crypto.Point) mkChallenges InnerProductProof{ lCommits, rCommits } commitmentLR
Bulletproofs/MultiRangeProof/Prover.hs view
@@ -20,7 +20,7 @@ import Bulletproofs.InnerProductProof as IPP hiding (generateProof) import qualified Bulletproofs.InnerProductProof as IPP --- | Prove that a list of values lie in a specific range+-- | Prove that a list of values lies in a specific range generateProof   :: (AsInteger f, Eq f, Field f, Show f, MonadRandom m)   => Integer                -- ^ Upper bound of the range we want to prove@@ -74,9 +74,11 @@    (sL, sR) <- chooseBlindingVectors nm -  [aBlinding, sBlinding]-    <- replicateM 2 ((fromInteger :: Integer -> f) <$> generateMax q)+  let genBlinding = (fromInteger :: Integer -> f) <$> generateMax q +  aBlinding <- genBlinding+  sBlinding <- genBlinding+   (aCommit, sCommit) <- commitBitVectors aBlinding sBlinding aL aR sL sR    -- Oracle generates y, z from a, c@@ -86,9 +88,8 @@   let lrPoly@LRPolys{..} = computeLRPolys n m aL aR sL sR y z       tPoly@TPoly{..} = computeTPoly lrPoly -  [t1Blinding, t2Blinding]-    <- replicateM 2 ((fromInteger :: Integer -> f) <$> generateMax q)-+  t1Blinding <- genBlinding+  t2Blinding <- genBlinding    let t1Commit = commit t1 t1Blinding       t2Commit = commit t2 t2Blinding
Bulletproofs/MultiRangeProof/Verifier.hs view
@@ -63,7 +63,7 @@     m = fromIntegral $ length vCommits     lhs = commit t tBlinding     rhs =-          foldl' addP Crypto.PointO ( zipWith mulP ((*) (fSquare z) <$> powerVector z m) vCommits )+          sumExps ((*) (fSquare z) <$> powerVector z m) vCommits           `addP`           (delta n m y z `mulP` g)           `addP`
Bulletproofs/RangeProof/Internal.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-} module Bulletproofs.RangeProof.Internal where  import Protolude@@ -37,14 +38,14 @@     , productProof :: InnerProductProof f     -- ^ Inner product argument to prove that a commitment P     -- has vectors l, r ∈  Z^n for which P = l · G + r · H + ( l, r ) · U-    } deriving (Show, Eq)+    } deriving (Show, Eq, Generic, NFData)  data RangeProofError   = UpperBoundTooLarge Integer  -- ^ The upper bound of the range is too large   | ValueNotInRange Integer     -- ^ Value is not within the range required   | ValuesNotInRange [Integer]  -- ^ Values are not within the range required   | NNotPowerOf2 Integer        -- ^ Dimension n is required to be a power of 2-  deriving (Show, Eq)+  deriving (Show, Eq, Generic, NFData)  ----------------------------- -- Polynomials@@ -136,10 +137,10 @@   -> [f]   -> m (Crypto.Point, Crypto.Point) commitBitVectors aBlinding sBlinding aL aR sL sR = do-    let aLG = foldl' addP Crypto.PointO ( zipWith mulP aL gs )-        aRH = foldl' addP Crypto.PointO ( zipWith mulP aR hs )-        sLG = foldl' addP Crypto.PointO ( zipWith mulP sL gs )-        sRH = foldl' addP Crypto.PointO ( zipWith mulP sR hs )+    let aLG = sumExps aL gs+        aRH = sumExps aR hs+        sLG = sumExps sL gs+        sRH = sumExps sR hs         aBlindingH = mulP aBlinding h         sBlindingH = mulP sBlinding h @@ -190,10 +191,10 @@     `addP`     Crypto.pointNegate curve (z `mulP` gsSum)             -- (- zG)     `addP`-    foldl' addP Crypto.PointO (zipWith mulP hExp hs')     -- (hExp Hs')+    sumExps hExp hs'     -- (hExp Hs')     `addP`     foldl'-      (\acc j -> acc `addP` foldl' addP Crypto.PointO (zipWith mulP (hExp' j) (sliceHs' j)))+      (\acc j -> acc `addP` sumExps (hExp' j) (sliceHs' j))       Crypto.PointO       [1..m]     `addP`
Bulletproofs/Utils.hs view
@@ -58,10 +58,21 @@ mulP :: AsInteger f => f -> Crypto.Point -> Crypto.Point mulP x = Crypto.pointMul curve (asInteger x) +-- | Double exponentiation (Shamir's trick): g0^x0 + g1^x1+addTwoMulP :: AsInteger f => f -> Crypto.Point -> f -> Crypto.Point -> Crypto.Point+addTwoMulP exp0 pt0 exp1 pt1 = Crypto.pointAddTwoMuls curve (asInteger exp0) pt0 (asInteger exp1) pt1++-- | Raise every point to the corresponding exponent, sum up results+sumExps :: AsInteger f => [f] -> [Crypto.Point] -> Crypto.Point+sumExps (exp0:exp1:exps) (pt0:pt1:pts)+  = addTwoMulP exp0 pt0 exp1 pt1 `addP` sumExps exps pts+sumExps (exp:_) (pt:_) = mulP exp pt -- this also catches cases where either list is longer than the other+sumExps _ _ = Crypto.PointO  -- this catches cases where either list is empty+ -- | Create a Pedersen commitment to a value given -- a value and a blinding factor commit :: AsInteger f => f -> f -> Crypto.Point-commit x r = (x `mulP` g) `addP` (r `mulP` h)+commit x r = addTwoMulP x g r h  isLogBase2 :: Integer -> Bool isLogBase2 x
ChangeLog.md view
@@ -3,3 +3,26 @@ ## 0.1  * Initial release.+* Implementation of the Bulletproofs protocol for range proofs+* Use of the improved inner-product argument to reduce the communication complexity+* Support for SECp256k1 curve++## 0.2++* Prove and verify computations of arithmetic circuits using Bulletproofs+  protocol.+* Extend range proofs with support for multi-range proofs.+* Add documentation and provide examples to explain and use arithmetic circuits.+* Provide examples for using aggregated range proofs.+* Add multi-range proofs documentation.++## 0.3++* Update dependencies++## 0.4++* Use double exponentiation to improve performance.+* Use Control.Exception.assert to make sure debugging assertions are not checked+  when compiled with optimisations.+* Add benchmarks for rangeproofs.
+ bench/Main.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- To run this, run "stack bench"++module Main where++import Protolude++import Criterion.Main+import qualified Crypto.PubKey.ECC.Types as Crypto+import qualified Bulletproofs.RangeProof as RP+import qualified Bulletproofs.Utils as Utils+import qualified Bulletproofs.Fq as Fq++upperBound :: Integer+upperBound = 2 ^ (2 ^ 6)++benchInput :: (Integer, Integer)+benchInput = (7238283, 827361)++proof :: (Integer, Integer) -> IO (RP.RangeProof Fq.Fq)+proof input = do+  Right proof <- runExceptT $ RP.generateProof upperBound input+  pure proof++prepareProof :: IO (Crypto.Point, RP.RangeProof Fq.Fq)+prepareProof = do+  proofObj <- proof benchInput+  let cm = Utils.commit (fst benchInput) (snd benchInput)+  pure (cm, proofObj)++verify :: Crypto.Point -> RP.RangeProof Fq.Fq -> Bool+verify = RP.verifyProof upperBound++rangeproofBenchmarks :: [Benchmark]+rangeproofBenchmarks+  = [ bench "Proving" $ nfAppIO proof benchInput+    , env prepareProof $ \ ~(cm, proofObj) -> bench "Verifying" $ nf (uncurry verify) (cm, proofObj)+    ]++main :: IO ()+main = defaultMain+  [ bgroup "Rangeproof" rangeproofBenchmarks ]
bulletproofs.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 3cc8d96dc71be213e360a7402cd170482c94bcd862ac5cfeb4687ac2726aa53f+-- hash: 45ba76c7c1825f4c36913fb81f9c8f6c9691748248208ec2ff4d1bbb54c9a836  name:           bulletproofs-version:        0.3.0+version:        0.4.0 description:    Please see the README on GitHub at <https://github.com/adjoint-io/bulletproofs#readme> category:       Cryptography homepage:       https://github.com/adjoint-io/bulletproofs#readme@@ -85,6 +85,31 @@     , random-shuffle     , tasty     , tasty-discover+    , tasty-hunit+    , tasty-quickcheck+    , text+  default-language: Haskell2010++benchmark rangeproof-benchmarks+  type: exitcode-stdio-1.0+  main-is: Main.hs+  other-modules:+      Paths_bulletproofs+  hs-source-dirs:+      bench+  build-depends:+      MonadRandom+    , QuickCheck+    , arithmoi+    , base >=4.7 && <5+    , bulletproofs+    , containers+    , criterion >=1.5.1.0+    , cryptonite+    , memory+    , protolude >=0.2+    , random-shuffle+    , tasty     , tasty-hunit     , tasty-quickcheck     , text