-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ba66145
commit 14ba695
Showing
5 changed files
with
172 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@penumbra-zone/keys': major | ||
--- | ||
|
||
publish package containing keys |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# `@penumbra-zone/keys` | ||
|
||
This package contains cryptographic keys relevant to the Penumbra blockchain, | ||
and checksums to validate the integrity of those keys. | ||
|
||
The default export is a JSON mapping of Penumbra `Action` names to their | ||
relevant key, necessary for building cryptographic proofs for those actions. | ||
Keys are exported as `[key_name]_pk.bin`. | ||
|
||
A basic shell script `penumbra-download-keys` is provided, if you have specific | ||
versioning, bundling, or copying needs. Most users can use the keys exported | ||
from the package. | ||
|
||
## Using Keys | ||
|
||
If your bundler supports `import.meta.resolve`, you can handle the raw key material like this: | ||
|
||
```ts | ||
const res: Result = await fetch(import.meta.resolve('@penumbra-zone/keys/convert_pk.bin')); | ||
const keyBuf: ArrayBuffer = await res.arrayBuffer(); | ||
const convertPk = new Uint8Array(keyBuf); | ||
``` | ||
|
||
## A More Complex Example | ||
|
||
If your bundler doesn't support `import.meta.resolve`, or you rely on customized | ||
bundling, you might want to just handle URLs. Our `@penumbra-zone/wasm` package | ||
expects you to input key URL strings when building `Action`s. | ||
|
||
Here's a simplified example of how we use the packages together in our reference | ||
wallet extension: | ||
|
||
```ts | ||
import actionKeys from '@penumbra-zone/keys'; | ||
|
||
import type { FullViewingKey } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb'; | ||
import type { | ||
Action, | ||
TransactionPlan, | ||
WitnessData, | ||
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/transaction/v1/transaction_pb'; | ||
|
||
// map filenames to bundled key asset URLs | ||
const keyUrls = actionKeys.map(keyFileName => new URL(`keys/${keyFileName}`, PRAX_ORIGIN)); | ||
|
||
async function buildAction( | ||
txPlan: TransactionPlan, | ||
witness: WitnessData, | ||
fvk: FullViewingKey, | ||
actionIndex: number, | ||
): Promise<Action> { | ||
// Dynamically load wasm module | ||
const builder = await import('@penumbra-zone/wasm/build'); | ||
|
||
// Identify action type | ||
const actionType: Action['value']['case'] = transactionPlan.actions[actionPlanIndex]!.action.case; | ||
|
||
// Identify key url, if present | ||
const keyUrl: string | undefined = keyUrls[actionType]?.href; | ||
|
||
// Build action | ||
return builder.buildActionParallel(txPlan, witness, fvk, actionIndex, keyUrl); | ||
} | ||
``` | ||
|
||
### Using the management script | ||
|
||
An executable `penumbra-download-keys` is included. It can checksum the keys | ||
included in this package, and download other versions referenced by git tag if | ||
you are working with a testnet or other custom chain with its own proving keys. | ||
|
||
In any workspace where this package is installed, you can use | ||
|
||
```sh | ||
[npm|pnpm|yarn] exec penumbra-download-keys [output-path] [git tag] [sha256 manifest] | ||
``` | ||
|
||
Which will acquire the default keys and display checksum validation, if a key | ||
manifest is already present. You can further specify a version and custom | ||
manifest file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,90 @@ | ||
#!/bin/sh | ||
set -e | ||
defaultKeysVersion="v0.71.0" | ||
|
||
defaultKeysVersion="v0.70.0" | ||
|
||
scriptDir=$(dirname "$(readlink -f -- "$0")") | ||
cacheDir="$scriptDir/keys" | ||
scriptName=$(basename "$0") | ||
shaCmd=$(which sha256sum || which shasum || true) | ||
|
||
[ -z $shaCmd ] && ( | ||
echo "No checksum tool found. $scriptName requires sha256sum or shasum in \$PATH." | ||
exit 69 # EX_UNAVAILABLE | ||
) | ||
|
||
# usage <message> | ||
usage() { | ||
echo "${1}" | ||
echo "Usage: $(basename ${0}) <output-path> [<git tag> <sha256 manifest>]" | ||
echo "$1" | ||
echo "Usage: $scriptName [output-path] [git tag] [sha256 manifest]" | ||
exit 64 # EX_USAGE | ||
} | ||
|
||
if [ -z "${PENUMBRA_KEYS_DIR}" ]; then | ||
[ -z "${1}" ] && usage "No output path specified." | ||
PENUMBRA_KEYS_DIR=$1 | ||
fi | ||
# nearest_checksums <git tag> | ||
nearest_checksums() { | ||
( | ||
( | ||
# generate list | ||
echo "$1.zzzEND" # version.zzzEND will sort after version.shasum | ||
ls -1 "$scriptDir/shasums" # list known checksum manifests | ||
) | | ||
# select nearest | ||
sort --version-sort | # sort by version | ||
grep --before-context=1 --max-count=1 "zzzEND" | # locate sentinel and previous item | ||
grep -v "zzzEND" # remove sentinel, leaving previous/nothing | ||
) || ( | ||
# if all of that fails, use latest | ||
ls -1 "$scriptDir/shasums" | sort --version-sort | tail -n 1 | ||
) | ||
} | ||
|
||
if [ -z "${PENUMBRA_KEYS_VERSION}"]; then | ||
if [ -z "${2}" ]; then | ||
PENUMBRA_KEYS_VERSION=$defaultKeysVersion | ||
else | ||
[ -z "${3}" ] && usage "No sha256 provided." | ||
PENUMBRA_KEYS_VERSION=$2 | ||
PENUMBRA_KEYS_SHA256=$(readlink -f "${3}") | ||
fi | ||
fi | ||
# env var or arg or default | ||
outDir="$PENUMBRA_KEYS_OUT" # env var output path | ||
[ -z "$outDir" ] && outDir="$1" # arg output path | ||
[ -z "$outDir" ] && outDir="$scriptDir/keys" # default | ||
[ -d "$outDir" ] || mkdir -p "$outDir" # create output dir | ||
# resolve absolute | ||
outDir=$(readlink -f "$outDir" || usage "No output directory available") | ||
|
||
# env var or arg or default | ||
keysVersion=$PENUMBRA_KEYS_VERSION | ||
[ -z $keysVersion ] && keysVersion=$2 | ||
[ -z $keysVersion ] && keysVersion=$defaultKeysVersion | ||
|
||
if [ -z "${SKIP_DOWNLOAD_KEYS}" ]; then | ||
keysUrl="https://github.com/penumbra-zone/penumbra/raw/${PENUMBRA_KEYS_VERSION}/crates/crypto/proof-params/src/gen/" | ||
# env var or arg or default to nearest version | ||
shaFile="$PENUMBRA_KEYS_SHA256" | ||
[ -z "$shaFile"] && shaFile="$3" | ||
[ -z "$shaFile" ] && shaFile="$scriptDir/shasums/"$(nearest_checksums $keysVersion) | ||
# resolve absolute | ||
shaFile=$(readlink -f "$shaFile" || usage "No checksum manifest available") | ||
|
||
# check_keys <dir> | ||
check_keys() { | ||
pwd=$(pwd) # save current dir | ||
( | ||
# cd, check, cd back | ||
cd "$1" && $shaCmd -c "$shaFile" 2>/dev/null && cd "$pwd" | ||
) || ( | ||
# if that fails, cd back and fail | ||
cd "$pwd" && false | ||
) | ||
# return failure | ||
return $? | ||
} | ||
|
||
## main ## | ||
|
||
# if good keys exist, we're already done | ||
check_keys "$outDir" && exit 0 | ||
|
||
if [ -z $PENUMBRA_KEYS_SKIP ]; then | ||
keysUrl="https://github.com/penumbra-zone/penumbra/raw/$keysVersion/crates/crypto/proof-params/src/gen/" | ||
keysGlob="{convert,delegator_vote,nullifier_derivation,output,spend,swap,swapclaim}_pk.bin" | ||
curl --output-dir "${PENUMBRA_KEYS_DIR}/${PENUMBRA_KEYS_VERSION}" --continue-at - \ | ||
curl --output-dir "$outDir/$keysVersion" --continue-at - \ | ||
--parallel --create-dirs --location --remote-name \ | ||
"${keysUrl}${keysGlob}" | ||
"$keysUrl$keysGlob" | ||
fi | ||
|
||
ln -vf "${PENUMBRA_KEYS_DIR}/${PENUMBRA_KEYS_VERSION}/"*_pk.bin "${PENUMBRA_KEYS_DIR}" | ||
|
||
shacmd=$(which sha256sum || which shasum) | ||
[ -z $shacmd ] && usage "No sha256sum or shasum tool available." | ||
|
||
cd "${PENUMBRA_KEYS_DIR}" | ||
if [ -f "${PENUMBRA_KEYS_SHA256}" ]; then | ||
${shacmd} -c "${PENUMBRA_KEYS_SHA256}" | ||
elif [ "${PENUMBRA_KEYS_VERSION}" = "${defaultKeysVersion}" ]; then | ||
${shacmd} -c <<EOF | ||
882527eb795af2819f8df4f6233d5844757768fb03d51a000f11b100eeea573f convert_pk.bin | ||
6712a90216c7c0cfb12ef2a37d48ffae666f8d2bd9a722836864d0a70064dce7 delegator_vote_pk.bin | ||
ac9568335c1c158edddb2a70212c7b98d7c7aeff633b485a088049ecc01cc0ef nullifier_derivation_pk.bin | ||
a8c5ccc9d6c74150a21a8411e90d523e6ebb0f2a2985327d9fb4ef690600461e output_pk.bin | ||
69694b15abd96fdbeba5bbe1ba982d2240129be05813a9693acce31a1b43b0fd spend_pk.bin | ||
3d75cac8a227cd8c6680cd40f94a436b89f10d9b9bb1a118cf4479f1aa9b3fef swap_pk.bin | ||
8501f1dad9ac85d80c6421b17b838f8c6478431babfa836d3d33b5398fa6b6ad swapclaim_pk.bin | ||
EOF | ||
fi | ||
cp -v "$cacheDir/$keysVersion/"*_pk.bin "$outDir" | ||
|
||
check_keys "$outDir" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
882527eb795af2819f8df4f6233d5844757768fb03d51a000f11b100eeea573f convert_pk.bin | ||
6712a90216c7c0cfb12ef2a37d48ffae666f8d2bd9a722836864d0a70064dce7 delegator_vote_pk.bin | ||
ac9568335c1c158edddb2a70212c7b98d7c7aeff633b485a088049ecc01cc0ef nullifier_derivation_pk.bin | ||
a8c5ccc9d6c74150a21a8411e90d523e6ebb0f2a2985327d9fb4ef690600461e output_pk.bin | ||
69694b15abd96fdbeba5bbe1ba982d2240129be05813a9693acce31a1b43b0fd spend_pk.bin | ||
3d75cac8a227cd8c6680cd40f94a436b89f10d9b9bb1a118cf4479f1aa9b3fef swap_pk.bin | ||
8501f1dad9ac85d80c6421b17b838f8c6478431babfa836d3d33b5398fa6b6ad swapclaim_pk.bin |