@@ -7,6 +7,8 @@ import Protolude hiding (head)
77import Data.List (head )
88import qualified Data.List as List
99import qualified Data.Map as Map
10+ import Test.QuickCheck
11+ import PrimeField (PrimeField (.. ), toInt )
1012
1113import System.Random.Shuffle (shuffleM )
1214import qualified Crypto.Random.Types as Crypto (MonadRandom (.. ))
@@ -103,10 +105,10 @@ padAssignment Assignment{..}
103105 aRNew = padToNearestPowerOfTwo aR
104106 aONew = padToNearestPowerOfTwo aO
105107
106- delta :: (Eq f , Field f ) => Integer -> f -> [f ] -> [f ] -> f
108+ delta :: (KnownNat p ) => Integer -> PrimeField p -> [PrimeField p ] -> [PrimeField p ] -> PrimeField p
107109delta n y zwL zwR= (powerVector (recip y) n `hadamardp` zwR) `dot` zwL
108110
109- commitBitVector :: (AsInteger f ) => f -> [f ] -> [f ] -> Crypto. Point
111+ commitBitVector :: (KnownNat p ) => PrimeField p -> [PrimeField p ] -> [PrimeField p ] -> Crypto. Point
110112commitBitVector vBlinding vL vR = vLG `addP` vRH `addP` vBlindingH
111113 where
112114 vBlindingH = vBlinding `mulP` h
@@ -115,13 +117,13 @@ commitBitVector vBlinding vL vR = vLG `addP` vRH `addP` vBlindingH
115117
116118shamirGxGxG :: (Show f , Num f ) => Crypto. Point -> Crypto. Point -> Crypto. Point -> f
117119shamirGxGxG p1 p2 p3
118- = fromInteger $ oracle $ show q <> pointToBS p1 <> pointToBS p2 <> pointToBS p3
120+ = fromInteger $ oracle $ show _q <> pointToBS p1 <> pointToBS p2 <> pointToBS p3
119121
120122shamirGs :: (Show f , Num f ) => [Crypto. Point ] -> f
121- shamirGs ps = fromInteger $ oracle $ show q <> foldMap pointToBS ps
123+ shamirGs ps = fromInteger $ oracle $ show _q <> foldMap pointToBS ps
122124
123125shamirZ :: (Show f , Num f ) => f -> f
124- shamirZ z = fromInteger $ oracle $ show q <> show z
126+ shamirZ z = fromInteger $ oracle $ show _q <> show z
125127
126128---------------------------------------------
127129-- Polynomials
@@ -180,30 +182,7 @@ genIdenMatrix size = (\x -> (\y -> fromIntegral (fromEnum (x == y))) <$> [1..siz
180182genZeroMatrix :: (Num f ) => Integer -> Integer -> [[f ]]
181183genZeroMatrix (fromIntegral -> n) (fromIntegral -> m) = replicate n (replicate m 0 )
182184
183- generateWv :: (Num f , MonadRandom m ) => Integer -> Integer -> m [[f ]]
184- generateWv lConstraints m
185- | lConstraints < m = panic " Number of constraints must be bigger than m"
186- | otherwise = shuffleM (genIdenMatrix m ++ genZeroMatrix (lConstraints - m) m)
187-
188- generateGateWeights :: (Crypto. MonadRandom m , Num f ) => Integer -> Integer -> m (GateWeights f )
189- generateGateWeights lConstraints n = do
190- let genVec = ((\ i -> insertAt (fromIntegral i) (oneVector n) (replicate (fromIntegral lConstraints - 1 ) (zeroVector n))) <$> generateMax (fromIntegral lConstraints))
191- wL <- genVec
192- wR <- genVec
193- wO <- genVec
194- pure $ GateWeights wL wR wO
195- where
196- zeroVector x = replicate (fromIntegral x) 0
197- oneVector x = replicate (fromIntegral x) 1
198-
199- generateRandomAssignment :: forall f m . (Num f , AsInteger f , Crypto. MonadRandom m ) => Integer -> m (Assignment f )
200- generateRandomAssignment n = do
201- aL <- replicateM (fromIntegral n) ((fromInteger :: Integer -> f ) <$> generateMax (2 ^ n))
202- aR <- replicateM (fromIntegral n) ((fromInteger :: Integer -> f ) <$> generateMax (2 ^ n))
203- let aO = aL `hadamardp` aR
204- pure $ Assignment aL aR aO
205-
206- computeInputValues :: (Field f , Eq f ) => GateWeights f -> [[f ]] -> Assignment f -> [f ] -> [f ]
185+ computeInputValues :: (KnownNat p ) => GateWeights (PrimeField p ) -> [[PrimeField p ]] -> Assignment (PrimeField p ) -> [PrimeField p ] -> [PrimeField p ]
207186computeInputValues GateWeights {.. } wV Assignment {.. } cs
208187 = solveLinearSystem $ zipWith (\ row s -> reverse $ s : row) wV solutions
209188 where
@@ -212,7 +191,7 @@ computeInputValues GateWeights{..} wV Assignment{..} cs
212191 ^+^ vectorMatrixProductT aO wO
213192 ^-^ cs
214193
215- gaussianReduce :: (Field f , Eq f ) => [[f ]] -> [[f ]]
194+ gaussianReduce :: (KnownNat p ) => [[PrimeField p ]] -> [[PrimeField p ]]
216195gaussianReduce matrix = fixlastrow $ foldl reduceRow matrix [0 .. length matrix- 1 ]
217196 where
218197 -- Swaps element at position a with element at position b.
@@ -247,13 +226,80 @@ gaussianReduce matrix = fixlastrow $ foldl reduceRow matrix [0..length matrix-1]
247226 nz = List. last (List. init row)
248227
249228-- Solve a matrix (must already be in REF form) by back substitution.
250- substituteMatrix :: (Field f , Eq f ) => [[f ]] -> [f ]
229+ substituteMatrix :: (KnownNat p ) => [[PrimeField p ]] -> [PrimeField p ]
251230substituteMatrix matrix = foldr next [List. last (List. last matrix)] (List. init matrix)
252231 where
253232 next row found = let
254233 subpart = List. init $ drop (length matrix - length found) row
255234 solution = List. last row - sum (zipWith (*) found subpart)
256235 in solution : found
257236
258- solveLinearSystem :: (Field f , Eq f ) => [[f ]] -> [f ]
237+ solveLinearSystem :: (KnownNat p ) => [[PrimeField p ]] -> [PrimeField p ]
259238solveLinearSystem = reverse . substituteMatrix . gaussianReduce
239+
240+ -------------------------
241+ -- Arbitrary instances --
242+ -------------------------
243+
244+ instance (KnownNat p ) => Arbitrary (ArithCircuit (PrimeField p )) where
245+ arbitrary = do
246+ n <- choose (1 , 100 )
247+ m <- choose (1 , n)
248+ arithCircuitGen n m
249+
250+ arithCircuitGen :: forall p . (KnownNat p ) => Integer -> Integer -> Gen (ArithCircuit (PrimeField p ))
251+ arithCircuitGen n m = do
252+ -- TODO: Can lConstraints be a different value?
253+ let lConstraints = m
254+
255+ cs <- vectorOf (fromIntegral m) arbitrary
256+
257+ weights@ GateWeights {.. } <- gateWeightsGen lConstraints n
258+ let gateWeights = GateWeights wL wR wO
259+
260+ commitmentWeights <- wvGen lConstraints m
261+ pure $ ArithCircuit gateWeights commitmentWeights cs
262+ where
263+ gateWeightsGen :: Integer -> Integer -> Gen (GateWeights (PrimeField p ))
264+ gateWeightsGen lConstraints n = do
265+ let genVec = ((\ i -> insertAt i (oneVector n) (replicate (fromIntegral lConstraints - 1 ) (zeroVector n))) <$> choose (0 , fromIntegral lConstraints))
266+ wL <- genVec
267+ wR <- genVec
268+ wO <- genVec
269+ pure $ GateWeights wL wR wO
270+
271+ wvGen :: Integer -> Integer -> Gen [[PrimeField p ]]
272+ wvGen lConstraints m
273+ | lConstraints < m = panic " Number of constraints must be bigger than m"
274+ | otherwise = shuffle (genIdenMatrix m ++ genZeroMatrix (lConstraints - m) m)
275+ zeroVector x = replicate (fromIntegral x) 0
276+ oneVector x = replicate (fromIntegral x) 1
277+
278+
279+ instance (KnownNat p ) => Arbitrary (Assignment (PrimeField p )) where
280+ arbitrary = do
281+ n <- (arbitrary :: Gen Integer )
282+ arithAssignmentGen n
283+
284+ arithAssignmentGen :: (KnownNat p ) => Integer -> Gen (Assignment (PrimeField p ))
285+ arithAssignmentGen n = do
286+ aL <- vectorOf (fromIntegral n) (fromInteger <$> choose (0 , 2 ^ n))
287+ aR <- vectorOf (fromIntegral n) (fromInteger <$> choose (0 , 2 ^ n))
288+ let aO = aL `hadamardp` aR
289+ pure $ Assignment aL aR aO
290+
291+ instance (KnownNat p ) => Arbitrary (ArithWitness (PrimeField p )) where
292+ arbitrary = do
293+ n <- choose (1 , 100 )
294+ m <- choose (1 , n)
295+ arithCircuit <- arithCircuitGen n m
296+ assignment <- arithAssignmentGen n
297+ arithWitnessGen assignment arithCircuit m
298+
299+ arithWitnessGen :: (KnownNat p ) => Assignment (PrimeField p ) -> ArithCircuit (PrimeField p ) -> Integer -> Gen (ArithWitness (PrimeField p ))
300+ arithWitnessGen assignment arith@ ArithCircuit {.. } m = do
301+ commitBlinders <- vectorOf (fromIntegral m) arbitrary
302+ let vs = computeInputValues weights commitmentWeights assignment cs
303+ commitments = zipWith commit vs commitBlinders
304+ pure $ ArithWitness assignment commitments commitBlinders
305+
0 commit comments