Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitwise operations #6090

Merged
merged 24 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
02ab54f
Initial bitwise primitives
kozross May 22, 2024
1a1ce70
Wire up new builtins
kozross May 22, 2024
0c32b48
Merge branch 'master' into koz/bitwise-2
kozross May 22, 2024
3556946
Tests
kozross May 23, 2024
249489a
Changelogs
kozross May 23, 2024
ad5cc7b
Fix failing goldens
kozross May 24, 2024
f51656e
Merge branch 'master' into koz/bitwise-2
kozross Jun 6, 2024
9520bc3
Fix cost model for tests
kozross Jun 6, 2024
aa5f83d
Bitwise primitives are not in Conway
kozross Jun 6, 2024
56e90ad
Merge branch 'master' into koz/bitwise-2
kozross Jun 9, 2024
a01acc0
Finish shift tests
kozross Jun 9, 2024
2fc1e8d
Fix goldens
kozross Jun 9, 2024
d23d03b
Rest of tests
kozross Jun 10, 2024
7d6ba9c
Merge branch 'master' into koz/bitwise-2
kozross Jun 10, 2024
30a7435
Merge branch 'master' into koz/bitwise-2
kozross Jun 11, 2024
50b9171
Rename operations
kozross Jun 11, 2024
2d73e9a
Note about split composition for shift property
kozross Jun 11, 2024
6ef45c0
Explain bitwise tests in comments, remove AND and OR tests for findin…
kozross Jun 11, 2024
c25541f
Goldens for bitwise primops
kozross Jun 11, 2024
6a6ee69
Chop down property test running times a bit
kozross Jun 11, 2024
cf668f4
Add test for finding first in zero byte string, rename some tests for…
kozross Jun 11, 2024
4f550df
Clarify implementation choices in the comments
kozross Jun 11, 2024
96d42bf
Tidy up helpers for property tests
kozross Jun 12, 2024
4a71fc5
Consolidate all bitwise ops, retarget links to CIPs
kozross Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions plutus-core/changelog.d/20240523_124004_koz.ross_bitwise_2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!--
A new scriv changelog fragment.

Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Removed

- A bullet item for the Removed category.

-->
### Added

- Implementation and tests for primitive operations in [this
CIP](https://github.com/mlabs-haskell/CIPs/blob/koz/bitwise/CIP-XXXX/CIP-XXXX.md)

### Changed

- Rename `ReplicateByteString` to `ReplicateByte` (and similarly for denotation)

<!--
### Deprecated

- A bullet item for the Deprecated category.

-->
<!--
### Fixed

- A bullet item for the Fixed category.

-->
<!--
### Security

- A bullet item for the Security category.

-->
5 changes: 3 additions & 2 deletions plutus-core/plutus-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ library
PlutusCore.Analysis.Definitions
PlutusCore.Annotation
PlutusCore.Arity
PlutusCore.Bitwise.Convert
PlutusCore.Bitwise.Logical
PlutusCore.Bitwise
PlutusCore.Builtin
PlutusCore.Builtin.Debug
PlutusCore.Builtin.Elaborate
Expand Down Expand Up @@ -417,6 +416,7 @@ test-suite untyped-plutus-core-test
DeBruijn.Spec
DeBruijn.UnDeBruijnify
Evaluation.Builtins
Evaluation.Builtins.Bitwise
Evaluation.Builtins.BLS12_381
Evaluation.Builtins.BLS12_381.TestClasses
Evaluation.Builtins.BLS12_381.Utils
Expand All @@ -430,6 +430,7 @@ test-suite untyped-plutus-core-test
Evaluation.Debug
Evaluation.FreeVars
Evaluation.Golden
Evaluation.Helpers
Evaluation.Machines
Evaluation.Regressions
Flat.Spec
Expand Down
1,168 changes: 1,168 additions & 0 deletions plutus-core/plutus-core/src/PlutusCore/Bitwise.hs

Large diffs are not rendered by default.

544 changes: 0 additions & 544 deletions plutus-core/plutus-core/src/PlutusCore/Bitwise/Convert.hs

This file was deleted.

464 changes: 0 additions & 464 deletions plutus-core/plutus-core/src/PlutusCore/Bitwise/Logical.hs

This file was deleted.

84 changes: 65 additions & 19 deletions plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
Expand All @@ -26,8 +25,7 @@ import PlutusCore.Evaluation.Machine.ExMemoryUsage (ExMemoryUsage, LiteralByteSi
import PlutusCore.Evaluation.Result (EvaluationResult (..))
import PlutusCore.Pretty (PrettyConfigPlc)

import PlutusCore.Bitwise.Convert as Convert
import PlutusCore.Bitwise.Logical as Logical
import PlutusCore.Bitwise qualified as Bitwise
import PlutusCore.Crypto.BLS12_381.G1 qualified as BLS12_381.G1
import PlutusCore.Crypto.BLS12_381.G2 qualified as BLS12_381.G2
import PlutusCore.Crypto.BLS12_381.Pairing qualified as BLS12_381.Pairing
Expand Down Expand Up @@ -160,7 +158,12 @@ data DefaultFun
| ComplementByteString
| ReadBit
| WriteBits
| ReplicateByteString
| ReplicateByte
-- Bitwise
| ShiftByteString
| RotateByteString
| CountSetBits
| FindFirstSetBit
deriving stock (Show, Eq, Ord, Enum, Bounded, Generic, Ix)
deriving anyclass (NFData, Hashable, PrettyBy PrettyConfigPlc)

Expand Down Expand Up @@ -1817,15 +1820,15 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
let integerToByteStringDenotation :: Bool -> LiteralByteSize -> Integer -> BuiltinResult BS.ByteString
{- The second argument is wrapped in a LiteralByteSize to allow us to interpret it as a size during
costing. It appears as an integer in UPLC: see Note [Integral types as Integer]. -}
integerToByteStringDenotation b (LiteralByteSize w) n = integerToByteStringWrapper b w n
integerToByteStringDenotation b (LiteralByteSize w) = Bitwise.integerToByteStringWrapper b w
{-# INLINE integerToByteStringDenotation #-}
in makeBuiltinMeaning
integerToByteStringDenotation
(runCostingFunThreeArguments . paramIntegerToByteString)

toBuiltinMeaning _semvar ByteStringToInteger =
let byteStringToIntegerDenotation :: Bool -> BS.ByteString -> Integer
byteStringToIntegerDenotation = byteStringToIntegerWrapper
byteStringToIntegerDenotation = Bitwise.byteStringToIntegerWrapper
{-# INLINE byteStringToIntegerDenotation #-}
in makeBuiltinMeaning
byteStringToIntegerDenotation
Expand All @@ -1834,60 +1837,94 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
-- Logical
toBuiltinMeaning _semvar AndByteString =
let andByteStringDenotation :: Bool -> BS.ByteString -> BS.ByteString -> BS.ByteString
andByteStringDenotation = Logical.andByteString
andByteStringDenotation = Bitwise.andByteString
{-# INLINE andByteStringDenotation #-}
in makeBuiltinMeaning
andByteStringDenotation
(runCostingFunThreeArguments . unimplementedCostingFun)

toBuiltinMeaning _semvar OrByteString =
let orByteStringDenotation :: Bool -> BS.ByteString -> BS.ByteString -> BS.ByteString
orByteStringDenotation = Logical.orByteString
orByteStringDenotation = Bitwise.orByteString
{-# INLINE orByteStringDenotation #-}
in makeBuiltinMeaning
orByteStringDenotation
(runCostingFunThreeArguments . unimplementedCostingFun)

toBuiltinMeaning _semvar XorByteString =
let xorByteStringDenotation :: Bool -> BS.ByteString -> BS.ByteString -> BS.ByteString
xorByteStringDenotation = Logical.xorByteString
xorByteStringDenotation = Bitwise.xorByteString
{-# INLINE xorByteStringDenotation #-}
in makeBuiltinMeaning
xorByteStringDenotation
(runCostingFunThreeArguments . unimplementedCostingFun)

toBuiltinMeaning _semvar ComplementByteString =
let complementByteStringDenotation :: BS.ByteString -> BS.ByteString
complementByteStringDenotation = Logical.complementByteString
complementByteStringDenotation = Bitwise.complementByteString
{-# INLINE complementByteStringDenotation #-}
in makeBuiltinMeaning
complementByteStringDenotation
(runCostingFunOneArgument . unimplementedCostingFun)

toBuiltinMeaning _semvar ReadBit =
let readBitDenotation :: BS.ByteString -> Int -> BuiltinResult Bool
readBitDenotation = Logical.readBit
readBitDenotation = Bitwise.readBit
{-# INLINE readBitDenotation #-}
in makeBuiltinMeaning
readBitDenotation
(runCostingFunTwoArguments . unimplementedCostingFun)

toBuiltinMeaning _semvar WriteBits =
let writeBitsDenotation :: BS.ByteString -> [(Integer, Bool)] -> BuiltinResult BS.ByteString
writeBitsDenotation = Logical.writeBits
writeBitsDenotation = Bitwise.writeBits
{-# INLINE writeBitsDenotation #-}
in makeBuiltinMeaning
writeBitsDenotation
(runCostingFunTwoArguments . unimplementedCostingFun)

toBuiltinMeaning _semvar ReplicateByteString =
let byteStringReplicateDenotation :: Int -> Word8 -> BuiltinResult BS.ByteString
byteStringReplicateDenotation = Logical.replicateByteString
{-# INLINE byteStringReplicateDenotation #-}
toBuiltinMeaning _semvar ReplicateByte =
let replicateByteDenotation :: Int -> Word8 -> BuiltinResult BS.ByteString
replicateByteDenotation = Bitwise.replicateByte
{-# INLINE replicateByteDenotation #-}
in makeBuiltinMeaning
byteStringReplicateDenotation
replicateByteDenotation
(runCostingFunTwoArguments . unimplementedCostingFun)

-- Bitwise

toBuiltinMeaning _semvar ShiftByteString =
let shiftByteStringDenotation :: BS.ByteString -> Int -> BS.ByteString
shiftByteStringDenotation = Bitwise.shiftByteString
{-# INLINE shiftByteStringDenotation #-}
in makeBuiltinMeaning
shiftByteStringDenotation
(runCostingFunTwoArguments . unimplementedCostingFun)

toBuiltinMeaning _semvar RotateByteString =
let rotateByteStringDenotation :: BS.ByteString -> Int -> BS.ByteString
rotateByteStringDenotation = Bitwise.rotateByteString
{-# INLINE rotateByteStringDenotation #-}
in makeBuiltinMeaning
rotateByteStringDenotation
(runCostingFunTwoArguments . unimplementedCostingFun)

toBuiltinMeaning _semvar CountSetBits =
let countSetBitsDenotation :: BS.ByteString -> Int
countSetBitsDenotation = Bitwise.countSetBits
{-# INLINE countSetBitsDenotation #-}
in makeBuiltinMeaning
countSetBitsDenotation
(runCostingFunOneArgument . unimplementedCostingFun)

toBuiltinMeaning _semvar FindFirstSetBit =
let findFirstSetBitDenotation :: BS.ByteString -> Int
findFirstSetBitDenotation = Bitwise.findFirstSetBit
{-# INLINE findFirstSetBitDenotation #-}
in makeBuiltinMeaning
findFirstSetBitDenotation
(runCostingFunOneArgument . unimplementedCostingFun)

-- See Note [Inlining meanings of builtins].
{-# INLINE toBuiltinMeaning #-}

Expand Down Expand Up @@ -2021,7 +2058,12 @@ instance Flat DefaultFun where
ComplementByteString -> 78
ReadBit -> 79
WriteBits -> 80
ReplicateByteString -> 81
ReplicateByte -> 81

ShiftByteString -> 82
RotateByteString -> 83
CountSetBits -> 84
FindFirstSetBit -> 85

decode = go =<< decodeBuiltin
where go 0 = pure AddInteger
Expand Down Expand Up @@ -2105,7 +2147,11 @@ instance Flat DefaultFun where
go 78 = pure ComplementByteString
go 79 = pure ReadBit
go 80 = pure WriteBits
go 81 = pure ReplicateByteString
go 81 = pure ReplicateByte
go 82 = pure ShiftByteString
go 83 = pure RotateByteString
go 84 = pure CountSetBits
go 85 = pure FindFirstSetBit
go t = fail $ "Failed to decode builtin tag, got: " ++ show t

size _ n = n + builtinTagWidth
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bool -> bytestring -> bytestring -> bytestring
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bytestring -> bytestring
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bytestring -> integer
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bytestring -> integer
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bool -> bytestring -> bytestring -> bytestring
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bytestring -> integer -> bool
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
integer -> integer -> bytestring
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bytestring -> integer -> bytestring
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bytestring -> integer -> bytestring
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bytestring -> list (pair integer bool) -> bytestring
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bool -> bytestring -> bytestring -> bytestring
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,15 @@ isCommutative = \case
IntegerToByteString -> False
ByteStringToInteger -> False
-- Currently, this requires commutativity in all arguments, which the
-- logical operations are not.
-- logical and bitwise operations are not.
AndByteString -> False
OrByteString -> False
XorByteString -> False
ComplementByteString -> False
ReadBit -> False
WriteBits -> False
ReplicateByteString -> False
ReplicateByte -> False
ShiftByteString -> False
RotateByteString -> False
CountSetBits -> False
FindFirstSetBit -> False
Loading