Skip to content

Commit 4b9b126

Browse files
authored
Merge pull request #2 from zkFold/1-off-chain-code-zkpass-integration
Off chain code for zkpass integration
2 parents 939a026 + 569b8fa commit 4b9b126

File tree

10 files changed

+719
-0
lines changed

10 files changed

+719
-0
lines changed

.github/workflows/main-pull.yml

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
name: CI Pull Request
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
on-main-pull-request:
12+
13+
strategy:
14+
matrix:
15+
os: [ubuntu-latest]
16+
cabal: [3.10.3.0]
17+
ghc: [9.6.6]
18+
19+
runs-on: ${{ matrix.os }}
20+
21+
steps:
22+
- name: Install system dependencies
23+
run: |
24+
sudo apt-get update -y
25+
sudo apt-get install automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ tmux git jq wget libncursesw6 libtool autoconf liblmdb-dev -y
26+
27+
- name: Install C dependencies
28+
run: |
29+
CARDANO_NODE_VERSION='10.1.3'
30+
IOHKNIX_VERSION=$(curl https://raw.githubusercontent.com/IntersectMBO/cardano-node/$CARDANO_NODE_VERSION/flake.lock | jq -r '.nodes.iohkNix.locked.rev')
31+
echo "iohk-nix version: $IOHKNIX_VERSION"
32+
33+
mkdir -p ~/src
34+
cd ~/src
35+
36+
SODIUM_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/$IOHKNIX_VERSION/flake.lock | jq -r '.nodes.sodium.original.rev')
37+
echo "Using sodium version: $SODIUM_VERSION"
38+
39+
: ${SODIUM_VERSION:='dbb48cc'}
40+
git clone https://github.com/intersectmbo/libsodium
41+
cd libsodium
42+
git checkout $SODIUM_VERSION
43+
./autogen.sh
44+
./configure
45+
make
46+
make check
47+
sudo make install
48+
49+
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
50+
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
51+
source ~/.bashrc
52+
53+
cd ~/src
54+
55+
SECP256K1_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/$IOHKNIX_VERSION/flake.lock | jq -r '.nodes.secp256k1.original.ref')
56+
echo "Using secp256k1 version: ${SECP256K1_VERSION}"
57+
58+
: ${SECP256K1_VERSION:='v0.3.2'}
59+
git clone --depth 1 --branch ${SECP256K1_VERSION} https://github.com/bitcoin-core/secp256k1
60+
cd secp256k1
61+
./autogen.sh
62+
./configure --enable-module-schnorrsig --enable-experimental
63+
make
64+
make check
65+
sudo make install
66+
sudo ldconfig
67+
68+
cd ~/src
69+
70+
BLST_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/master/flake.lock | jq -r '.nodes.blst.original.ref')
71+
echo "Using blst version: ${BLST_VERSION}"
72+
73+
: ${BLST_VERSION:='v0.3.11'}
74+
git clone --depth 1 --branch ${BLST_VERSION} https://github.com/supranational/blst
75+
cd blst
76+
./build.sh
77+
cat > libblst.pc << EOF
78+
prefix=/usr/local
79+
exec_prefix=\${prefix}
80+
libdir=\${exec_prefix}/lib
81+
includedir=\${prefix}/include
82+
83+
Name: libblst
84+
Description: Multilingual BLS12-381 signature library
85+
URL: https://github.com/supranational/blst
86+
Version: ${BLST_VERSION#v}
87+
Cflags: -I\${includedir}
88+
Libs: -L\${libdir} -lblst
89+
EOF
90+
sudo cp libblst.pc /usr/local/lib/pkgconfig/
91+
sudo cp bindings/blst_aux.h bindings/blst.h bindings/blst.hpp /usr/local/include/
92+
sudo cp libblst.a /usr/local/lib
93+
sudo chmod u=rw,go=r /usr/local/{lib/{libblst.a,pkgconfig/libblst.pc},include/{blst.{h,hpp},blst_aux.h}}
94+
95+
cd
96+
97+
- name: Checkout code
98+
uses: actions/[email protected]
99+
100+
- name: Set up Haskell
101+
uses: haskell-actions/[email protected]
102+
id: setup
103+
with:
104+
ghc-version: ${{ matrix.ghc }}
105+
cabal-version: ${{ matrix.cabal }}
106+
cabal-update: true
107+
108+
- name: Configure Cabal
109+
run: |
110+
cabal update
111+
# cabal configure --enable-tests --enable-benchmarks --enable-documentation
112+
113+
- name: Generate cache key
114+
# Creates plan.json file
115+
run: |
116+
cabal build all --dry-run
117+
118+
- name: Restore cached dependencies
119+
uses: actions/cache/[email protected]
120+
id: cache
121+
env:
122+
key: ${{ matrix.os }}-ghc-${{ matrix.ghc }}-cabal-${{ matrix.cabal }}
123+
with:
124+
path: ${{ steps.setup.outputs.cabal-store }}
125+
key: ${{ env.key }}-plan-${{ hashFiles('**/plan.json') }}
126+
restore-keys: ${{ env.key }}-
127+
128+
- name: Install stylish-haskell
129+
run: |
130+
cabal install stylish-haskell
131+
132+
- name: Lint Haskell
133+
run: |
134+
find . -name '*.hs' -exec sh -c 'for file do stylish-haskell --inplace "$file"; done' sh {} +
135+
136+
- name: Auto-commit lint
137+
uses: stefanzweifel/git-auto-commit-action@v4
138+
with:
139+
commit_message: stylish-haskell auto-commit
140+
commit_user_name: GitHub Action
141+
commit_user_email: [email protected]
142+
branch: ${{ github.head_ref }}
143+
144+
- name: Install dependencies
145+
# If we had an exact cache hit, the dependencies will be up to date.
146+
if: steps.cache.outputs.cache-hit != 'true'
147+
run: |
148+
cabal build all --only-dependencies
149+
150+
# Cache dependencies already here, so that we do not have to rebuild them should the subsequent steps fail.
151+
- name: Save cached dependencies
152+
uses: actions/cache/[email protected]
153+
# If we had an exact cache hit, trying to save the cache would error because of key clash.
154+
if: steps.cache.outputs.cache-hit != 'true'
155+
with:
156+
path: ${{ steps.setup.outputs.cabal-store }}
157+
key: ${{ steps.cache.outputs.cache-primary-key }}
158+
159+
- name: Build
160+
run: |
161+
cabal build all -f Pedantic

.github/workflows/main-push.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: CI Push
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
on-main-update:
14+
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Install system dependencies
19+
run: |
20+
sudo apt-get update -y
21+
sudo apt-get install automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ tmux git jq wget libncursesw6 libtool autoconf liblmdb-dev -y
22+
23+
- name: Install C dependencies
24+
run: |
25+
CARDANO_NODE_VERSION='10.1.3'
26+
IOHKNIX_VERSION=$(curl https://raw.githubusercontent.com/IntersectMBO/cardano-node/$CARDANO_NODE_VERSION/flake.lock | jq -r '.nodes.iohkNix.locked.rev')
27+
echo "iohk-nix version: $IOHKNIX_VERSION"
28+
29+
mkdir -p ~/src
30+
cd ~/src
31+
32+
SODIUM_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/$IOHKNIX_VERSION/flake.lock | jq -r '.nodes.sodium.original.rev')
33+
echo "Using sodium version: $SODIUM_VERSION"
34+
35+
: ${SODIUM_VERSION:='dbb48cc'}
36+
git clone https://github.com/intersectmbo/libsodium
37+
cd libsodium
38+
git checkout $SODIUM_VERSION
39+
./autogen.sh
40+
./configure
41+
make
42+
make check
43+
sudo make install
44+
45+
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
46+
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
47+
source ~/.bashrc
48+
49+
cd ~/src
50+
51+
SECP256K1_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/$IOHKNIX_VERSION/flake.lock | jq -r '.nodes.secp256k1.original.ref')
52+
echo "Using secp256k1 version: ${SECP256K1_VERSION}"
53+
54+
: ${SECP256K1_VERSION:='v0.3.2'}
55+
git clone --depth 1 --branch ${SECP256K1_VERSION} https://github.com/bitcoin-core/secp256k1
56+
cd secp256k1
57+
./autogen.sh
58+
./configure --enable-module-schnorrsig --enable-experimental
59+
make
60+
make check
61+
sudo make install
62+
sudo ldconfig
63+
64+
cd ~/src
65+
66+
BLST_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/master/flake.lock | jq -r '.nodes.blst.original.ref')
67+
echo "Using blst version: ${BLST_VERSION}"
68+
69+
: ${BLST_VERSION:='v0.3.11'}
70+
git clone --depth 1 --branch ${BLST_VERSION} https://github.com/supranational/blst
71+
cd blst
72+
./build.sh
73+
cat > libblst.pc << EOF
74+
prefix=/usr/local
75+
exec_prefix=\${prefix}
76+
libdir=\${exec_prefix}/lib
77+
includedir=\${prefix}/include
78+
79+
Name: libblst
80+
Description: Multilingual BLS12-381 signature library
81+
URL: https://github.com/supranational/blst
82+
Version: ${BLST_VERSION#v}
83+
Cflags: -I\${includedir}
84+
Libs: -L\${libdir} -lblst
85+
EOF
86+
sudo cp libblst.pc /usr/local/lib/pkgconfig/
87+
sudo cp bindings/blst_aux.h bindings/blst.h bindings/blst.hpp /usr/local/include/
88+
sudo cp libblst.a /usr/local/lib
89+
sudo chmod u=rw,go=r /usr/local/{lib/{libblst.a,pkgconfig/libblst.pc},include/{blst.{h,hpp},blst_aux.h}}
90+
91+
cd
92+
93+
- name: Checkout code
94+
uses: actions/[email protected]
95+
- name: Setup Haskell
96+
uses: haskell-actions/[email protected]
97+
with:
98+
ghc-version: '9.6.6'
99+
cabal-version: '3.10.3.0'
100+
101+
- name: Cache
102+
uses: actions/[email protected]
103+
env:
104+
cache-name: cache-cabal
105+
with:
106+
path: ~/.cabal
107+
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/cabal.project') }}
108+
restore-keys: |
109+
${{ runner.os }}-build-${{ env.cache-name }}-
110+
${{ runner.os }}-build-
111+
${{ runner.os }}-
112+
113+
- name: Build package
114+
shell: bash
115+
run: |
116+
cabal update
117+
cabal new-build all -f Pedantic
118+

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dist-*
2+
*~
3+
assets
4+
test-data

backends/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Off-chain code for `zkPassToken`
2+
3+
1. `zkPassToken-init-transaction` writes the related Plutus scripts (UPLC code) to files in CBOR format.
4+
2. `zkPassToken-minting-transaction` constructs the data items used as script parameters and writes them to files in CBOR format.
5+
3. `zkPassToken-transfer-transaction` writes token's policy id to a file in CBOR format.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module Main where
2+
3+
import Data.Aeson (encode)
4+
import qualified Data.ByteString as BS
5+
import qualified Data.ByteString.Lazy as BL
6+
import Prelude (Bool (..), IO,
7+
Show (..), putStr, ($),
8+
(++), (.))
9+
import System.Directory (createDirectoryIfMissing)
10+
import System.FilePath ((</>))
11+
import qualified System.IO as IO
12+
import System.Random (randomRIO)
13+
import Test.QuickCheck.Arbitrary (Arbitrary (..))
14+
import Test.QuickCheck.Gen (generate)
15+
16+
import ZkFold.Cardano.OffChain.Utils (currencySymbolOf,
17+
dataToCBOR, savePlutus)
18+
import ZkPass.Cardano.Example.IdentityCircuit (IdentityCircuitContract (..),
19+
identityCircuitVerificationBytes)
20+
import ZkPass.Cardano.UPLC.ZkPassToken (forwardingMintCompiled,
21+
zkPassTokenCompiled)
22+
23+
main :: IO ()
24+
main = do
25+
let path = "."
26+
27+
x <- generate arbitrary
28+
ps <- generate arbitrary
29+
30+
let contract = IdentityCircuitContract x ps
31+
32+
createDirectoryIfMissing True $ path </> "test-data"
33+
createDirectoryIfMissing True $ path </> "assets"
34+
35+
BL.writeFile (path </> "test-data" </> "plonkup-raw-contract-data.json") $ encode contract
36+
37+
putStr $ "x: " ++ show x ++ "\n" ++ "ps: " ++ show ps ++ "\n"
38+
39+
let (setup, _, _) = identityCircuitVerificationBytes x ps
40+
41+
fmTag <- randomRIO (1, 10000)
42+
43+
savePlutus (path </> "assets" </> "zkPassToken.plutus") $ zkPassTokenCompiled setup
44+
savePlutus (path </> "assets" </> "forwardingMint.plutus") $ forwardingMintCompiled fmTag
45+
46+
BS.writeFile (path </> "assets" </> "datumZkPassToken.cbor") . dataToCBOR . currencySymbolOf $ zkPassTokenCompiled setup
47+
48+
IO.writeFile (path </> "assets" </> "parkingTag.txt") $ show fmTag
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module Main where
2+
3+
import Cardano.Api (AssetName (..),
4+
UsingRawBytesHex (..))
5+
import Data.Aeson (decode)
6+
import Data.ByteString as BS (writeFile)
7+
import qualified Data.ByteString.Lazy as BL
8+
import Data.Maybe (fromJust)
9+
import Data.String (IsString (..))
10+
import PlutusLedgerApi.V3 (fromBuiltin)
11+
import Prelude (IO, Integer, putStr,
12+
return, show, ($),
13+
(++), (.), (<$>),
14+
(>>=))
15+
import System.FilePath ((</>))
16+
import System.Random (randomRIO)
17+
import ZkFold.Cardano.OffChain.Utils (dataToCBOR)
18+
import qualified ZkFold.Cardano.OnChain.BLS12_381.F as F
19+
import ZkFold.Cardano.OnChain.Plonkup.Data (InputBytes)
20+
import ZkFold.Cardano.OnChain.Utils (dataToBlake)
21+
import ZkPass.Cardano.Example.IdentityCircuit (IdentityCircuitContract (..),
22+
zkPassResultVerificationBytes)
23+
24+
25+
-- | Sample input from ZKPass result.
26+
zkPassResultInput :: IO InputBytes
27+
zkPassResultInput = randomRIO (1 :: Integer, 10000) >>= return . F.toInput . dataToBlake
28+
29+
main :: IO ()
30+
main = do
31+
let path = "."
32+
33+
zkpr <- zkPassResultInput
34+
35+
IdentityCircuitContract{..} <- fromJust . decode <$> BL.readFile (path </> "test-data" </> "plonkup-raw-contract-data.json")
36+
37+
putStr $ "x: " ++ show x ++ "\n" ++ "ps: " ++ show ps ++ "\n"
38+
39+
let (_, input, proof) = zkPassResultVerificationBytes x ps zkpr
40+
41+
BS.writeFile (path </> "assets" </> "tokenname") $ fromString $ show $ UsingRawBytesHex $ AssetName $ fromBuiltin $ F.fromInput input
42+
BS.writeFile (path </> "assets" </> "unit.cbor") $ dataToCBOR ()
43+
BS.writeFile (path </> "assets" </> "redeemerZkPassToken.cbor") $ dataToCBOR proof

0 commit comments

Comments
 (0)