TestGoldilocks.hs
1 2 3 module TestGoldilocks where 4 5 -------------------------------------------------------------------------------- 6 7 import Semantics 8 9 import Common 10 11 -------------------------------------------------------------------------------- 12 -- global parameters 13 14 circomFile :: FilePath 15 circomFile = circuitSourceDir </> "test_wrapper.circom" 16 17 data Op 18 = Neg 19 | Add 20 | Sub 21 | Sqr 22 | Mul 23 | Inv 24 | Div 25 deriving (Eq,Show,Bounded,Enum) 26 27 enumerateOps :: [Op] 28 enumerateOps = enumFromTo minBound maxBound 29 30 ---------------------------------------- 31 32 mainComponent :: Op -> MainComponent 33 mainComponent op = 34 case op of 35 Neg -> unary "Neg" 36 Add -> binary "Add" 37 Sub -> binary "Sub" 38 Sqr -> unary "Sqr" 39 Mul -> binary "Mul" 40 Inv -> unary "Inv" 41 Div -> binary "Div" 42 where 43 44 unary name = MainComponent 45 { _templateName = name ++ "Wrapper" 46 , _templateParams = [] 47 , _publicInputs = ["A"] 48 } 49 50 binary name = MainComponent 51 { _templateName = name ++ "Wrapper" 52 , _templateParams = [] 53 , _publicInputs = ["A","B"] 54 } 55 56 -------------------------------------------------------------------------------- 57 -- test cases and expected semantics 58 59 type TestCase1 = Int 60 type TestCase2 = (Int,Int) 61 62 type Output = Int 63 64 testCasesUnary :: [TestCase1] 65 testCasesUnary = [0..fieldPrime-1] 66 67 testCasesBinary :: [TestCase2] 68 testCasesBinary = [ (a,b) | a<-testCasesUnary , b<-testCasesUnary ] 69 70 -- | Multiplication and division is too slow to test exhaustively 71 testCasesBinarySmall :: [TestCase2] 72 testCasesBinarySmall = [ (a,b) | a<-testset, b<-testset ] where 73 testset = [0..17] ++ [63,64,65] ++ [127,128,129] ++ [191,192,193] ++ [fieldPrime-18..fieldPrime-1] 74 75 ---------------------------------------- 76 77 semantics_neg :: F -> Expected F 78 semantics_neg x = Expecting $ Semantics.neg x 79 80 semantics_add :: (F,F) -> Expected F 81 semantics_add (x,y) = Expecting $ Semantics.add x y 82 83 semantics_sub :: (F,F) -> Expected F 84 semantics_sub (x,y) = Expecting $ Semantics.sub x y 85 86 semantics_sqr :: F -> Expected F 87 semantics_sqr x = Expecting $ Semantics.sqr x 88 89 semantics_mul :: (F,F) -> Expected F 90 semantics_mul (x,y) = Expecting $ Semantics.mul x y 91 92 semantics_inv :: F -> Expected F 93 semantics_inv x = Expecting $ Semantics.inv x 94 95 semantics_div :: (F,F) -> Expected F 96 semantics_div (x,y) = Expecting $ Semantics.div x y 97 98 -------------------------------------------------------------------------------- 99 -- inputs and outputs 100 101 inputsA :: TestCase1 -> Inputs Name Integer 102 inputsA a = Inputs $ toMapping "A" a 103 104 inputsAB :: TestCase2 -> Inputs Name Integer 105 inputsAB (a,b) = Inputs $ toMapping "A" a 106 <> toMapping "B" b 107 108 outputsC :: Output -> Outputs Name Integer 109 outputsC y = Outputs $ toMapping "C" y 110 111 -------------------------------------------------------------------------------- 112 113 specUnary :: Op -> (F -> Expected F) -> TestSpec TestCase1 Output 114 specUnary op semantics = TestSpec circomFile (mainComponent op) inputsA outputsC semantics testCasesUnary 115 116 specBinary :: Op -> ((F,F) -> Expected F) -> TestSpec TestCase2 Output 117 specBinary op semantics = TestSpec circomFile (mainComponent op) inputsAB outputsC semantics testCasesBinary 118 119 specBinarySmall :: Op -> ((F,F) -> Expected F) -> TestSpec TestCase2 Output 120 specBinarySmall op semantics = TestSpec circomFile (mainComponent op) inputsAB outputsC semantics testCasesBinarySmall 121 122 -------------------------------------------------------------------------------- 123 124 input :: TestCase1 -> Inputs Name Integer 125 input x = Inputs $ toMapping "inp" x 126 127 output :: Output -> Outputs Name Integer 128 output y = Outputs $ toMapping "out" y 129 130 131 semantics_toGoldi :: Int -> Expected Int 132 semantics_toGoldi k 133 | k < 0 = ShouldFail 134 | k >= fieldPrime = ShouldFail 135 | otherwise = Expecting k 136 137 main_toGoldi :: MainComponent 138 main_toGoldi = MainComponent 139 { _templateName = "ToGoldilocksWrapper" 140 , _templateParams = [] 141 , _publicInputs = ["inp"] 142 } 143 144 specToGoldi :: TestSpec TestCase1 Output 145 specToGoldi = TestSpec circomFile main_toGoldi input output semantics_toGoldi [-10..300] 146 147 -------------------------------------------------------------------------------- 148 149 semantics_isZero :: Int -> Expected Int 150 semantics_isZero k = Expecting (if k == 0 then 1 else 0) 151 152 main_isZero :: MainComponent 153 main_isZero = MainComponent 154 { _templateName = "IsZero" 155 , _templateParams = [] 156 , _publicInputs = ["inp"] 157 } 158 159 specIsZero :: TestSpec Int Int 160 specIsZero = TestSpec circomFile main_isZero input output semantics_isZero [-50..300] 161 162 -------------------------------------------------------------------------------- 163