Skip to content

Commit 991fb0c

Browse files
authored
Add keccak256, Secp256k1{Sign, Verify, PubKey} builtins (#3417)
1 parent 6aa2291 commit 991fb0c

File tree

23 files changed

+426
-73
lines changed

23 files changed

+426
-73
lines changed

src/Juvix/Compiler/Builtins/Anoma.hs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,55 @@ checkAnomaByteArrayFromAnomaContents f = do
109109
(ftype === (nat_ --> nat_ --> byteArray))
110110
$ builtinsErrorText l "fromAnomaContents must be of type Nat -> Nat -> ByteArray"
111111

112+
checkSecp256k1SignCompact ::
113+
(Members '[Reader BuiltinsTable, Error ScoperError, NameIdGen] r) =>
114+
AxiomDef ->
115+
Sem r ()
116+
checkSecp256k1SignCompact f = do
117+
let ftype = f ^. axiomType
118+
l = getLoc f
119+
nat_ <- getBuiltinNameScoper l BuiltinNat
120+
unless
121+
(ftype `hasArguments` [nat_, nat_])
122+
$ builtinsErrorText l (prettyText BuiltinAnomaSecp256k1SignCompact <> " must be of type Nat -> Nat -> _")
123+
124+
checkSecp256k1PubKey ::
125+
(Members '[Reader BuiltinsTable, Error ScoperError, NameIdGen] r) =>
126+
AxiomDef ->
127+
Sem r ()
128+
checkSecp256k1PubKey f = do
129+
let ftype = f ^. axiomType
130+
l = getLoc f
131+
nat_ <- getBuiltinNameScoper l BuiltinNat
132+
unless
133+
(ftype === (nat_ --> nat_))
134+
$ builtinsErrorText l (prettyText BuiltinAnomaSecp256k1PubKey <> " must be of type Nat -> Nat")
135+
136+
checkSecp256k1Verify ::
137+
(Members '[Reader BuiltinsTable, Error ScoperError, NameIdGen] r) =>
138+
AxiomDef ->
139+
Sem r ()
140+
checkSecp256k1Verify f = do
141+
let ftype = f ^. axiomType
142+
l = getLoc f
143+
nat_ <- getBuiltinNameScoper l BuiltinNat
144+
bool_ <- getBuiltinNameScoper l BuiltinBool
145+
unless
146+
(ftype === (nat_ --> nat_ --> nat_ --> bool_))
147+
$ builtinsErrorText l (prettyText BuiltinAnomaSecp256k1Verify <> " must be of type (msg signature pubKey : Nat) -> Bool")
148+
149+
checkKeccak256 ::
150+
(Members '[Reader BuiltinsTable, Error ScoperError, NameIdGen] r) =>
151+
AxiomDef ->
152+
Sem r ()
153+
checkKeccak256 f = do
154+
let ftype = f ^. axiomType
155+
l = getLoc f
156+
nat_ <- getBuiltinNameScoper l BuiltinNat
157+
unless
158+
(ftype === (nat_ --> nat_))
159+
$ builtinsErrorText l (prettyText BuiltinAnomaKeccak256 <> " must be of type Nat -> Nat")
160+
112161
checkAnomaSha256 :: (Members '[Reader BuiltinsTable, Error ScoperError, NameIdGen] r) => AxiomDef -> Sem r ()
113162
checkAnomaSha256 f = do
114163
let ftype = f ^. axiomType

src/Juvix/Compiler/Concrete/Data/Builtins.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ data BuiltinAxiom
332332
| BuiltinByteArrayLength
333333
| BuiltinRangeCheck
334334
| BuiltinNockmaReify
335+
| BuiltinAnomaKeccak256
336+
| BuiltinAnomaSecp256k1SignCompact
337+
| BuiltinAnomaSecp256k1Verify
338+
| BuiltinAnomaSecp256k1PubKey
335339
deriving stock (Show, Eq, Ord, Enum, Bounded, Generic, Data)
336340

337341
instance HasNameKind BuiltinAxiom where
@@ -405,6 +409,11 @@ instance HasNameKind BuiltinAxiom where
405409
BuiltinAnomaSetFromList -> KNameFunction
406410
BuiltinRangeCheck -> KNameFunction
407411
BuiltinNockmaReify -> KNameFunction
412+
BuiltinAnomaKeccak256 -> KNameFunction
413+
BuiltinAnomaSecp256k1SignCompact -> KNameFunction
414+
BuiltinAnomaSecp256k1Verify -> KNameFunction
415+
BuiltinAnomaSecp256k1PubKey -> KNameFunction
416+
408417
getNameKindPretty :: BuiltinAxiom -> NameKind
409418
getNameKindPretty = getNameKind
410419

@@ -485,6 +494,10 @@ instance Pretty BuiltinAxiom where
485494
BuiltinByteArrayLength -> Str.byteArrayLength
486495
BuiltinRangeCheck -> Str.rangeCheck
487496
BuiltinNockmaReify -> Str.nockmaReify
497+
BuiltinAnomaKeccak256 -> Str.keccak256
498+
BuiltinAnomaSecp256k1SignCompact -> Str.secp256k1SignCompact
499+
BuiltinAnomaSecp256k1Verify -> Str.secp256k1Verify
500+
BuiltinAnomaSecp256k1PubKey -> Str.secp256k1PubKey
488501

489502
data BuiltinType
490503
= BuiltinTypeInductive BuiltinInductive

src/Juvix/Compiler/Core/Evaluator.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ geval opts herr tab env0 = eval' env0
257257
OpUInt8FromInt -> uint8FromIntOp
258258
OpByteArrayFromListByte -> byteArrayFromListByteOp
259259
OpByteArrayLength -> byteArrayLengthOp
260+
OpAnomaKeccak256 -> normalizeOrUnsupported opcode
261+
OpAnomaSecp256k1SignCompact -> normalizeOrUnsupported opcode
262+
OpAnomaSecp256k1Verify -> normalizeOrUnsupported opcode
263+
OpAnomaSecp256k1PubKey -> normalizeOrUnsupported opcode
260264
where
261265
err :: Text -> a
262266
err msg = evalError msg n

src/Juvix/Compiler/Core/Extra/Base.hs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ mkConstr' = mkConstr Info.empty
5656
mkLambda :: Info -> Binder -> Node -> Node
5757
mkLambda i bi b = NLam (Lambda i bi b)
5858

59+
-- TODO use this in Core/Translation/FromInternal.hs
60+
5961
-- | If b is a builtin with arguments ty1 ty2
6062
-- it returns: `\lambda (x1 : ty1) (x2 : ty2) := b x1 x2`
61-
mkBuiltinExpanded' :: [Type] -> BuiltinOp -> Node
62-
mkBuiltinExpanded' argTys b =
63+
mkBuiltinExpanded' :: BuiltinOp -> [Type] -> Node
64+
mkBuiltinExpanded' b argTys =
6365
let numArgs = length argTys
64-
app = mkBuiltinApp' b [mkVar' argIx | argIx <- reverse [0 .. numArgs - 1]]
66+
prefixTypes = length (takeWhile isUniverse argTys)
67+
app = mkBuiltinApp' b [mkVar' argIx | argIx <- reverse [0 .. numArgs - 1 - prefixTypes]]
6568
in if
66-
| builtinOpArgsNum b == numArgs -> mkLambdas' argTys app
69+
| builtinOpArgsNum b == numArgs - prefixTypes -> mkLambdas' argTys app
6770
| otherwise ->
6871
impossibleError
6972
( "unexpected number of args to builtin "

src/Juvix/Compiler/Core/Extra/Utils.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ isDebugOp = \case
265265
OpIntSub -> False
266266
OpFieldToInt -> False
267267
OpShow -> False
268+
OpAnomaKeccak256 -> False
269+
OpAnomaSecp256k1SignCompact -> False
270+
OpAnomaSecp256k1Verify -> False
271+
OpAnomaSecp256k1PubKey -> False
268272
_ -> False
269273

270274
-- | Check if the node contains `trace`, `fail` or `seq` (`>->`).
@@ -557,6 +561,10 @@ builtinOpArgTypes = \case
557561
OpUInt8FromInt -> [mkTypeInteger']
558562
OpByteArrayFromListByte -> [mkDynamic']
559563
OpByteArrayLength -> [mkTypeByteArray']
564+
OpAnomaKeccak256 -> [mkTypeInteger']
565+
OpAnomaSecp256k1PubKey -> [mkTypeInteger']
566+
OpAnomaSecp256k1SignCompact -> [mkTypeInteger', mkTypeInteger']
567+
OpAnomaSecp256k1Verify -> [mkTypeInteger', mkTypeInteger', mkTypeInteger']
560568

561569
translateCase :: (Node -> Node -> Node -> a) -> a -> Case -> a
562570
translateCase translateIfFun dflt Case {..} = case _caseBranches of

src/Juvix/Compiler/Core/Language/Builtins.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ builtinCategory = \case
7777
OpUInt8FromInt -> BuiltinCategoryUInt8
7878
OpByteArrayFromListByte -> BuiltinCategoryByteArray
7979
OpByteArrayLength -> BuiltinCategoryByteArray
80+
OpAnomaKeccak256 -> BuiltinCategoryAnoma
81+
OpAnomaSecp256k1SignCompact -> BuiltinCategoryAnoma
82+
OpAnomaSecp256k1Verify -> BuiltinCategoryAnoma
83+
OpAnomaSecp256k1PubKey -> BuiltinCategoryAnoma
8084

8185
-- | Builtin operations which the evaluator and the code generator treat
8286
-- specially and non-uniformly.
@@ -133,6 +137,10 @@ data BuiltinOp
133137
| OpAnomaActionCreate
134138
| OpAnomaSetToList
135139
| OpAnomaSetFromList
140+
| OpAnomaKeccak256
141+
| OpAnomaSecp256k1SignCompact
142+
| OpAnomaSecp256k1Verify
143+
| OpAnomaSecp256k1PubKey
136144
| OpNockmaReify
137145
| OpPoseidonHash
138146
| OpEc
@@ -239,6 +247,10 @@ builtinOpArgsNum = \case
239247
OpAnomaProveDelta -> 1
240248
OpAnomaSetToList -> 1
241249
OpAnomaSetFromList -> 1
250+
OpAnomaKeccak256 -> 1
251+
OpAnomaSecp256k1PubKey -> 1
252+
OpAnomaSecp256k1SignCompact -> 2
253+
OpAnomaSecp256k1Verify -> 3
242254
OpPoseidonHash -> 1
243255
OpEc -> 3
244256
OpRandomEcPoint -> 0
@@ -325,6 +337,10 @@ builtinIsFoldable = \case
325337
OpUInt8FromInt -> True
326338
OpByteArrayFromListByte -> False
327339
OpByteArrayLength -> False
340+
OpAnomaKeccak256 -> False
341+
OpAnomaSecp256k1SignCompact -> False
342+
OpAnomaSecp256k1Verify -> False
343+
OpAnomaSecp256k1PubKey -> False
328344

329345
builtinsInCategory :: BuiltinCategory -> [BuiltinOp]
330346
builtinsInCategory c = filter ((== c) . builtinCategory) allElements

src/Juvix/Compiler/Core/Pretty/Base.hs

Lines changed: 65 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -32,67 +32,71 @@ class PrettyCode c where
3232
ppCode :: (Member (Reader Options) r) => c -> Sem r (Doc Ann)
3333

3434
instance PrettyCode BuiltinOp where
35-
ppCode = \case
36-
OpIntAdd -> return primPlus
37-
OpIntSub -> return primMinus
38-
OpIntMul -> return primMul
39-
OpIntDiv -> return primDiv
40-
OpIntMod -> return primMod
41-
OpIntLt -> return primLess
42-
OpIntLe -> return primLessEquals
43-
OpFieldAdd -> return primFieldAdd
44-
OpFieldSub -> return primFieldSub
45-
OpFieldMul -> return primFieldMul
46-
OpFieldDiv -> return primFieldDiv
47-
OpFieldFromInt -> return primFieldFromInt
48-
OpFieldToInt -> return primFieldToInt
49-
OpEq -> return primEquals
50-
OpShow -> return primShow
51-
OpStrConcat -> return primStrConcat
52-
OpStrToInt -> return primStrToInt
53-
OpAssert -> return primAssert
54-
OpRangeCheck -> return primRangeCheck
55-
OpSeq -> return primSeq
56-
OpTrace -> return primTrace
57-
OpFail -> return primFail
58-
OpAnomaGet -> return primAnomaGet
59-
OpAnomaEncode -> return primAnomaEncode
60-
OpAnomaDecode -> return primAnomaDecode
61-
OpAnomaVerifyDetached -> return primAnomaVerifyDetached
62-
OpAnomaSign -> return primAnomaSign
63-
OpAnomaSignDetached -> return primAnomaSignDetached
64-
OpAnomaVerifyWithMessage -> return primAnomaVerifyWithMessage
65-
OpAnomaByteArrayToAnomaContents -> return primAnomaByteArrayToAnomaContents
66-
OpAnomaByteArrayFromAnomaContents -> return primAnomaByteArrayFromAnomaContents
67-
OpAnomaSha256 -> return primAnomaSha256
68-
OpAnomaResourceCommitment -> return primResourceCommitment
69-
OpAnomaResourceNullifier -> return primResourceNullifier
70-
OpAnomaResourceKind -> return primResourceKind
71-
OpAnomaResourceDelta -> return primResourceDelta
72-
OpAnomaActionDelta -> return primActionDelta
73-
OpAnomaActionsDelta -> return primActionsDelta
74-
OpAnomaZeroDelta -> return primZeroDelta
75-
OpAnomaAddDelta -> return primAddDelta
76-
OpAnomaSubDelta -> return primSubDelta
77-
OpAnomaRandomGeneratorInit -> return primRandomGeneratorInit
78-
OpAnomaRandomNextBytes -> return primRandomNextBytes
79-
OpAnomaRandomSplit -> return primRandomSplit
80-
OpAnomaIsCommitment -> return primIsCommitment
81-
OpAnomaIsNullifier -> return primIsNullifier
82-
OpAnomaCreateFromComplianceInputs -> return primAnomaCreateFromComplianceInputs
83-
OpAnomaProveDelta -> return primAnomaProveDelta
84-
OpAnomaActionCreate -> return primActionCreate
85-
OpAnomaTransactionCompose -> return primTransactionCompose
86-
OpAnomaSetToList -> return primAnomaSetToList
87-
OpAnomaSetFromList -> return primAnomaSetFromList
88-
OpNockmaReify -> return primNockmaReify
89-
OpPoseidonHash -> return primPoseidonHash
90-
OpEc -> return primEc
91-
OpRandomEcPoint -> return primRandomEcPoint
92-
OpUInt8ToInt -> return primUInt8ToInt
93-
OpUInt8FromInt -> return primFieldFromInt
94-
OpByteArrayFromListByte -> return primByteArrayFromListByte
95-
OpByteArrayLength -> return primByteArrayLength
35+
ppCode p = return $ case p of
36+
OpIntAdd -> primPlus
37+
OpIntSub -> primMinus
38+
OpIntMul -> primMul
39+
OpIntDiv -> primDiv
40+
OpIntMod -> primMod
41+
OpIntLt -> primLess
42+
OpIntLe -> primLessEquals
43+
OpFieldAdd -> primFieldAdd
44+
OpFieldSub -> primFieldSub
45+
OpFieldMul -> primFieldMul
46+
OpFieldDiv -> primFieldDiv
47+
OpFieldFromInt -> primFieldFromInt
48+
OpFieldToInt -> primFieldToInt
49+
OpEq -> primEquals
50+
OpShow -> primShow
51+
OpStrConcat -> primStrConcat
52+
OpStrToInt -> primStrToInt
53+
OpAssert -> primAssert
54+
OpRangeCheck -> primRangeCheck
55+
OpSeq -> primSeq
56+
OpTrace -> primTrace
57+
OpFail -> primFail
58+
OpAnomaGet -> primAnomaGet
59+
OpAnomaEncode -> primAnomaEncode
60+
OpAnomaDecode -> primAnomaDecode
61+
OpAnomaVerifyDetached -> primAnomaVerifyDetached
62+
OpAnomaSign -> primAnomaSign
63+
OpAnomaSignDetached -> primAnomaSignDetached
64+
OpAnomaVerifyWithMessage -> primAnomaVerifyWithMessage
65+
OpAnomaByteArrayToAnomaContents -> primAnomaByteArrayToAnomaContents
66+
OpAnomaByteArrayFromAnomaContents -> primAnomaByteArrayFromAnomaContents
67+
OpAnomaSha256 -> primAnomaSha256
68+
OpAnomaResourceCommitment -> primResourceCommitment
69+
OpAnomaResourceNullifier -> primResourceNullifier
70+
OpAnomaResourceKind -> primResourceKind
71+
OpAnomaResourceDelta -> primResourceDelta
72+
OpAnomaActionDelta -> primActionDelta
73+
OpAnomaActionsDelta -> primActionsDelta
74+
OpAnomaZeroDelta -> primZeroDelta
75+
OpAnomaAddDelta -> primAddDelta
76+
OpAnomaSubDelta -> primSubDelta
77+
OpAnomaRandomGeneratorInit -> primRandomGeneratorInit
78+
OpAnomaRandomNextBytes -> primRandomNextBytes
79+
OpAnomaRandomSplit -> primRandomSplit
80+
OpAnomaIsCommitment -> primIsCommitment
81+
OpAnomaIsNullifier -> primIsNullifier
82+
OpAnomaCreateFromComplianceInputs -> primAnomaCreateFromComplianceInputs
83+
OpAnomaProveDelta -> primAnomaProveDelta
84+
OpAnomaActionCreate -> primActionCreate
85+
OpAnomaTransactionCompose -> primTransactionCompose
86+
OpAnomaSetToList -> primAnomaSetToList
87+
OpAnomaSetFromList -> primAnomaSetFromList
88+
OpNockmaReify -> primNockmaReify
89+
OpPoseidonHash -> primPoseidonHash
90+
OpEc -> primEc
91+
OpRandomEcPoint -> primRandomEcPoint
92+
OpUInt8ToInt -> primUInt8ToInt
93+
OpUInt8FromInt -> primFieldFromInt
94+
OpByteArrayFromListByte -> primByteArrayFromListByte
95+
OpByteArrayLength -> primByteArrayLength
96+
OpAnomaKeccak256 -> Str.keccak256
97+
OpAnomaSecp256k1SignCompact -> primitive Str.secp256k1SignCompact
98+
OpAnomaSecp256k1Verify -> primitive Str.secp256k1Verify
99+
OpAnomaSecp256k1PubKey -> primitive Str.secp256k1PubKey
96100

97101
instance PrettyCode BuiltinDataTag where
98102
ppCode = \case

src/Juvix/Compiler/Core/Transformation/ComputeTypeInfo.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ computeNodeTypeInfo md = umapL go
124124
OpUInt8FromInt -> mkTypeUInt8'
125125
OpByteArrayFromListByte -> mkDynamic'
126126
OpByteArrayLength -> mkTypeInteger'
127+
OpAnomaKeccak256 -> Info.getNodeType node
128+
OpAnomaSecp256k1SignCompact -> Info.getNodeType node
129+
OpAnomaSecp256k1Verify -> Info.getNodeType node
130+
OpAnomaSecp256k1PubKey -> Info.getNodeType node
127131
NCtr Constr {..} ->
128132
let ci = lookupConstructorInfo md _constrTag
129133
ii = lookupInductiveInfo md (ci ^. constructorInductive)

src/Juvix/Compiler/Core/Translation/FromInternal.hs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,10 @@ builtinInductive a =
729729
Internal.BuiltinByteArrayLength -> Nothing
730730
Internal.BuiltinRangeCheck -> Nothing
731731
Internal.BuiltinNockmaReify -> Nothing
732+
Internal.BuiltinAnomaKeccak256 -> Nothing
733+
Internal.BuiltinAnomaSecp256k1SignCompact -> Nothing
734+
Internal.BuiltinAnomaSecp256k1Verify -> Nothing
735+
Internal.BuiltinAnomaSecp256k1PubKey -> Nothing
732736
where
733737
registerInductiveAxiom :: forall r. (Members '[InfoTableBuilder, Reader InternalTyped.TypesTable, Reader InternalTyped.FunctionsTable, Reader InternalTyped.InfoTable, NameIdGen, Error BadScope] r) => Maybe BuiltinAxiom -> [(Tag, Text, Type -> Type, Maybe BuiltinConstructor)] -> Sem r ()
734738
registerInductiveAxiom ax ctrs = do
@@ -951,6 +955,21 @@ goAxiomDef a = maybe goAxiomNotBuiltin builtinBody (a ^. Internal.axiomBuiltin)
951955
natType
952956
(mkBuiltinApp' OpAnomaSha256 [mkVar' 0])
953957
)
958+
Internal.BuiltinAnomaSecp256k1PubKey -> do
959+
natType <- getNatType
960+
registerAxiomDef
961+
(mkBuiltinExpanded' OpAnomaSecp256k1PubKey [natType])
962+
Internal.BuiltinAnomaSecp256k1Verify -> do
963+
natType <- getNatType
964+
registerAxiomDef
965+
(mkBuiltinExpanded' OpAnomaSecp256k1Verify [natType, natType, natType])
966+
Internal.BuiltinAnomaSecp256k1SignCompact -> do
967+
natType <- getNatType
968+
registerAxiomDef
969+
(mkBuiltinExpanded' OpAnomaSecp256k1SignCompact [natType, natType])
970+
Internal.BuiltinAnomaKeccak256 -> do
971+
natType <- getNatType
972+
registerAxiomDef (mkBuiltinExpanded' OpAnomaKeccak256 [natType])
954973
Internal.BuiltinAnomaDelta -> return ()
955974
Internal.BuiltinAnomaKind -> return ()
956975
Internal.BuiltinAnomaResourceCommitment -> do
@@ -1585,6 +1604,10 @@ goApplication a = do
15851604
Internal.BuiltinByteArray -> app
15861605
Internal.BuiltinByteArrayFromListByte -> app
15871606
Internal.BuiltinByteArrayLength -> app
1607+
Internal.BuiltinAnomaKeccak256 -> app
1608+
Internal.BuiltinAnomaSecp256k1PubKey -> app
1609+
Internal.BuiltinAnomaSecp256k1SignCompact -> app
1610+
Internal.BuiltinAnomaSecp256k1Verify -> app
15881611
Internal.ExpressionIden (Internal.IdenFunction n) -> do
15891612
funInfoBuiltin <- Internal.getFunctionBuiltinInfo n
15901613
case funInfoBuiltin of

src/Juvix/Compiler/Core/Translation/Stripped/FromCore.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ fromCore' tab =
176176
BuiltinByteArrayFromListByte -> False
177177
BuiltinByteArrayLength -> False
178178
BuiltinRangeCheck -> False
179+
BuiltinAnomaKeccak256 -> False
180+
BuiltinAnomaSecp256k1PubKey -> False
181+
BuiltinAnomaSecp256k1Verify -> False
182+
BuiltinAnomaSecp256k1SignCompact -> False
179183
BuiltinTypeInductive i -> case i of
180184
BuiltinNat -> False
181185
BuiltinInt -> False

0 commit comments

Comments
 (0)