├── .gitignore ├── Integration_guide.md ├── README.md ├── application └── Keystone_Application_Update_Package_Verification.md ├── audit-report └── cobo_audit_report_2020_09_en_1_0.pdf ├── hardware ├── .DS_Store ├── Keystone_V1.02_BOM.xls ├── Keystone_V1.02_schematic.pdf └── README.md ├── integration ├── aptos.md ├── arweave.md ├── btc_only_firmware.md ├── cosmos.md ├── ethereum.md └── index.md ├── part_f6a35290_5271C071.psbt ├── pics ├── cosmos_sign_request.gif ├── crypto_account_multi_qr.png ├── crypto_account_qr.png ├── multi_signed_psbt.gif ├── multi_unsigned_psbt.gif ├── read_keyring.png ├── sig_signed_psbt.gif ├── sig_unsigned_psbt.gif ├── sign_request.png └── wallet_file_multisig.png ├── research ├── arweave-qr-data-protocol.md ├── blinding-signing-on-solana.md ├── ethereum-qr-data-protocol.md ├── ledger-solana-tx.png ├── near-qr-data-protocol.md ├── solana-qr-data-protocol.md ├── sui-qr-data-protocol.md └── tron-qr-data-protocol.md ├── se ├── Keystone_SE_Firmware_Update_Package_Verification.md ├── Keystone_Secure_Element_Datasheet.md └── pics │ └── datasheet │ ├── Functional_block_diagram.jpg │ ├── QFN40.jpg │ └── QFN40_size.jpg ├── signed_41262fb9.psbt ├── system-arch-chart.png ├── unsigned_multisig_psbt.psbt └── unsigned_single_sig_psbt.psbt /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/.gitignore -------------------------------------------------------------------------------- /Integration_guide.md: -------------------------------------------------------------------------------- 1 | # Keystone Integration Guide 2 | Keystone is an air-gapped, QR Code based hardware wallet. Keystone is a pure signer for your crypto transactions, Keystone don't have external wireless connections like Bluetooth, WiFi, etc. The only way it can transmit data is via QR codes. 3 | This guide is for developers who would like to integrate their services with Keystone. 4 | 5 | ### Animated QR Codes 6 | With Keystone, we use QR Codes to transmit data, since each qr code image can only contain limited size of data, in order to send big chunks of data, we use animated QR codes to transmit big chunks of data. We are using the bc-ur to encode the data, for bc-ur please refer to [bc-ur](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md). In the BTC-only firmware, we also use [ur-type]([https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-006-urtypes.md]) for different bitcoin related data usages. 7 | 8 | We are using these libraries: 9 | - JavaScript: 10 | - ur-type encoding https://github.com/KeystoneHQ/ur-registry 11 | - bc-ur encoding https://github.com/Apocentre/bc-ur#readme 12 | 13 | - Java 14 | - bc-ur and ur-type https://github.com/sparrowwallet/hummingbird 15 | 16 | #### libraries 17 | ##### web 18 | There are a lot of existing libraries which currently can be used to scan qr codes and here is some of it used by our friends :) 19 | - [qr-scanner](https://github.com/nimiq/qr-scanner) 20 | - [vue-qr-code](https://github.com/gruhn/vue-qrcode-reader/) 21 | 22 | ##### React Native 23 | - [react-native-camera](https://github.com/react-native-camera/react-native-camera) 24 | 25 | ##### Native App 26 | For IOS and Android App we can use their native libraries to scan QR Codes. 27 | 28 | ## BTC Only Firmware 29 | We also provide a [BTC-only Firmware](https://github.com/KeystoneHQ/Keystone-cold-app-btc) for those who only use Bitcoin. You can get the latest firmware from [here](https://keyst.one/firmware), For Bitcoin, we follow the BIP174, aka PSBT to encode transactions. For those who are not familiar with BIP174 and PSBT, those can find here are some good reference guides: 30 | 31 | - https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki 32 | - https://bitcointechweekly.com/front/bip-174-psbt-partially-signed-bitcoin-transactions/ 33 | - https://en.bitcoin.it/wiki/BIP_0174 34 | 35 | And we strictly follow the [slip-0132](https://github.com/satoshilabs/slips/blob/master/slip-0132.md) to encode the extended public key. 36 | Coin | Public Key | Address Encoding | BIP 32 Path | 37 | ------------------------------------------|-----------------------|---------------------------------|-------------| 38 | [Bitcoin](https://bitcoin.org/) | `0x0488b21e` - `xpub` |P2PKH or P2SH | m/44'/0' | 39 | Bitcoin | `0x049d7cb2` - `ypub` |P2WPKH in P2SH | m/49'/0' | 40 | Bitcoin | `0x04b24746` - `zpub` |P2WPKH | m/84'/0' | 41 | Bitcoin | `0x0295b43f` - `Ypub` |Multi-signature P2WSH in P2SH | m/48'/0'/0'/1' | 42 | Bitcoin | `0x02aa7ed3` - `Zpub` |Multi-signature P2WSH | m/48'/0'/0'/2' | 43 | Bitcoin Testnet | `0x043587cf` - `tpub` |P2PKH or P2SH | m/44'/1' | 44 | Bitcoin Testnet | `0x044a5262` - `upub` |P2WPKH in P2SH | m/49'/1' | 45 | Bitcoin Testnet | `0x045f1cf6` - `vpub` |P2WPKH | m/84'/1' | 46 | Bitcoin Testnet | `0x024289ef` - `Upub` |Multi-signature P2WSH in P2SH | m/48'/1'/0'/1' | 47 | Bitcoin Testnet | `0x02575483` - `Vpub` |Multi-signature P2WSH | m/48'/1'/0'/2' | 48 | 49 | 50 | ### Single-Sig 51 | Currently we have integrated with a lot of well-known wallets, like Electrum, Blue Wallet, Wasabi Wallet, BTCPay, Specter, Sparrow etc. and also we provide generic wallet models to other wallets or services who would like to integrate with us. 52 | 53 | #### Setup the watch-only wallet 54 | 55 | Watch-only wallet import of the extended public key from Keystone, Keystone support both file and qrcode. 56 | - QR code: we are using [crypto-account](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md) to describe the extended public keys. However, currently we only put one xpub selected by user into crypto-account for some product reason. 57 | 58 | - File: we are using [bitcoin output descriptor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) to describe extended public key. 59 | 60 | **Raw Data**: 61 | ``` 62 | Extended Public Key: 63 | xpub6C23Z5ywx3Ts5TauvBCsf6e1EstwJ2bMbgGQAQp98oftj6j2HgiWt3jEVvTMndkuE8V58Tcaj9E11kVcwbGCxf5UZpyxBvWKEjuRVRPKnaT 64 | Path: M/44'/0'/0' 65 | Script Type: `p2pkh` 66 | ``` 67 | **UR**: 68 | ``` 69 | ur:crypto-account/oeadcyemrewytyaolytaadmutaaddloxaxhdclaxadatgawpashssbrdfsmubshgntsbnniaktfyvtqdrsmdfhpajntbvytnispagdplaahdcxbaspkkfmfmdrhyfdlprlcshylsvebdfyoxjpueiettdijysnrhgulnbyoypdkemuamtaaddyoyadlncsdwykaeykaeykaycyjnnthelrlswzrpss 70 | ``` 71 | 72 | **QR**: 73 | ![qrcode](./pics/crypto_account_qr.png) 74 | 75 | #### Sign PSBT 76 | We use psbt to encode the unsigned transaction and we provide two ways for that: 77 | 1. File:The unsigned PSBT file should be encoded as binary or base64 encoding and should use the .psbt file extension. reference [bip174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) here is the example unsigned psbt file [example](./unsigned_single_sig_psbt.psbt) 78 | 79 | 2. QRCode: We use [crypto-psbt](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-006-urtypes.md#partially-signed-bitcoin-transaction-psbt-crypto-psbt) to encode the psbt data. Here is a sample QRCode Image. 80 | 81 | ![image](./pics/sig_unsigned_psbt.gif) 82 | 83 | #### Export Signed PSBT 84 | 85 | After signing, users can export the signed psbt, we provide two ways for that: 86 | 87 | 1. Signed psbt file: see the example signed psbt file [example](./signed_41262fb9.psbt) 88 | 89 | 2. QRCode: here is the sample qr code of signed PSBT. 90 | 91 | ![signed-qrcode](./pics/sig_signed_psbt.gif) 92 | 93 | ## Multi-Sig 94 | We also support Multi-Sig for Bitcoin, currently we can use Keystone and ColdCard to set up Multi-Sig Wallet and perform multi-Sig, we have integrated with Electurm, Spector-Desktop, BlueWallet, Sparrow etc. 95 | 96 | 97 | 98 | #### Setup Multi-sig wallet 99 | 100 | Users can create a Multi-sig wallet by collecting all co-signers extended public key or import a multi-sig wallet file export from another Keystone co-signer. 101 | 102 | 1. Export the xpub of co-signer, it can be export via file or QR Code: 103 | 104 | **Raw Data**: 105 | ``` 106 | ExtendedPublicKey: Zpub6vZyhw1ShkEwNBUvpwXnR6u9tSdkeNY7LpS9xqZy2g3Yq3wwbNaDNeiB2nrj17sB2NsBYeqCiQFBEWf5x5WjshDepfXjFDmgCnoT3ayhm5u 107 | Path: M/48'/0'/0'/2' 108 | xfp: 37b5eed4 109 | script Type: P2WSH 110 | ``` 111 | **UR**: 112 | ``` 113 | ur:crypto-account/oeadcyemrewytyaolytaadmetaaddloxaxhdclaohnhffmvsbndslrfgclpfjejyatbdpebacnzokotofxntaoemvskpaowmryfnotfgaahdcxdlnbvecentssfsssgylnhkrstoytecrdlyadrekirfaybglahltalsrfcaeerobwamtaaddyoyadlocsdyykaeykaeykaoykaycyhkrpnddrckvoonsa 114 | ``` 115 | **QR**: 116 | ![qrcode](./pics/crypto_account_multi_qr.png) 117 | 118 | 119 | 2. Import Multi-sig wallet, Multi-sig wallet data format 120 | 121 | These data can be exported via fil or QR Code, here is a sample file: 122 | 123 | ``` 124 | # Keystone Multisig setup file (created on 5271C071) 125 | # 126 | Name: CC-2-of-3 127 | Policy: 2 of 3 128 | Derivation: m/48'/0'/0'/2' 129 | Format: P2WSH 130 | 131 | 748CC6AA: Zpub75fLJ4Y3UMxgoL2N6XLecqLj2Gt6JJ6U5t48PwB6bTEnWUgkhG3vavhnh8ZZwj3mA9acN7gU1NaqNXzvZyTKJrZLK7q7JqcamdoFhpgtizf 132 | C2202A77: Zpub75H51BQ73jcN2d8VcnScwnwKwrfRsA7UXL1LHmoxmXmGmFgCwxs4raek66GYG5sBdqnyS7whyR4c36Ky4x7Rfo7sVkfS7hvJNEUtX6LexH2 133 | 5271C071: Zpub755NbzNDFus6egJM22CLBqjabHyNV8PEWJHGBkfCSXN2W8HRPKEA2MyxvycgD4AxNMcrTuxSwKYiNJ19h9PLURGZoWyC2Tutr7SWaU1swYK 134 | ``` 135 | 136 | - Name: the multi-sig wallet name 137 | - Policy: multi-sig policy like 2 of 2 , 2 of 3 138 | - Derivation: the Derivation path of all the extend public key for multi-sig 139 | - Format: your script format, current we support P2WSH, P2WSH-P2SH, P2SH (P2SH-P2MS) 140 | 141 | the following items are master fingerprint and its extended public key 142 | - {master fingerprint:extended public key} 143 | 144 | The data format should be consistent with the file and all the fields should be filled. 145 | 146 | **QR**: 147 | 148 | We use bc-ur to encode this sample file and here is an sample data: 149 | 150 | ``` 151 | UR:BYTES/HKADWYCNCXGRIHKKJKJYJLJTIHCXGTKPJZJYINJKINIOCXJKIHJYKPJOCXIYINJZIHCXDEIAJPIHHSJYIHIECXJLJTCXECEYEMEHFXDYEMEHDTBKCNBKGLHSJNIHFTCXFXFXDPEYDPJLIYDPEOBKGDJLJZINIAKKFTCXEYCXJLIYCXEOBKFYIHJPINKOHSJYINJLJTFTCXJNDLEEETDIDLDYDIDLDYDIDLEYDIBKFGJLJPJNHSJYFTCXGDEYHGGUFDBKBKEMEEETFXFXENFPFPFTCXHTJOKPIDEMECIYGSGEEEHKEOGOGTKSIOJLGSEYGLENHDGSIHIAJSGSIMEYFLJYENGEGEENGOECJYEEETGDKTFWENIDGHFEJTHGGOIOJEISFLEOKOHSKOISJTISETHTHTKTIMEOJNFPESHSIAGLEMIOGOEHGLHSJSGLHDKNKOHTKKGHGRGEJPHTGSGREMJSEMGEJSIAHSJNIEJLFGISJOIOJYINKNIYBKFXEYEYDYEYFPEMEMFTCXHTJOKPIDEMECFDECEHFWGYEMEOIMIAGLEYIEETHFIAJTGUIAKTJTKTGRKTJPIYGMJKFPEMGOHDGSEHGSFDJNJLKSJNHDJNFLJNFGIOFXKTKSJKEEJPHSIHJEENENFLHKFLECJKFWIEJSJTKKGUEMKTISKKGMEEIAEOENGRKKEEKSEMGMIYJLEMJKHFJEIYGUEMISKOGEGLFEGOJYHDENGSIHKSFDEYBKECEYEMEHFXDYEMEHFTCXHTJOKPIDEMECECGLIDKNGLFYFGKPJKENIHIOGEGTEYEYFXGSFWJSIMHSIDFDKKGLHFETGDFEHGGEFDFLFWJEIYFXGUHDGLEYHGETFDGMGDGRFEFPEYGTKKKSKOKKIAIOFYEEFPKSGLGTIAJPGHKPKSGUKTGRHKINGLGEEHESISESGDGSGOGMFLHTJLHGKKFXEYGHKPJYJPEMGUHGHSGOEHJKKTHKGRBKHHIOCNOS 152 | ``` 153 | 154 | And here is the sample image: 155 | 156 | ![image](./pics/wallet_file_multisig.png) 157 | 158 | 159 | #### Sign PSBT 160 | 161 | For multi-sig, unsigned and signed PSBT are consistent with single-sig and we also provide two ways for it. 162 | 163 | Unsigned psbt file: 164 | 165 | See the example unsigned multisig psbt file [example](./unsigned_multisig_psbt.psbt) 166 | 167 | Unsigned psbt Qrcode(encoded in bc-ur): 168 | 169 | ![unsinged PSBT](./pics/multi_unsigned_psbt.gif) 170 | 171 | #### Export Signed PSBT 172 | 173 | Signed multisig psbt file: 174 | 175 | See the example partially signed multisig psbt file [example](./part_f6a35290_5271C071.psbt) 176 | 177 | Signed multisig psbt qrcode(encoded in bc-ur): 178 | 179 | ![signed psbt](./pics/multi_signed_psbt.gif) 180 | 181 | ### FAQ 182 | 183 | TBD -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Keystone Developer hub 2 | 3 | **The Keystone hardware wallet is simply relaunched from the Cobo Vault branding so both the code base and infrastructure are almost the same. For more info please checkout [here](https://blog.keyst.one/leaving-cobo-to-continue-the-cobo-vault-legacy-29bb2f8f026e)** 4 | 5 | 6 | Keystone is an air-gapped, open source hardware wallet that uses completely transparent QR code data transmissions. Visit the Keystone official [website](https://keyst.one) to learn more. 7 | 8 | ## High Level Architecture 9 | Keystone is built on a specialized security hardware platform with a Secure Element that currently runs on a highly secure and enhanced Android Go platform. 10 | 11 | ![Keystone Hight Level Architecture](./system-arch-chart.png) 12 | 13 | The user's senstive data like private keys, master seed, entropy are stored on the secure element.The Secure Element communicates with the hardware wallet application layer through a serial communication protocol. Users need to set a password before using Keystone, which can be used to unlock the device, sign transactions, or do other sensitive operations. 14 | 15 | We use QR code data transmissions to air-gap. For details on the data protocol we use, please check [here](https://github.com/KeystoneHQ/crypto-coin-message-protocol) 16 | 17 | current we are using the bc-ur for encoding data. for more info about the bc-ur, please check out the [Blockchain Common Docs](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md) 18 | 19 | 20 | ``` 21 | UR:BYTES/HDTYCTLUAYAEAEAEAEAEAEAEVLHNBBVOYLGLPMDWDMSOTKGRGODEDWGETOGWGAMDNYSRSPSEDESSHSIMIEJTVSJZHNJTDETLSBSPTLSKSPSKWPBBVODWRTDETLRTSPSKWEPYJLIDPTPLJLAEFWFWYTBZAHONGAIYDMSWNLDSIYMEDSSWSEJTINHKPLGLMECFPTGLUESWGADAMERNFPRHMTTOINGACMCLDADSRNOLGLIHLNIYDAMNFEKBGLVWOLMNCLKBMDHYVYHKDTSORNMDFMBZYTTODTCKVYCLIHRHSWLDTAVAHKFGGLVYLDSOLPOLFMVWDSVACMLDMEOYPTMNFPYTMERHDSDTIHLDLYWLHYGLMNWYSKGABGLKCYBWZCLKLRVTGLKODPDMGLSNDNSOGSSFADAEJYLDJLCXSOAEAEAEASYTSKAS 22 | ``` 23 | 24 | we are working an demo of the animated QRCodes. once finished we will open it on our Github. 25 | 26 | ## Integration 27 | Please check this folder for intergation: [Integration](./integration/index.md) 28 | 29 | ## Hardware docs 30 | [hardware](./hardware): check the `hardware` folders for our hardware documents. Currently our schematic and BOM files are open source. 31 | 32 | ## Application docs 33 | [applications](./application): check the `application` folders to see our applications documents. 34 | 35 | ## Secure Element docs 36 | [se](./se): check the `se` folders to see our secure element documents. 37 | 38 | ## Audit-report docs 39 | The Keystone hardware wallet is simply relaunched from the Cobo Vault branding so both the code base and infrastructure are the same. For more information, Please see the Audit Report by PeckShield from mid 2020. 40 | 41 | [audit-report](./audit-report): check the `audit-report` folders for audit report documents. 42 | 43 | ## Don't Trust, Verify! 44 | `Don't Trust Verify`. Check our documentation to learn about how you can verify our firmware. 45 | - [Verify Application](./application/Keystone_Application_Update_Package_Verification.md) 46 | - [Verify Secure Element](./se/Keystone_SE_Firmware_Update_Package_Verification.md) 47 | 48 | 49 | ## FAQ 50 | 1. How to decode the QRCode and verify the data in the QRCode ? 51 | 52 | For multi-coin firmware, we are using the proto-buffer to encode the transaction data or sync data. Really thanks @fnord123 build an great tool to others to decode the QRCodes. 53 | For details, please check out this repo: https://github.com/KeystoneHQ/KeystoneQRVerifier 54 | -------------------------------------------------------------------------------- /application/Keystone_Application_Update_Package_Verification.md: -------------------------------------------------------------------------------- 1 | 2 | # Keystone Application Upgrade Package Verification 3 | 4 | ## Introduction 5 | Keystone offers a method for verifying official release upgrade packages. You can compare a version package you compiled from Github source code with the official release update package to accomplish this. 6 | 7 | Refer to the below sections for instructions. 8 | 9 | ## Download official release update package 10 | - [Firmware upgrades on the official Keystone website](https://keyst.one/firmware) 11 | 12 | ## Verify Checksum 13 | 14 | Calculate the sha256 checksum of the package to ensure that it is consistent with the official website 15 | ``` 16 | shasum -a 256 V1.2.0.zip 17 | ``` 18 | 19 | ## Unzip official release update package 20 | 1. Unzip the file you just downloaded and get a file called update.zip 21 | 22 | 2. Use the public key defined in the code to unzip upgrade package update.zip 23 | 24 | [public key for multi-coin version](https://github.com/KeystoneHQ/keystone-cold-app/blob/master/app/build.gradle#L112) 25 | 26 | [public key for btc-only version](https://github.com/KeystoneHQ/keystone-cold-app-btc/blob/master/app/build.gradle#L112) 27 | 28 | An upgrade package consists of the following parts: 29 | - `app_[version_code]_[version_name]_[git_commit_id]_[apk_sha1_checksum].apk` : Keystone cold upgrade version package 30 | - `manifest.json` : Upgrade package digest information 31 | - `serial_*.bin` : Keystone Secure Element upgrade version package 32 | - `signed.rsa` : Signature for upgrade package 33 | 34 | 3. Verify the Signature 35 | 36 | `signed.rsa` is the digital signature of `manifest.json` by SHA1withRSA, you can verify the signature with public key mentioned above. Refer to the code [verify update.zip signature](https://github.com/KeystoneHQ/Keystone-cold-app/blob/8ddba8ba7f9937132dd73ff489e3297cc01ec7ae/app/src/main/java/com/keystone/cold/update/Checking.java#L114) 37 | 38 | 39 | ## Download source code 40 | - Download the code of the branch corresponding to the official upgrade package version from Github. For example, if the official upgrade package version is `V1.1.0`, the corresponding code branch is `V1.1.0-release`. 41 | Run the following command to download the code: 42 | 43 | `git clone -b [code branch] git@github.com:KeystoneHQ/keystone-cold-app.git --recursive` 44 | or 45 | `git clone -b [code branch] git@github.com:KeystoneHQ/keystone-cold-app-btc.git --recursive` 46 | 47 | Replace `[code branch]` with a specific branch name. 48 | 49 | - When the code is downloaded you can run `git log` to find the latest commit ID. 50 | This commit ID should be the same as the commit ID obtained in the previous step. 51 | 52 | ## Build APK 53 | 54 | `./gradlew assembleVault_v2Release` 55 | 56 | You can find the APK in: 57 | 58 | `./releases/[version_code]/app_***.apk` 59 | 60 | ## Verify APK 61 | We now have two APK files, one extracted from official upgrade package, another built from the open source code. 62 | 63 | Because the keystore used to sign the APK cannot be made public, a test keystore is used in the open source code. 64 | Therefore, the digest of the APK file cannot be directly compared. Instead, we can compare whether the information before signing is consistent. 65 | 66 | Change the suffix of the APK file to .zip, and then unzip the .zip file. 67 | You can find the `META-INF/CERT.SF` file. 68 | 69 | Then compare the two `META-INF/CERT.SF` files. If they are the same,you will have verified that the official upgrade package matches the open source code. 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /audit-report/cobo_audit_report_2020_09_en_1_0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/audit-report/cobo_audit_report_2020_09_en_1_0.pdf -------------------------------------------------------------------------------- /hardware/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/hardware/.DS_Store -------------------------------------------------------------------------------- /hardware/Keystone_V1.02_BOM.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/hardware/Keystone_V1.02_BOM.xls -------------------------------------------------------------------------------- /hardware/Keystone_V1.02_schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/hardware/Keystone_V1.02_schematic.pdf -------------------------------------------------------------------------------- /hardware/README.md: -------------------------------------------------------------------------------- 1 | # Keystone Hardware 2 | Our product design philosophy is to minimize trust dependencies. A crucial way of minimizing trust is to make our product as transparent as possible. 3 | 4 | As part of working towards this goal, we are open sourcing the hardware design of Keystone Essential and Pro. We encourage researchers to use it to rebuild our product for further verification. 5 | 6 | [View hardware schematic and BOM](.) 7 | 8 | ## Schematic 9 | [`Keystone_schematic.pdf`](Keystone_V1.02_schematic.pdf) 10 | 11 | Notes: 12 | The self-destruct mechanism has been removed from the schematic as we chose not to disclose all of its functionality. 13 | In order to minimize the attack surface, we do not share detailed information on the Secure Element. For researchers who are interested in our Secure Element design, you can request we share the development board, datasheet, and other materials under NDA (required by our Secure Element vendor). Contact us at eng@keyst.one 14 | 15 | 16 | ## BOM 17 | [`Keystone_BOM.xls`](Keystone_V1.02_BOM.xls) 18 | 19 | This list contains all the materials used in the production of Keystone Essential and Pro. 20 | 21 | ## Important Notices 22 | Keystone retains sole copyright of these files and all design elements of Keystone Essential and Pro. 23 | As part of making quality improvements, we will constantly update this schematic and it may not be current. 24 | The above information is for research and testing purposes only and includes no warranties. 25 | Keystone does not grant license of this information for commercial use. 26 | -------------------------------------------------------------------------------- /integration/aptos.md: -------------------------------------------------------------------------------- 1 | # Keystone Aptos Mode Integration Guide 2 | 3 | The goal of the Keystone hardware wallet is to provide users with a reliable and quality signer by protecting users' 4 | private keys so Keystone seeks to integrate with existing wallets and applications. 5 | 6 | We have drafted a QR Code data transmission, Here is the 7 | link [QRCODE](https://github.com/KeystoneHQ/Keystone-developer-hub/issues/8), hopefully later we can propose an AIP. 8 | 9 | ## Firmware Requirement 10 | 11 | You need Keystone Multi-coin Firmware support Aptos for the integration. Find it 12 | from [here](https://keyst.one/firmware?locale=en). 13 | 14 | ## Wallet Integration 15 | 16 | In order to work with Keystone, a wallet can follow the process: 17 | 18 | 1. Keystone provides the public key information to the wallet via QR code, to generate authentication key, which then 19 | can be used to search the Aptos addresses on chain. 20 | 2. The wallet generates the unsigned transactions, sends it to Keystone to sign via QR Code. 21 | 3. Keystone would then sign the data and provide a signature as well as the related public key, back to the wallet via 22 | QR Code. 23 | 4. The wallet receives the signature and public key, constructs the signed data (transaction), and performs the 24 | following activities like broadcasting the transaction, etc. 25 | 26 | ## Library 27 | 28 | [`@keystonehq/bc-ur-registry-aptos`](https://www.npmjs.com/package/@keystonehq/bc-ur-registry-aptos) 29 | 30 | [`@keystonehq/animated-qr`](https://www.npmjs.com/package/@keystonehq/animated-qr) 31 | 32 | [`@keystonehq/aptos-keyring`](https://www.npmjs.com/package/@keystonehq/aptos-keyring) 33 | 34 | ## Example 35 | 36 | With the help of `@keystone/aptos-keyring`, wallets can easily integrate with Keystone without caring too much about UR. 37 | `@keystone/aptos-keyring` encapsulates the details like encode/decode UR, construct UR from data etc. 38 | 39 | Wallets only need to pay some attention to the UI like display the qr code or render the camera to scan the QR 40 | code. 41 | 42 | `@keystone/aptos-keyring` uses `InteactionProvider` to handle the UI interaction, by default it uses `@keystone/sdk` as 43 | the interaction provider to interact with wallet, it's functional but less UI designed, you can define your own 44 | interaction provider by extending the `BaseKeyring`. With `DefaultKeyring` the integration is very simple: 45 | 46 | ### Connect Keystone 47 | 48 | ```ts 49 | import {DefaultKeyring} from '@keystonehq/aptos-keyring'; 50 | 51 | const connectWallet = aysnc()=>{ 52 | ... 53 | // Init a keyring instance 54 | const keyring = DefaultKeyring.getEmptyKeyring(); 55 | 56 | // This will call the video camera. 57 | // by scanning the QR code displayed in Keystone HardWare Wallet, The keyring will be initalized with public key, hdPath inforamtion. 58 | await keyring.readKeyring(); 59 | console.log(keyring.getPubKeys()[0].pubKey); // 8e53e7b10656816de70824e3016fc1a277e77825e12825dc4f239f418ab2e04e 60 | ... 61 | } 62 | 63 | ``` 64 | 65 | ![readKeyring waiting for scan QR code](../pics/read_keyring.png) 66 | 67 | ### Sign Transaction 68 | 69 | ```ts 70 | // In your Transfer component, call the `keyring.signTransaction`. 71 | // It will render the `aptos-sign-request` UR, 72 | // This promised will be resolved by scanning the `aptos-signature` UR generated from Keystone HardWare Wallet. 73 | const {signature, authPubKey} = await keyring.signTransaction(authPubKey, signData); 74 | console.log(signature.toString('hex')); // 47e7b510784406dfa14d9fd13c3834128b49c56ddfc28edb02c5047219779adeed12017e2f9f116e83762e86f805c7311ea88fb403ff21900e069142b1fb310e 75 | console.log(authPubKey.toString('hex')); // 8e53e7b10656816de70824e3016fc1a277e77825e12825dc4f239f418ab2e04e 76 | ``` 77 | 78 | ![transaction to be signed](../pics/sign_request.png) 79 | 80 | ## Customize the interaction provider 81 | 82 | If you want to define your own interaction provider, you'll need to implement the `InteractionProvider` interface. 83 | 84 | ```ts 85 | export interface InteractionProvider { 86 | readCryptoMultiAccounts: () => Promise; 87 | requestSignature: ( 88 | signRequest: AptosSignRequest, 89 | requestTitle?: string, 90 | requestDescription?: string 91 | ) => Promise; 92 | } 93 | ``` 94 | 95 | Here is an example 96 | of [MetaMask Interaction Provider](https://github.com/KeystoneHQ/keystone-airgaped-base/blob/master/packages/metamask-airgapped-keyring/src/MetaMaskInteractionProvider.ts) 97 | . 98 | 99 | By defining your own interaction provider, wallets can customize the `UI Components` by subscribing to the specific event 100 | emitted by the interaction provider. 101 | 102 | ### Define your own interaction provider 103 | 104 | ```ts 105 | export class WalletInteractionProvider extends EventEmitter implements InteractionProvider { 106 | static instance: WalletInteractionProvider; 107 | 108 | constructor() { 109 | super(); 110 | if (WalletInteractionProvider.instance) { 111 | return WalletInteractionProvider.instance; 112 | } 113 | WalletInteractionProvider.instance = this; 114 | } 115 | 116 | ... 117 | requestSignature = (signRequest: AptosSignRequest) => { 118 | return new Promise((resolve, reject) => { 119 | const ur = signRequest.toUR(); 120 | const requestIdBuffer = signRequest.getRequestId(); 121 | const requestId = uuid.stringify(requestIdBuffer); 122 | const signPayload = { 123 | requestId, 124 | payload: { 125 | type: ur.type, 126 | cbor: ur.cbor.toString("hex"), 127 | } 128 | }; 129 | this.emit('signRequest', requestPayload); 130 | this.once(`${requestId}-signed`, (cbor: string) => { 131 | const aptosSignature = AptosSignature.fromCBOR(Buffer.from(cbor, "hex")); 132 | resolve(aptosSignature); 133 | }); 134 | }); 135 | }; 136 | ... 137 | } 138 | ``` 139 | 140 | ### Keyring with customized interaction provider 141 | 142 | ```ts 143 | export class WalletKeyring extends BaseKeyring { 144 | getInteraction = (): WalletInteractionProvider => { 145 | return new WalletInteractionProvider(); 146 | }; 147 | } 148 | ``` 149 | 150 | ### UI Component 151 | 152 | ```tsx 153 | // '@keystonehq/animated-qr' makes the handle of multiple QR codes much easier. 154 | import {AnimatedQRCode} from '@keystonehq/animated-qr'; 155 | 156 | export default class ConfirmKeystoneTransaction extends Component { 157 | constructor(props) { 158 | super(props); 159 | this.state = { 160 | signRequest: null 161 | } 162 | this.props.wallet.keyring.getEventEmitter().on('signRequest', (signRequest) => { 163 | this.setState(() => ({ 164 | signRequest 165 | })); 166 | }); 167 | } 168 | return 169 | 170 | } 171 | 172 | ``` 173 | -------------------------------------------------------------------------------- /integration/arweave.md: -------------------------------------------------------------------------------- 1 | # Keystone Arweave Mode Integration Guide 2 | 3 | The goal of the Keystone hardware wallet is to provide users with a reliable and quality signer by protecting users' 4 | private keys so Keystone seeks to integrate with existing wallets and applications. 5 | 6 | We have drafted a QR Code data transmission, Here is the 7 | link [QRCODE](https://github.com/KeystoneHQ/Keystone-developer-hub/blob/main/research/arweave-qr-data-protocol.md). 8 | 9 | ## Firmware Requirement 10 | 11 | You need Keystone Multi-coin Firmware support Arweave for the integration. Find it 12 | from [here](https://keyst.one/firmware?locale=en). 13 | 14 | ## Wallet Integration 15 | 16 | In order to work with Keystone, a wallet can follow the process: 17 | 18 | 1. Keystone provides the public key information to the wallet via QR code, to generate Arweave address. 19 | 2. The wallet generates the unsigned transactions, sends it to Keystone to sign via QR Code. 20 | 3. Keystone would then sign the data and provide a signature back to the wallet via 21 | QR Code. 22 | 4. The wallet receives the signature, constructs the signed data (transaction), and performs the 23 | following activities like broadcasting the transaction, etc. 24 | 25 | ## Library 26 | 27 | [`@keystonehq/bc-ur-registry-arweave`](https://www.npmjs.com/package/@keystonehq/bc-ur-registry-arweave) 28 | 29 | [`@keystonehq/animated-qr`](https://www.npmjs.com/package/@keystonehq/animated-qr) 30 | 31 | [`@keystonehq/arweave-keyring`](https://www.npmjs.com/package/@keystonehq/arweave-keyring) 32 | 33 | ## Example 34 | 35 | With the help of `@keystone/arweave-keyring`, wallets can easily integrate with Keystone without caring too much about 36 | UR. 37 | `@keystone/arweave-keyring` encapsulates the details like encode/decode UR, construct UR from data etc. wallets only 38 | need care about the UX like `display the qr code` or `render the camera to scan the QR` 39 | code. 40 | 41 | `@keystone/arweave-keyring` uses `InteactionProvider` to handle the UI interaction, it uses `@keystone/sdk` 42 | as the interaction provider by default, the integration is very straightforward. 43 | 44 | ### Connect Keystone 45 | 46 | ```ts 47 | import {DefaultKeyring} from '@keystonehq/arweave-keyring'; 48 | 49 | const connectWallet = aysnc()=>{ 50 | ... 51 | // Init a keyring instance 52 | const keyring = DefaultKeyring.getEmptyKeyring(); 53 | 54 | // This will call the video camera. 55 | // by scanning the QR code displayed in Keystone HardWare Wallet, The keyring will be initalized with public key inforamtion. 56 | await keyring.readKeyring(); 57 | console.log(keyring.getKeyData().toString('hex')); //c41a50ed2155a5740b45df8e3815774d6b8d193e5ad80c9efaaf6d6d0253f350c85becf39eb7056d75841f6a064acf8381383eceb218e16859ef72be7273321a2b4855b87bc6f14c734e2a9c90850c34a8a0a4279ac9be3186b086db5b302fb68176b4c1fee337456c42f972c7993f618fdedc0bf1658c2d59cf2c0c6ac31a61ac1260e0fd4a761ca3707e27611c14b4c6b6abe698c11009ddf5d1511ae47ea271079b6892d229a27d0822e0c7aa12a4cf7f7c28fe23d201eae2adb7f403c9c5a1762c2d8cc96898ce41fe529ab0ef8184e50063e6fc62e0a808e8602254c142c9e7f7e94e6ef2c767ac0e99810d09a44bfde8db46298bc0e25b4a333b4ef86cd7ce658ff661ab0d1789b603b8770a6b433851a91c8ff07a7a8a0767702f6887098ea34bf4a8309eaab9baadd16d45cdd9b1899b6a303a2dce23745cec9fc2ecd9735a66c77fdea1bfd4cdb2be7bfb407a4fd5d3405c3cb33b5316e16559f0c4bf0bc7d1a3ada78917217b289c4d75eb60e0396f03035fd8d553727c790189cfd8dabcee8a4ae6607925b9a27ff7ad7ede26b98f8acd2532cf3175693f3eede9989a0aeedbdb3ff14fec823017531aead4cd22733ab30dbce76cebcdac64424128d6eeff3cdc1825d7cdb7113e74db126e6d931544467c6979aa8d50ac803f36084ed7077f34acfcf3f77bb13d5ebb723fc5d3f45212d2dd6ef20ea757fb4c95 58 | ... 59 | } 60 | 61 | ``` 62 | 63 | ![readKeyring waiting for scan QR code](../pics/read_keyring.png) 64 | 65 | ### Sign Transaction 66 | 67 | ```ts 68 | // In your Transfer component, call the `keyring.signTransaction`. 69 | // It will render the `arweave-sign-request` UR, 70 | // This promised will be resolved by scanning the `arweave-signature` UR generated from Keystone HardWare Wallet. 71 | const signature = await keyring.signTransaction(signData,32); 72 | console.log(signature.toString('hex')); // a8e58c9aa9a74039f239f49adca18ea5d54b9d28852b7d39b098a96230ebe4b07bf1f66eea2ef3ee29ab912f90508917703ca9838f228b0f75014ea5d41101f7dff194d8086010aa92b6e6d04a56ed6cb7bd63c3dc15f833c0fcbeb03a16892ed715f7b178c20dbb6cd9923ddd0ab4b1c8753a554a8165ff34224fb630445582d3b588581deca41dbcf2144dcf10a362510178af9923e9f6cdf30dfaafa5642a20f777a4a9bff7170517d9a4347a2f0e360a38bf90a8b5d10f80f2581422798aa7b77d959f237a77d71b35558349e35f9c1193154bcf252d79171abeec6f37858584f878503af44a3553eb218b86dc31dfcca66dea947364580515bb2543d2403d53866ee16bba1b8e51ba060a5ecfef3ef4617d96fa3a3f67176621e638ad7e33bf08c56409f0ce01ef345ac4b49ba4fd94dbaf11b544f4ce089d9adcebf5b592afd2f8cecf22f21539975e50441fe3bf5f77d7d0fcfa2bd3c6e2cbf1bb59ed141b5c0f257be5958c5b46c9f08ec1e912b7fa6ff7182aa9010ce9f0cd6fc4845760a37f97197ea8ad3fa8a75b742e9ad61f877acd5771e7c43e0c75a422eb7d96153d4c561469c0f6011d0fe74f718b2db26894e3c5daf72784d34374c4dab78c3ff7619f883085a45efe1781cfcdb80b64b4c8aa96f86225144ca9430a499e96c607a77538ad7fb920fdd1126cdc8c5574ed3c2b1fb1dadac51ad4e13fdd9d 73 | ``` 74 | 75 | ![transaction to be signed](../pics/sign_request.png) 76 | 77 | ## Customize the interaction provider 78 | 79 | you can define your own interaction provider to customize ux by implementing the `InteractionProvider` interface. 80 | 81 | ```ts 82 | export interface InteractionProvider { 83 | readArweaveCryptoAccount: () => Promise; 84 | requestSignature: (signRequest: ArweaveSignRequest) => Promise; 85 | } 86 | ``` 87 | 88 | Here is an example 89 | of [MetaMask Interaction Provider](https://github.com/KeystoneHQ/keystone-airgaped-base/blob/master/packages/metamask-airgapped-keyring/src/MetaMaskInteractionProvider.ts) 90 | . 91 | 92 | By defining your own interaction provider, wallets can customize the `UI Components` by subscribing to the specific 93 | event 94 | emitted by the interaction provider. 95 | 96 | ### Define your own interaction provider 97 | 98 | ```ts 99 | export class WalletInteractionProvider extends EventEmitter implements InteractionProvider { 100 | static instance: WalletInteractionProvider; 101 | 102 | constructor() { 103 | super(); 104 | if (WalletInteractionProvider.instance) { 105 | return WalletInteractionProvider.instance; 106 | } 107 | WalletInteractionProvider.instance = this; 108 | } 109 | 110 | ... 111 | requestSignature = (signRequest: ArweaveSignRequest) => { 112 | return new Promise((resolve, reject) => { 113 | const ur = signRequest.toUR(); 114 | const requestIdBuffer = signRequest.getRequestId(); 115 | const requestId = uuid.stringify(requestIdBuffer); 116 | const signPayload = { 117 | requestId, 118 | payload: { 119 | type: ur.type, 120 | cbor: ur.cbor.toString("hex"), 121 | } 122 | }; 123 | this.emit('signRequest', requestPayload); 124 | this.once(`${requestId}-signed`, (cbor: string) => { 125 | const signature = ArweaveSignature.fromCBOR(Buffer.from(cbor, "hex")); 126 | resolve(signature); 127 | }); 128 | }); 129 | }; 130 | ... 131 | } 132 | ``` 133 | 134 | ### Keyring with customized interaction provider 135 | 136 | ```ts 137 | export class WalletKeyring extends BaseKeyring { 138 | getInteraction = (): WalletInteractionProvider => { 139 | return new WalletInteractionProvider(); 140 | }; 141 | } 142 | ``` 143 | 144 | ### UI Component 145 | 146 | ```tsx 147 | // '@keystonehq/animated-qr' makes the handle of multiple QR codes much easier. 148 | import {AnimatedQRCode} from '@keystonehq/animated-qr'; 149 | 150 | export default class ConfirmKeystoneTransaction extends Component { 151 | constructor(props) { 152 | super(props); 153 | this.state = { 154 | signRequest: null 155 | } 156 | this.props.wallet.keyring.getEventEmitter().on('signRequest', (signRequest) => { 157 | this.setState(() => ({ 158 | signRequest 159 | })); 160 | }); 161 | } 162 | return 163 | 164 | } 165 | 166 | ``` 167 | -------------------------------------------------------------------------------- /integration/btc_only_firmware.md: -------------------------------------------------------------------------------- 1 | # Keystone BTC Only firmware Integration Guide 2 | Keystone is an air-gapped, QR Code based hardware wallet. Keystone is a pure signer for your crypto transactions, Keystone don't have external wireless connections like Bluetooth, WiFi, etc. The only way it can transmit data is via QR codes. 3 | This guide is for developers who would like to integrate their services with Keystone. 4 | 5 | ### Animated QR Codes 6 | With Keystone, we use QR Codes to transmit data, since each qr code image can only contain limited size of data, in order to send big chunks of data, we use animated QR codes to transmit big chunks of data. We are using the bc-ur to encode the data, for bc-ur please refer to [bc-ur](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md). In the BTC-only firmware, we also use [ur-type]([https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-006-urtypes.md]) for different bitcoin related data usages. 7 | 8 | We are using these libraries: 9 | - JavaScript: 10 | - ur-type encoding https://github.com/KeystoneHQ/ur-registry 11 | - bc-ur encoding https://github.com/Apocentre/bc-ur#readme 12 | 13 | - Java 14 | - bc-ur and ur-type https://github.com/sparrowwallet/hummingbird 15 | 16 | #### libraries 17 | ##### web 18 | There are a lot of existing libraries which currently can be used to scan qr codes and here is some of it used by our friends :) 19 | - [qr-scanner](https://github.com/nimiq/qr-scanner) 20 | - [vue-qr-code](https://github.com/gruhn/vue-qrcode-reader/) 21 | 22 | ##### React Native 23 | - [react-native-camera](https://github.com/react-native-camera/react-native-camera) 24 | 25 | ##### Native App 26 | For IOS and Android App we can use their native libraries to scan QR Codes. 27 | 28 | ## BTC Only Firmware 29 | We also provide a [BTC-only Firmware](https://github.com/KeystoneHQ/Keystone-cold-app-btc) for those who only use Bitcoin. You can get the latest firmware from [here](https://keyst.one/firmware), For Bitcoin, we follow the BIP174, aka PSBT to encode transactions. For those who are not familiar with BIP174 and PSBT, those can find here are some good reference guides: 30 | 31 | - https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki 32 | - https://bitcointechweekly.com/front/bip-174-psbt-partially-signed-bitcoin-transactions/ 33 | - https://en.bitcoin.it/wiki/BIP_0174 34 | 35 | And we strictly follow the [slip-0132](https://github.com/satoshilabs/slips/blob/master/slip-0132.md) to encode the extended public key. 36 | Coin | Public Key | Address Encoding | BIP 32 Path | 37 | ------------------------------------------|-----------------------|---------------------------------|-------------| 38 | [Bitcoin](https://bitcoin.org/) | `0x0488b21e` - `xpub` |P2PKH or P2SH | m/44'/0' | 39 | Bitcoin | `0x049d7cb2` - `ypub` |P2WPKH in P2SH | m/49'/0' | 40 | Bitcoin | `0x04b24746` - `zpub` |P2WPKH | m/84'/0' | 41 | Bitcoin | `0x0295b43f` - `Ypub` |Multi-signature P2WSH in P2SH | m/48'/0'/0'/1' | 42 | Bitcoin | `0x02aa7ed3` - `Zpub` |Multi-signature P2WSH | m/48'/0'/0'/2' | 43 | Bitcoin Testnet | `0x043587cf` - `tpub` |P2PKH or P2SH | m/44'/1' | 44 | Bitcoin Testnet | `0x044a5262` - `upub` |P2WPKH in P2SH | m/49'/1' | 45 | Bitcoin Testnet | `0x045f1cf6` - `vpub` |P2WPKH | m/84'/1' | 46 | Bitcoin Testnet | `0x024289ef` - `Upub` |Multi-signature P2WSH in P2SH | m/48'/1'/0'/1' | 47 | Bitcoin Testnet | `0x02575483` - `Vpub` |Multi-signature P2WSH | m/48'/1'/0'/2' | 48 | 49 | 50 | ### Single-Sig 51 | Currently we have integrated with a lot of well-known wallets, like Electrum, Blue Wallet, Wasabi Wallet, BTCPay, Specter, Sparrow etc. and also we provide generic wallet models to other wallets or services who would like to integrate with us. 52 | 53 | #### Setup the watch-only wallet 54 | 55 | Watch-only wallet import of the extended public key from Keystone, Keystone support both file and qrcode. 56 | - QR code: we are using [crypto-account](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md) to describe the extended public keys. However, currently we only put one xpub selected by user into crypto-account for some product reason. 57 | 58 | - File: we are using [bitcoin output descriptor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) to describe extended public key. 59 | 60 | **Raw Data**: 61 | ``` 62 | Extended Public Key: 63 | xpub6C23Z5ywx3Ts5TauvBCsf6e1EstwJ2bMbgGQAQp98oftj6j2HgiWt3jEVvTMndkuE8V58Tcaj9E11kVcwbGCxf5UZpyxBvWKEjuRVRPKnaT 64 | Path: M/44'/0'/0' 65 | Script Type: `p2pkh` 66 | ``` 67 | **UR**: 68 | ``` 69 | ur:crypto-account/oeadcyemrewytyaolytaadmutaaddloxaxhdclaxadatgawpashssbrdfsmubshgntsbnniaktfyvtqdrsmdfhpajntbvytnispagdplaahdcxbaspkkfmfmdrhyfdlprlcshylsvebdfyoxjpueiettdijysnrhgulnbyoypdkemuamtaaddyoyadlncsdwykaeykaeykaycyjnnthelrlswzrpss 70 | ``` 71 | 72 | **QR**: 73 | ![qrcode](../pics/crypto_account_qr.png) 74 | 75 | #### Sign PSBT 76 | We use psbt to encode the unsigned transaction and we provide two ways for that: 77 | 1. File:The unsigned PSBT file should be encoded as binary or base64 encoding and should use the .psbt file extension. reference [bip174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) here is the example unsigned psbt file [example](./unsigned_single_sig_psbt.psbt) 78 | 79 | 2. QRCode: We use [crypto-psbt](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-006-urtypes.md#partially-signed-bitcoin-transaction-psbt-crypto-psbt) to encode the psbt data. Here is a sample QRCode Image. 80 | 81 | ![image](../pics/sig_unsigned_psbt.gif) 82 | 83 | #### Export Signed PSBT 84 | 85 | After signing, users can export the signed psbt, we provide two ways for that: 86 | 87 | 1. Signed psbt file: see the example signed psbt file [example](../signed_41262fb9.psbt) 88 | 89 | 2. QRCode: here is the sample qr code of signed PSBT. 90 | 91 | ![signed-qrcode](../pics/sig_signed_psbt.gif) 92 | 93 | ## Multi-Sig 94 | We also support Multi-Sig for Bitcoin, currently we can use Keystone and ColdCard to set up Multi-Sig Wallet and perform multi-Sig, we have integrated with Electurm, Spector-Desktop, BlueWallet, Sparrow etc. 95 | 96 | 97 | 98 | #### Setup Multi-sig wallet 99 | 100 | Users can create a Multi-sig wallet by collecting all co-signers extended public key or import a multi-sig wallet file export from another Keystone co-signer. 101 | 102 | 1. Export the xpub of co-signer, it can be export via file or QR Code: 103 | 104 | **Raw Data**: 105 | ``` 106 | ExtendedPublicKey: Zpub6vZyhw1ShkEwNBUvpwXnR6u9tSdkeNY7LpS9xqZy2g3Yq3wwbNaDNeiB2nrj17sB2NsBYeqCiQFBEWf5x5WjshDepfXjFDmgCnoT3ayhm5u 107 | Path: M/48'/0'/0'/2' 108 | xfp: 37b5eed4 109 | script Type: P2WSH 110 | ``` 111 | **UR**: 112 | ``` 113 | ur:crypto-account/oeadcyemrewytyaolytaadmetaaddloxaxhdclaohnhffmvsbndslrfgclpfjejyatbdpebacnzokotofxntaoemvskpaowmryfnotfgaahdcxdlnbvecentssfsssgylnhkrstoytecrdlyadrekirfaybglahltalsrfcaeerobwamtaaddyoyadlocsdyykaeykaeykaoykaycyhkrpnddrckvoonsa 114 | ``` 115 | **QR**: 116 | ![qrcode](../pics/crypto_account_multi_qr.png) 117 | 118 | 119 | 2. Import Multi-sig wallet, Multi-sig wallet data format 120 | 121 | These data can be exported via fil or QR Code, here is a sample file: 122 | 123 | ``` 124 | # Keystone Multisig setup file (created on 5271C071) 125 | # 126 | Name: CC-2-of-3 127 | Policy: 2 of 3 128 | Derivation: m/48'/0'/0'/2' 129 | Format: P2WSH 130 | 131 | 748CC6AA: Zpub75fLJ4Y3UMxgoL2N6XLecqLj2Gt6JJ6U5t48PwB6bTEnWUgkhG3vavhnh8ZZwj3mA9acN7gU1NaqNXzvZyTKJrZLK7q7JqcamdoFhpgtizf 132 | C2202A77: Zpub75H51BQ73jcN2d8VcnScwnwKwrfRsA7UXL1LHmoxmXmGmFgCwxs4raek66GYG5sBdqnyS7whyR4c36Ky4x7Rfo7sVkfS7hvJNEUtX6LexH2 133 | 5271C071: Zpub755NbzNDFus6egJM22CLBqjabHyNV8PEWJHGBkfCSXN2W8HRPKEA2MyxvycgD4AxNMcrTuxSwKYiNJ19h9PLURGZoWyC2Tutr7SWaU1swYK 134 | ``` 135 | 136 | - Name: the multi-sig wallet name 137 | - Policy: multi-sig policy like 2 of 2 , 2 of 3 138 | - Derivation: the Derivation path of all the extend public key for multi-sig 139 | - Format: your script format, current we support P2WSH, P2WSH-P2SH, P2SH (P2SH-P2MS) 140 | 141 | the following items are master fingerprint and its extended public key 142 | - {master fingerprint:extended public key} 143 | 144 | The data format should be consistent with the file and all the fields should be filled. 145 | 146 | **QR**: 147 | 148 | We use bc-ur to encode this sample file and here is an sample data: 149 | 150 | ``` 151 | UR:BYTES/HKADWYCNCXGRIHKKJKJYJLJTIHCXGTKPJZJYINJKINIOCXJKIHJYKPJOCXIYINJZIHCXDEIAJPIHHSJYIHIECXJLJTCXECEYEMEHFXDYEMEHDTBKCNBKGLHSJNIHFTCXFXFXDPEYDPJLIYDPEOBKGDJLJZINIAKKFTCXEYCXJLIYCXEOBKFYIHJPINKOHSJYINJLJTFTCXJNDLEEETDIDLDYDIDLDYDIDLEYDIBKFGJLJPJNHSJYFTCXGDEYHGGUFDBKBKEMEEETFXFXENFPFPFTCXHTJOKPIDEMECIYGSGEEEHKEOGOGTKSIOJLGSEYGLENHDGSIHIAJSGSIMEYFLJYENGEGEENGOECJYEEETGDKTFWENIDGHFEJTHGGOIOJEISFLEOKOHSKOISJTISETHTHTKTIMEOJNFPESHSIAGLEMIOGOEHGLHSJSGLHDKNKOHTKKGHGRGEJPHTGSGREMJSEMGEJSIAHSJNIEJLFGISJOIOJYINKNIYBKFXEYEYDYEYFPEMEMFTCXHTJOKPIDEMECFDECEHFWGYEMEOIMIAGLEYIEETHFIAJTGUIAKTJTKTGRKTJPIYGMJKFPEMGOHDGSEHGSFDJNJLKSJNHDJNFLJNFGIOFXKTKSJKEEJPHSIHJEENENFLHKFLECJKFWIEJSJTKKGUEMKTISKKGMEEIAEOENGRKKEEKSEMGMIYJLEMJKHFJEIYGUEMISKOGEGLFEGOJYHDENGSIHKSFDEYBKECEYEMEHFXDYEMEHFTCXHTJOKPIDEMECECGLIDKNGLFYFGKPJKENIHIOGEGTEYEYFXGSFWJSIMHSIDFDKKGLHFETGDFEHGGEFDFLFWJEIYFXGUHDGLEYHGETFDGMGDGRFEFPEYGTKKKSKOKKIAIOFYEEFPKSGLGTIAJPGHKPKSGUKTGRHKINGLGEEHESISESGDGSGOGMFLHTJLHGKKFXEYGHKPJYJPEMGUHGHSGOEHJKKTHKGRBKHHIOCNOS 152 | ``` 153 | 154 | And here is the sample image: 155 | 156 | ![image](../pics/wallet_file_multisig.png) 157 | 158 | 159 | #### Sign PSBT 160 | 161 | For multi-sig, unsigned and signed PSBT are consistent with single-sig and we also provide two ways for it. 162 | 163 | Unsigned psbt file: 164 | 165 | See the example unsigned multisig psbt file [example](./unsigned_multisig_psbt.psbt) 166 | 167 | Unsigned psbt Qrcode(encoded in bc-ur): 168 | 169 | ![unsinged PSBT](../pics/multi_unsigned_psbt.gif) 170 | 171 | #### Export Signed PSBT 172 | 173 | Signed multisig psbt file: 174 | 175 | See the example partially signed multisig psbt file [example](./part_f6a35290_5271C071.psbt) 176 | 177 | Signed multisig psbt qrcode(encoded in bc-ur): 178 | 179 | ![signed psbt](../pics/multi_signed_psbt.gif) 180 | 181 | ### FAQ 182 | 183 | TBD -------------------------------------------------------------------------------- /integration/cosmos.md: -------------------------------------------------------------------------------- 1 | # Keystone Cosmos Mode Integration Guide 2 | 3 | The goal of the Keystone hardware wallet is to provide users with a reliable and quality signer by protecting users' 4 | private keys so Keystone seeks to integrate with existing wallets and applications. 5 | 6 | 7 | ## Firmware Requirement 8 | 9 | You need Keystone Multi-coin Firmware support Cosmos for the integration. Find it 10 | from [here](https://keyst.one/firmware?locale=en). 11 | 12 | ## Wallet Integration 13 | 14 | In order to work with Keystone, a wallet can follow the process: 15 | 16 | 1. Keystone provides the public key information to the wallet via QR code, to generate Cosmos addresses. 17 | 2. The wallet generates the unsigned transactions, sends it to Keystone to sign via QR Code. 18 | 3. Keystone would then sign the data and provide a signature as well as the related public key, back to the wallet via QR Code. 19 | 4. The wallet receives the signature and public key, constructs the signed data (transaction), and performs the following activities like broadcasting the transaction, etc. 20 | 21 | ## Library 22 | 23 | [`@keystonehq/bc-ur-registry-cosmos`](https://www.npmjs.com/package/@keystonehq/bc-ur-registry-cosmos) 24 | 25 | [`@keystonehq/animated-qr`](https://www.npmjs.com/package/@keystonehq/animated-qr) 26 | 27 | [`@keystonehq/cosmos-keyring`](https://www.npmjs.com/package/@keystonehq/cosmos-keyring) 28 | 29 | ## Example 30 | 31 | With the help of `@keystone/cosmos-keyring`, wallets can easily integrate with Keystone without caring too much about UR. 32 | `@keystone/cosmos-keyring` encapsulates the details like encode/decode UR, construct UR from data etc. 33 | 34 | Wallets only need to pay some attention to the UI like display the qr code or render the camera to scan the QR 35 | code. 36 | 37 | `@keystone/cosmos-keyring` uses `InteactionProvider` to handle the UI interaction, by default it uses `@keystone/sdk` as 38 | the interaction provider to interact with wallet, it's functional but less UI designed, you can define your own 39 | interaction provider by extending the `BaseKeyring`. With `DefaultKeyring` the integration is very simple: 40 | 41 | ### Connect Keystone 42 | 43 | ```ts 44 | import {DefaultKeyring} from '@keystonehq/cosmos-keyring'; 45 | 46 | const connectWallet = aysnc()=>{ 47 | ... 48 | // Init a keyring instance 49 | const keyring = DefaultKeyring.getEmptyKeyring(); 50 | 51 | // This will call the video camera. 52 | // by scanning the QR code displayed in Keystone HardWare Wallet, The keyring will be initalized with public key, hdPath inforamtion. 53 | await keyring.readKeyring(); 54 | console.log(keyring.getPubKeys()[0].pubKey); //02ddee545cc3774212ea76915bded1d502699c635002c21a770d373bb933374432 55 | ... 56 | } 57 | 58 | ``` 59 | ![readKeyring waiting for scan QR code](../pics/aptos_read_keyring.png) 60 | 61 | 62 | ### Sign Transaction 63 | 64 | ```ts 65 | // In your Transfer component, call the `keyring.signDirectTransaction` or 'keyring.signAminoTransaction', up to your sign mdoe. 66 | // It will render the `cosmos-sign-request` UR. 67 | // This promised will be resolved by scanning the `cosmos-signature` UR generated from Keystone HardWare Wallet. 68 | const {signature, pubKey} = await keyring.signDirectTransaction(pubKey, signData); 69 | console.log(signature.toString('hex')); // 47e7b510784406dfa14d9fd13c3834128b49c56ddfc28edb02c5047219779adeed12017e2f9f116e83762e86f805c7311ea88fb403ff21900e069142b1fb310e 70 | console.log(pubKey.toString('hex')); // 02ddee545cc3774212ea76915bded1d502699c635002c21a770d373bb933374432 71 | ``` 72 | ![transaction to be signed](../pics/cosmos_sign_request.gif) 73 | 74 | ## Customize the interaction provider 75 | 76 | If you want to define your own interaction provider, you'll need to implement the `InteractionProvider` interface. 77 | 78 | ```ts 79 | export interface InteractionProvider { 80 | readCryptoMultiAccounts: () => Promise; 81 | requestSignature: ( 82 | signRequest: CosmosSignRequest, 83 | requestTitle?: string, 84 | requestDescription?: string 85 | ) => Promise; 86 | } 87 | ``` 88 | 89 | Here is an example 90 | of [MetaMask Interaction Provider](https://github.com/KeystoneHQ/keystone-airgaped-base/blob/master/packages/metamask-airgapped-keyring/src/MetaMaskInteractionProvider.ts) 91 | . 92 | 93 | By defining your own interaction provider, wallets can customize the `UI Components` by subscribing to the specific event 94 | emitted by the interaction provider. 95 | 96 | ### Define your own interaction provider 97 | 98 | ```ts 99 | export class WalletInteractionProvider extends EventEmitter implements InteractionProvider { 100 | static instance: WalletInteractionProvider; 101 | 102 | constructor() { 103 | super(); 104 | if (WalletInteractionProvider.instance) { 105 | return WalletInteractionProvider.instance; 106 | } 107 | WalletInteractionProvider.instance = this; 108 | } 109 | 110 | ... 111 | requestSignature = (signRequest: CosmosSignRequest) => { 112 | return new Promise((resolve, reject) => { 113 | const ur = signRequest.toUR(); 114 | const requestIdBuffer = signRequest.getRequestId(); 115 | const requestId = uuid.stringify(requestIdBuffer); 116 | const signPayload = { 117 | requestId, 118 | payload: { 119 | type: ur.type, 120 | cbor: ur.cbor.toString("hex"), 121 | } 122 | }; 123 | this.emit('signRequest', requestPayload); 124 | this.once(`${requestId}-signed`, (cbor: string) => { 125 | const cosmosSignature = CosmosSignature.fromCBOR(Buffer.from(cbor, "hex")); 126 | resolve(cosmosSignature); 127 | }); 128 | }); 129 | }; 130 | ... 131 | } 132 | ``` 133 | 134 | ### Keyring with customized interaction provider 135 | 136 | ```ts 137 | export class WalletKeyring extends BaseKeyring { 138 | getInteraction = (): WalletInteractionProvider => { 139 | return new WalletInteractionProvider(); 140 | }; 141 | } 142 | ``` 143 | 144 | ### UI Component 145 | 146 | ```tsx 147 | // '@keystonehq/animated-qr' makes the handle of multiple QR codes much easier. 148 | import {AnimatedQRCode} from '@keystonehq/animated-qr'; 149 | 150 | export default function ConfirmKeystoneTransaction(props) { 151 | const [signRequest, setSignRequest] = useState(null); 152 | props.wallet.keyring.getInteraction().on('signRequest', (signRequest) => { 153 | setSignRequest(signRequest); 154 | }); 155 | 156 | return 157 | 158 | } 159 | 160 | ``` 161 | -------------------------------------------------------------------------------- /integration/ethereum.md: -------------------------------------------------------------------------------- 1 | # Keystone Web3 Mode (Ethereum) Integration Guide 2 | The goal of the Keystone hardware wallet is to provide users with a reliable and quality signer by protecting users' private keys so Keystone seeks to integrate with existing wallets and applications. Keystone has now provided the Web3 Mode which has worked with a lot of Ethereum wallets like Metamask and a lot of Dapps like Sushi Swap, Yearn, Gnosis Safe, and etc. 3 | 4 | We have now proposed an EIP for the QR Code data transmission. Here is the link for the [EIP](https://github.com/ethereum/EIPs/pull/4527) 5 | 6 | ## Firmware Requirement 7 | You need Keystone Multi-coin Firmware M-5.0 or above for the integration. Find it from [here](https://keyst.one/firmware?locale=en) 8 | 9 | ## Wallet Integration 10 | In order to work with Keystone, a wallet can follow the following process: 11 | 1. Keystone provides the public key information to the wallet to generate addresses, sync balances, etc via QR Codes. 12 | 2. The wallet generates the unsigned data that can include transactions, typed data, and etc, and then sends it to Keystone to sign via QR Code. 13 | 3. Keystone would then sign the data and provide a signature back to the wallet via QR Code. 14 | 4. The wallet receives the signature, constructs the signed data (transaction), and performs the following activities like broadcasting the transaction, etc. 15 | 16 | ### Setting up the wallet with Keystone 17 | In order to allow a wallet to collect information from the Ethereum blockchain, Keystone would need to provide the extended public key to the watch-only wallet in which the wallet will use to generate addresses and query the necessary information from the Ethereum blockchain. 18 | 19 | We use the `crypto-hdkey` to encode the extended public key and its derivation path. If you would like to know more about this, please check the `Specification` section of the [EIP](https://github.com/ethereum/EIPs/pull/4527) 20 | 21 | #### Library 22 | We have published the library to help developers to extract the extended public key from the QRCode. 23 | 24 | Please check the library here: 25 | 26 | ur-registry-eth: [source code](https://github.com/KeystoneHQ/keystone-airgaped-base/tree/master/packages/ur-registry-eth) 27 | 28 | npm package: [`@keystonehq/bc-ur-registry-eth`](https://www.npmjs.com/package/@keystonehq/bc-ur-registry-eth) 29 | 30 | #### Sample 31 | Install the package `@keystonehq/bc-ur-registry-eth` 32 | 33 | ```js 34 | yarn add @keystonehq/bc-ur-registry-eth 35 | ``` 36 | 37 | sample code: 38 | 39 | ```ts 40 | // this is the extended public key data from the QR Code 41 | const UR = "UR:CRYPTO-HDKEY/PTAOWKAXHDCLAXAMLSDSDSFSYLLTFLGAAYLDFTBNMWRDPAHLPTJSFDOSDPONAAEENYHKMOYLREJLGOAAHDCXSEJORFDRBNSKKBESEHPMLDMTCYPMRSBNDRKBIDKIFLSSWLTIESDRHKTSZTHGHHINAHTAADEHOEADCSFNAOAEAMTAADDYOTADLNCSDWYKCSFNYKAEYKAOCYZCTEHDWKAXAXATTAADDYOEADLRAEWKLAWKAXAEAYCYPFKPEOASASISGRIHKKJKJYJLJTIHBKJOHSIAIAJLKPJTJYDMJKJYHSJTIEHSJPIEKBJZJTYN" 42 | 43 | import { URRegistryDecoder } from '@keystonehq/bc-ur-registry-eth' 44 | 45 | const decoder = new URRegistryDecoder(); 46 | 47 | decoder.receivePart(UR); 48 | if(decoder.isSuccess()) { 49 | const cryptoHDkey = decoder.resultRegistryType(); 50 | const path = cryptoHDkey.getOrigin().getPath()); // 44'/60'/0' 51 | const extenedPubKey = cryptoHDKey.getBip32Key(); //xpub6CwzeNGArLq2XuEwGtycrise31bP3dZe1cim6urwWvyJ4D4EStJtp7ppZfHbi8pQTiEyapmGQS7NMrEarbDwPdjNMkGKSQEtpXytCWcQvH4 52 | return 53 | } else if(decoder.isError()){ 54 | // logic for error handling 55 | throw new Error() 56 | } 57 | ``` 58 | 59 | ### Sending the unsigned data from the wallet to Keystone 60 | For sending the unsigned data to Keystone, the data have to be encoded into the QR Codes. We will use the new UR Type `eth-sign-request` for this action. For more info about the `eth-sign-request`, please check the `Specification` section of the [EIP](https://github.com/ethereum/EIPs/pull/4527) 61 | 62 | When generating an eth-sign-request, we have currently defined four types of unsigned data: 63 | ```ts 64 | enum DataType { 65 | transaction = 1, // For the legacy transaction, the rlp encoding of the unsigned data. 66 | typedData = 2, // For the EIP-712 typed data. Bytes of the json string. 67 | personalMessage = 3, // For the personal message signing. 68 | typedTransaction = 4 // For the typed transaction, like the EIP-1559 transaction. 69 | } 70 | ``` 71 | 72 | for just one sign request, these fields should be filled. 73 | 74 | ```ts 75 | signData: Buffer, // the unsignd data bytes, for 76 | signDataType: DataType, // supported data type 77 | hdPath: string, // derivation path for the signing key 78 | xfp: string, // master fingerprint provided by Keystone when syncing with wallet 79 | uuidString?: string, // uuid for the request 80 | chainId?: number, // chain id for this signing, optional 81 | address?: string, // address for request this signing, optional 82 | origin?: string // source of the request, wallet name etc, optional 83 | ``` 84 | 85 | #### Library 86 | We have also provided the `eth-sign-request` in the `ur-registry-eth` library. 87 | 88 | #### Sample 89 | 90 | we will use the `@ethereumjs` to show how to generate the request 91 | 92 | ##### Legacy Transaction 93 | 94 | ```ts 95 | import { Transaction } from '@ethereumjs/tx'; 96 | import Common, { Hardfork } from '@ethereumjs/common'; 97 | import { BN } from 'ethereumjs-util'; 98 | import { 99 | CryptoHDKey, 100 | generateAddressfromXpub, 101 | findHDPathFromAddress, 102 | EthSignRequest, 103 | DataType, 104 | ETHSignature, 105 | } from '@keystonehq/bc-ur-registry-eth'; 106 | 107 | const _txParams = { 108 | to: "0x121212121212121212121212", 109 | gasLimit: 200000, 110 | gasPrice: 120000000000, 111 | data: "0x", 112 | nonce: 1, 113 | value: txParams.value, 114 | }; 115 | 116 | const tx = Transaction.fromTxData(_txParams, { common: this._common, freeze: false }); 117 | 118 | tx.v = new BN(tx.common.chainId()); 119 | 120 | tx.r = new BN(0); 121 | 122 | tx.s = new BN(0); 123 | 124 | const unsignedBuffer = tx.serialize(); // generate the unsigned transaction bytes 125 | const requestId = uuid.v4(); 126 | const addressPath = "M/44'/60'/0'/0/0" 127 | 128 | const ethSignRequest = EthSignRequest.constructETHRequest( 129 | unsignedBuffer, 130 | DataType.transaction, 131 | addressPath, 132 | "12345678", // master fingerprint 133 | requestId, 134 | 1, // chainId 135 | "0xfromaddress", 136 | ); 137 | 138 | const eachChunkNumberInEachQR = 400; // specify the each chunk Number in single QR Code 139 | 140 | // get the ur encoder 141 | const urEncoder = ethSignRequest.toUREncoder(eachChunkNumberInEachQR); 142 | 143 | // render each chunk of data in sign QR Code 144 | while (true) { 145 | renderQR(urEncoder.nextPart()); 146 | } 147 | ``` 148 | 149 | ##### Typed Transaction 150 | We will use the EIP-1559 transaction as an example. 151 | 152 | ``` ts 153 | import { Transaction } from '@ethereumjs/tx'; 154 | import Common, { Hardfork } from '@ethereumjs/common'; 155 | import { BN } from 'ethereumjs-util'; 156 | import { 157 | CryptoHDKey, 158 | generateAddressfromXpub, 159 | findHDPathFromAddress, 160 | EthSignRequest, 161 | DataType, 162 | ETHSignature, 163 | } from '@keystonehq/bc-ur-registry-eth'; 164 | 165 | const common = Common.forCustomChain('mainnet', { chainId: this._networkId }, Hardfork.London); 166 | const eip1559Tx = FeeMarketEIP1559Transaction.fromTxData(txParams, { common }); 167 | const unsignedBuffer = Buffer.from(eip1559Tx.getMessageToSign(false)); // generate the unsigned transaction bytes 168 | const requestId = uuid.v4(); 169 | const addressPath = "M/44'/60'/0'/0/0" 170 | 171 | const ethSignRequest = EthSignRequest.constructETHRequest( 172 | unsignedBuffer, 173 | DataType.typedTransaction, 174 | addressPath, 175 | "12345678", // master fingerprint 176 | requestId, 177 | 1, // chainId 178 | "0xfromaddress", 179 | ); 180 | 181 | const ChunkNumberInEachQR = 400; // specify the each chunk number in single QR Code 182 | 183 | // get the ur encoder 184 | const urEncoder = ethSignRequest.toUREncoder(eachChunkNumberInEachQR); 185 | 186 | // render each chunk of data in sign QR Code 187 | while (true) { 188 | renderQR(urEncoder.nextPart()); 189 | } 190 | ``` 191 | 192 | ##### EIP-712 TypedData 193 | ```ts 194 | import { 195 | CryptoHDKey, 196 | generateAddressfromXpub, 197 | findHDPathFromAddress, 198 | EthSignRequest, 199 | DataType, 200 | ETHSignature, 201 | } from '@keystonehq/bc-ur-registry-eth'; 202 | 203 | const typeData = "{}" // json string the typed data 204 | const dataHex = Buffer.from(typedData, 'utf-8'); 205 | const requestId = uuid.v4(); 206 | const addressPath = "M/44'/60'/0'/0/0" 207 | const ethSignRequest = EthSignRequest.constructETHRequest( 208 | dataHex, 209 | DataType.typedData, 210 | addressPath, 211 | "12345678", // master fingerprint 212 | requestId, 213 | undefined, 214 | "0xfromaddress", 215 | ); 216 | 217 | const ChunkNumberInEachQR = 400; // specify the each chunk number in single QR Code 218 | 219 | // get the ur encoder 220 | const urEncoder = ethSignRequest.toUREncoder(eachChunkNumberInEachQR); 221 | 222 | // render each chunk of data in sign QR Code 223 | while (true) { 224 | renderQR(urEncoder.nextPart()); 225 | } 226 | ``` 227 | 228 | ##### Message Signing Request 229 | ```ts 230 | import { 231 | EthSignRequest, 232 | DataType, 233 | ETHSignature, 234 | } from '@keystonehq/bc-ur-registry-eth'; 235 | 236 | 237 | const message = "68656c6c6f" // hex string of the message "hello" 238 | const dataHex = Buffer.from(message, 'hex'); 239 | const requestId = uuid.v4(); 240 | const addressPath = "M/44'/60'/0'/0/0" 241 | const ethSignRequest = EthSignRequest.constructETHRequest( 242 | dataHex, 243 | DataType.typedData, 244 | addressPath, 245 | "12345678", // master fingerprint 246 | requestId, 247 | undefined, 248 | "0xfromaddress", 249 | ); 250 | 251 | const ChunkNumberInEachQR = 400; // specify the each chunk number in single QR Code 252 | 253 | // get the ur encoder 254 | const urEncoder = ethSignRequest.toUREncoder(eachChunkNumberInEachQR); 255 | 256 | // render each chunk of data in sign QR Code 257 | while (true) { 258 | renderQR(urEncoder.nextPart()); 259 | } 260 | ``` 261 | 262 | ### Regarding the signature provided by Keystone to the wallet 263 | After Keystone signs the request, the Keystone device will provide a signature to the wallet. This is when the wallet is able to extract the signature to either construct the transaction or verify the signature. We have provided a new UR type `eth-signature` for the purpose above. For more info about the `eth-signature`, please check the `Specification` section of the [EIP](https://github.com/ethereum/EIPs/pull/4527) 264 | 265 | ##### Library 266 | We have also provided the `eth-signature` in the `ur-registry-eth` library. 267 | 268 | ##### Sample 269 | ```ts 270 | import { 271 | ETHSignature, 272 | } from '@keystonehq/bc-ur-registry-eth'; 273 | 274 | import {URDecoder} from '@ngraveio/bc-ur'; 275 | 276 | const decoder = new URDecoder(); 277 | 278 | // signature data from the QR Code 279 | const ur = 'ur:eth-signature/oeadtpdagdndcawmgtfrkigrpmndutdnbtkgfssbjnaohdfptywtosrftahprdctrkbegylogdghjkbafhflamfwlohghtpsseaozorsimnybbtnnbiynlckenbtfmeeamsabnaeoxasjkwswfkekiieckhpecckssptndzelnwfecylbwdlsgvazt'; 280 | 281 | decoder.receivePart(ur) 282 | 283 | if(decoder.isSuccess()) { 284 | const ur = decoder.resultUR(); 285 | const ethSignature = ETHSignature.fromCBOR(ur.cbor); 286 | const requestIdBuffer = ethSignature.getRequestId(); 287 | const signature = ethSignature.getSignature(); // it will return the signature r,s,v 288 | const r = signature.slice(0, 32); 289 | const s = signature.slice(32, 64); 290 | const v = signature.slice(64, 65); 291 | } else if(decoder.isError()){ 292 | // logic for error handling 293 | throw new Error() 294 | } 295 | ``` 296 | 297 | ## Dapp Integration 298 | If you are a Dapp developer and would like to directly integrate with Keystone, we have published several packages to help you do so. 299 | 300 | ### [Onboard](https://www.npmjs.com/package/bnc-onboard) 301 | If you have used onboard.js for wallet connection, Keystone has integrated with onboard.js since `1.32.0-0.2.0`. Install the latest version of onboard.js. you can then enable Keystone as a wallet option. 302 | 303 | ### [Keystone-connector](https://www.npmjs.com/package/@keystonehq/keystone-connector) 304 | If you are using web3-react or something like it for wallet integrations, we have published our `keystone-connector` to help with your integration. You can view it here:[Readme](https://github.com/KeystoneHQ/keystone-airgaped-base/tree/master/packages/keystone-connector) 305 | -------------------------------------------------------------------------------- /integration/index.md: -------------------------------------------------------------------------------- 1 | # Integration With Keystone 2 | 3 | ## Introduction 4 | Keystone is an air-gapped, QR Code based hardware wallet. Keystone is a pure signer for your crypto transactions, Keystone don't have external wireless connections like Bluetooth, WiFi, etc. The only way it can transmit data is via QR codes. 5 | This guide is for developers who would like to integrate their services with Keystone. 6 | 7 | The goal of the Keystone hardware wallet is to provide users with a reliable and quality signer by protecting users' private keys so Keystone seeks to integrate with existing wallets and applications. 8 | 9 | ## Integration with Keystone BTC only firmware 10 | If you would like to integrate with our BTC only frimware. please check [this page](./btc_only_firmware.md). 11 | 12 | ## Integration with Keystone Multi-coin Web3 Mode (Ethereum) 13 | If you would like to integrate with Keystone Web3 Mode (Ethereum). please check [this page](./ethereum.md). -------------------------------------------------------------------------------- /part_f6a35290_5271C071.psbt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/part_f6a35290_5271C071.psbt -------------------------------------------------------------------------------- /pics/cosmos_sign_request.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/cosmos_sign_request.gif -------------------------------------------------------------------------------- /pics/crypto_account_multi_qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/crypto_account_multi_qr.png -------------------------------------------------------------------------------- /pics/crypto_account_qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/crypto_account_qr.png -------------------------------------------------------------------------------- /pics/multi_signed_psbt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/multi_signed_psbt.gif -------------------------------------------------------------------------------- /pics/multi_unsigned_psbt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/multi_unsigned_psbt.gif -------------------------------------------------------------------------------- /pics/read_keyring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/read_keyring.png -------------------------------------------------------------------------------- /pics/sig_signed_psbt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/sig_signed_psbt.gif -------------------------------------------------------------------------------- /pics/sig_unsigned_psbt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/sig_unsigned_psbt.gif -------------------------------------------------------------------------------- /pics/sign_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/sign_request.png -------------------------------------------------------------------------------- /pics/wallet_file_multisig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/pics/wallet_file_multisig.png -------------------------------------------------------------------------------- /research/arweave-qr-data-protocol.md: -------------------------------------------------------------------------------- 1 | # Arweave qr code data transmission protocol 2 | 3 | ## Abstract 4 | 5 | This is the process and data transmission standard via QR Code for offline signer to work with watch-only wallet on 6 | Arweave. 7 | 8 | ## Motivation 9 | 10 | Currently, more and more users would like to use complete offline signers like hardware wallets, mobile phones on 11 | offline mode to manage their private keys. In order to sign transaction or data, these offline signers have to work with 12 | a watch-only wallet. these watch-only will prepare the data to be signed. 13 | Currently, the data transmission method between offline signers and watch-only wallet will include QR Code, 14 | usb,bluetooth and file transfer. Compare with other data transmission method like usb, bluetooth, and file transfer, the 15 | QR Code data transmission have these advantages. 16 | 17 | - Transparency and Security: Compared to usb or bluetooth, user can easily decode the data in QR Code (with the help of 18 | some tools), it can let user know what they are going to sign. this transparency can provide more security. 19 | - Better Compatibility: Compared to usb and Bluetooth, the QR Code data transmission have better compatibility, normally 20 | it will not be broken by other software changes like browser upgrade, system upgrade etc. 21 | - Better User Experience: The QR Code data transmission can provide much better user experience compare to usb, 22 | bluetooth and file transfer especially on the mobile environment. 23 | - Smaller Attack Surface. usb and bluetooth have a higher attack surface than QR-Codes. 24 | 25 | Because of these advantages, the QR Code data transmission is a better choice. However, there is no standard 26 | specification for QR usage in Arweave. 27 | This article presents a standard process and data transmission protocol for offline signers to work with the watch-only 28 | wallet. 29 | 30 | ## Specification 31 | 32 | **Offline signer**: the offline signer is a device or application which holds user private keys and does not have 33 | network access. 34 | 35 | **Watch-only wallet**: the watch only wallet is the wallet which has network access and will interact with blockchain. 36 | 37 | ## Process: 38 | 39 | In order to work with offline signers, the watch-only wallet should follow the following process. 40 | 41 | 1. offline signers provide public key information to watch-only wallets to generate addresses and sync balance etc via 42 | QR Code. 43 | 2. a watch-only wallet generates the unsigned data and sends it to an offline signer to sign it via QR Code. 44 | 3. an offline signer signs the data and provides a signature back to the watch-only wallet via QR Code. 45 | 4. a watch-only wallet gets the signature and constructs the signed data (transaction) and performs the following 46 | actions like broadcasting the transaction etc. 47 | 48 | ## Data transmission protocol 49 | 50 | Since one QR Code can contain a limited size of data, the animated QR Codes should be included for data transmission.The 51 | BC-UR defined by BlockchainCommons have published a series data transmission protocol called br-ur. It provides a basic 52 | method for encoding data to animated QR Code. this article will use the bc-ur and extend its current definition. all the 53 | data are encoded by CBOR and the CDDL is the data definition language for CBOR. For more info about bc-ur, please check 54 | out (here)[https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md]. 55 | 56 | ### Setup watch-only wallet by offline signer. 57 | 58 | In order to let a watch-only wallet collect information from blockchain, the offline signer should provide public keys 59 | to watch-only wallets which generate addresses from these keys and query info like balance from blockchain. 60 | 61 | In this case, offline signers will provide the public keys. A new UR type `crypto-arweave-account` will be used import arweave account. 62 | 63 | #### CDDL for arweave account 64 | 65 | ``` 66 | ; `master-fingerprint` is the identifier for this arweave account. 67 | ; `key-data` is the RSA public key modulus for generating the arweave account address. 68 | ; `device` is the origin of the account. like watch-only wallet name. 69 | 70 | account = { 71 | master-fingerprint: uint32, ; Master fingerprint (fingerprint for the master public key as per BIP32) 72 | key-data: key-data-bytes, ; RSA public key modulus. 73 | ? device: text ; Indicates the origin of the account, e.g. 'Keystone'. 74 | } 75 | 76 | master-fingerprint = 1 77 | key-data = 2 78 | device = 3 79 | ``` 80 | 81 | #### Example: 82 | 83 | Test Data: 84 | > TBD 85 | 86 | QR: 87 | > TBD 88 | 89 | ### Sending the unsigned data from wallet-only wallet to offline signer. 90 | 91 | For sending the unsigned data from a watch-only wallet to an offline signer. a new bc-ur type `arweave-sign-request` will 92 | be introduced for encoding the signing request, multiple sign requests are supported. 93 | 94 | #### CDDL for Arweave Sign Request. 95 | 96 | The following specification is written in Concise Data Definition Language [CDDL]. 97 | UUIDs in this specification notated uuid are CBOR binary strings tagged with #6.37, per the IANA CBOR Tags Registry. 98 | 99 | ``` 100 | ; Metadata for the signing request for Arweave. 101 | ; `master-fingerprint` is the identifier for this arweave account. 102 | ; `request-id` is the identifier for this signing request. 103 | ; `sign-data` is the transaction data to be signed. 104 | ; `sign-type` is the data type to be signed, eg `sign-type-transaction` for signing transaction, `sign-type-data-item` for signing data item. 105 | ; `salt-len` is the `rsa-pss` salt length, zero for deterministic signature. 106 | ; `origin` is the origin of this sign request. like watch-only wallet name. 107 | ; `account` is the Arweave account of the signing type for verification purpose which is optional. 108 | 109 | arweave-sign-request = ( 110 | master-fingerprint: uint32, ; Master fingerprint (fingerprint for the master public key as per BIP32) 111 | ?request-id: uuid, 112 | sign-data: [+ bytes], 113 | sign-type: int .default sign-type-transaction, ;sign type identifier, 114 | salt_len: int, ;RSA-PSS salt length. 115 | ?origin: text, 116 | ?account: bytes, 117 | ) 118 | 119 | master-fingerprint = 1 120 | request-id = 2 121 | sign-data = 3 122 | sign-type = 4 123 | salt-len = 5 124 | account = 6 125 | origin = 7 126 | ``` 127 | 128 | #### Example 129 | 130 | TBD 131 | 132 | ### Offline signers provide the signature to watch-only wallets. 133 | 134 | After signing the data offline signer should send the signature back to the watch-only wallet. and a new bc-ur type 135 | called `arweave-signature` introduced here to encode the data, multiple signatures are supported. 136 | 137 | #### CDDL for Sol Signature. 138 | 139 | The following specification is written in Concise Data Definition Language [CDDL]. 140 | 141 | ``` 142 | arweave-signature = ( 143 | request-id: uuid, 144 | signature: [+ bytes] 145 | ) 146 | ``` 147 | 148 | ## Copyright 149 | 150 | Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). 151 | 152 | ## References 153 | 154 | BC-UR https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md 155 | 156 | 157 | -------------------------------------------------------------------------------- /research/blinding-signing-on-solana.md: -------------------------------------------------------------------------------- 1 | # Blind Signing on Solana Blockchain 2 | 3 | ## What is Blind signing 4 | 5 | Transaction is the building block of blockchain. No matter whether it is an asset transfer or minting a nft, everything happening on blockchain is based on transaction. Every valid transaction should be signed by users' private keys. In this case, the user should know what the transaction is about and the result of signing the transaction. 6 | 7 | For blind signing, user are not aware about what they are signing about. Here is an example about the blind signing. 8 | 9 | ![](./ledger-solana-tx.png) 10 | 11 | Here is the screenshot about how ledger shows the data when doing a swap transaction on [Saber exchange](https://saber.so/). It only shows the transaction hash to make the user confirm which user actually doesn't know what it is about. This is a clear example of blind signing. 12 | 13 | ## Why blind signing is dangerous 14 | 15 | Blind signing can be really dangerous for users. Let's think about these cases. One if the attacker has hacked the user's computer, changed the transaction hash to a different one and tricked the user to sign it. Users' assets can be drained by this malicious transaction. 16 | 17 | Second and fishing exchange dapp(e.g. a fake [Saber exchange](https://saber.so/) ) can trick user to sign the malicious transaction when the user performs a swap transaction. 18 | 19 | Actually these incidents have happened. Hugh, the founder of Nexus, has been drained of his assets because the attacker hacked his wallet and tricked him to sign the malicious transaction. 20 | 21 | So the blind signing can be really dangerous for the user. and This is a really important topic on blockchain security. 22 | 23 | ## What is the current status of blind signing on Solana blockchain? 24 | 25 | Actually the blind signing issue has been discussed a lot in the ethereum community and a lot of improvement has been raised to fix this. Metamask has added an feature called Transaction Insight to decode the transaction data to make user to confirm. Keystone has created the `Smart Contract Metadata Registry` to collect smart contract abi data and use it as the data source to decode the transaction data. 26 | 27 | But what is the current status on the Solana blockchain? We have seen that ledger is blind signing for solana blockchain. Unfortunately, most of the solana wallets are actually blind signing. 28 | 29 | ## How to fix the blind signing on solana blockchain 30 | 31 | Since the blind signing can be really dangrouses, I think these fields can be applied to fix the blind signing issue on solana blockchain. 32 | 33 | ### Decode Transactions 34 | 35 | The first thing to fix blind signing to decode the transaction. Currently in most wallets, transactions are shown as raw binary string to the user. But actually we can decode it as a json string which can provide more transparency to users. The solana transaction includes different fields like `accounts`, `instructions`. After decoding, user can have a better idea about what is this transaction about. 36 | 37 | Current Transaction data shown to users on Solana. 38 | 39 | ``` 40 | 010001032d3c742b98f9ea7738f25a07e7019a6ec8ef0b08f1616b3a3d293e2010aef5bd3a5f18dc95951ad2b1d23f3c5d5aa57b299a9ef9a433be789229a19398e946bc0000000000000000000000000000000000000000000000000000000000000000a756488a76e24b97285c0f334e669b1b7165004f2f520bdad5ecbdbb3641057901020200010c0200000000ca9a3b00000000 41 | ``` 42 | 43 | Instead of showing the raw hex, we propose to show the json string. 44 | 45 | ```json 46 | { 47 | "accounts": [ 48 | "43ap6hKfRVzFWzrhmHnsUnY2TWPS81HorucbWte6mW5r", 49 | "4vrkYqBkdq2joekbn9YNNgosraNv1xnvLvWUt51AHN6P", 50 | "11111111111111111111111111111111" 51 | ], 52 | "block_hash": "CGDPugJoBqVzvmTfjnofbRjKYLhajAfYxb3dCP664ikG", 53 | "header": { 54 | "num_readonly_signed_accounts": 0, 55 | "num_readonly_unsigned_accounts": 1, 56 | "num_required_signatures": 1 57 | }, 58 | "instructions": [ 59 | { 60 | "account_indexes": [0, 1], 61 | "accounts": "43ap6hKfRVzFWzrhmHnsUnY2TWPS81HorucbWte6mW5r4vrkYqBkdq2joekbn9YNNgosraNv1xnvLvWUt51AHN6P", 62 | "data": "3Bxs3zzLZLuLQEYX", 63 | "program_account": "11111111111111111111111111111111", 64 | "program_index": 2 65 | } 66 | ] 67 | } 68 | ``` 69 | 70 | ### Use the verification code to confirm the data transmission 71 | 72 | On Solana, there is a really great rpc called `simulateTransaction`. With it the wallet can simulate the result of the transaction and show the result to the user to make them have more sense about the transaction's result. But there is one potenital issue here, especially if the user is using the hardware wallet as the signer. How to make sure the data hardware walle received is the same as the simulation ones? If the data is replaced during transmission, users will still have the risk of being hacked. 73 | 74 | One possible solution for this is showing an CRC32 verification code and software side and on the hardware side, the hardware will also calculate CRC32 based on the received data and show it on the hardware screen. So if the data have been replaced during transmission. Users can find it out when checking the verification code. 75 | 76 | ``` 77 | CRC32(unsigned transaction data) == CRC32(received data) 78 | ``` 79 | 80 | ### Decode the instruction data 81 | 82 | On solana, one transaction can contain multiple instructions. Take this unsigned transaction as an example. 83 | 84 | ```json 85 | { 86 | "accounts": [ 87 | "ETd398KHD12CV9htTeADMBwNQfXVuYRLmomGUKpgcdVc", 88 | "7fDG38NmBGVgM4dnZJcv7ZJ1ZsX5Z8QX8ET79A7qfpqr", 89 | "3Jzkz1f3Hy4uZNAG71HDa9pwivrCX7WLR5PoZJZVyAvs", 90 | "6aFutFMWR7PbWdBQhdfrcKrAor9WYa2twtSinTMb9tXv", 91 | "6MKBqwbRQSLisCGgtRjhBmAv7o6KtCWpWk7jTmob26Wn", 92 | "HXbhpnLTxSDDkTg6deDpsXzJRBf8j7T6Dc3GidwrLWeo", 93 | "J53kBEY831Mr3RdZtUjEkJeuweKNxTeYNbV9vLYLhp5W", 94 | "11111111111111111111111111111111", 95 | "72E8LfHqoxQCxnxmBbDG6WSHnDx1rWPUHNKwYvoL5qDm", 96 | "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", 97 | "Crt7UoUR6QgrFrN7j8rmSQpUTNWNSitSwWvsWGf1qZ5t", 98 | "EJwZgeZrdC8TXTQbQBoL6bfuAnFUUy1PVCMB4DYPzVaS", 99 | "SSwpkEEcbUqx4vtoEByFjSkhKdCT862DNVb52nZg1UZ", 100 | "SysvarC1ock11111111111111111111111111111111", 101 | "SysvarRent111111111111111111111111111111111", 102 | "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", 103 | "VeNkoB1HvSP6bSeGybQDnx9wTWFsQb2NBCemeCDSuKL" 104 | ], 105 | "block_hash": "MCLBNJ9fS9f6CUzB2JRZG5oquvrfzLkgKMSxT8K9Kn9", 106 | "header": { 107 | "num_readonly_signed_accounts": 0, 108 | "num_readonly_unsigned_accounts": 10, 109 | "num_required_signatures": 2 110 | }, 111 | "instructions": [ 112 | { 113 | "account_indexes": [0, 4, 0, 11, 7, 15, 14], 114 | "accounts": "ETd398KHD12CV9htTeADMBwNQfXVuYRLmomGUKpgcdVc6MKBqwbRQSLisCGgtRjhBmAv7o6KtCWpWk7jTmob26WnETd398KHD12CV9htTeADMBwNQfXVuYRLmomGUKpgcdVcEJwZgeZrdC8TXTQbQBoL6bfuAnFUUy1PVCMB4DYPzVaS11111111111111111111111111111111TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DASysvarRent111111111111111111111111111111111", 115 | "data": "", 116 | "program_account": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", 117 | "program_index": 9 118 | }, 119 | { 120 | "account_indexes": [0, 1], 121 | "accounts": "ETd398KHD12CV9htTeADMBwNQfXVuYRLmomGUKpgcdVc7fDG38NmBGVgM4dnZJcv7ZJ1ZsX5Z8QX8ET79A7qfpqr", 122 | "data": "1111d4cKUwWT791nL5fDAsbFpB8Z3U45oQ33rHwofEZqfVv9X9FAApjuHP73AKbnJks8N", 123 | "program_account": "11111111111111111111111111111111", 124 | "program_index": 7 125 | }, 126 | { 127 | "account_indexes": [1, 2, 4, 0], 128 | "accounts": "7fDG38NmBGVgM4dnZJcv7ZJ1ZsX5Z8QX8ET79A7qfpqr3Jzkz1f3Hy4uZNAG71HDa9pwivrCX7WLR5PoZJZVyAvs6MKBqwbRQSLisCGgtRjhBmAv7o6KtCWpWk7jTmob26WnETd398KHD12CV9htTeADMBwNQfXVuYRLmomGUKpgcdVc", 129 | "data": "8QL9xsAz2gjrVBFt8QhiPPMarbiNTJic1tfh", 130 | "program_account": "Crt7UoUR6QgrFrN7j8rmSQpUTNWNSitSwWvsWGf1qZ5t", 131 | "program_index": 10 132 | }, 133 | { 134 | "account_indexes": [1, 15, 12, 0, 16, 8, 13, 2, 3, 4, 5, 6], 135 | "accounts": "7fDG38NmBGVgM4dnZJcv7ZJ1ZsX5Z8QX8ET79A7qfpqrTokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DASSwpkEEcbUqx4vtoEByFjSkhKdCT862DNVb52nZg1UZETd398KHD12CV9htTeADMBwNQfXVuYRLmomGUKpgcdVcVeNkoB1HvSP6bSeGybQDnx9wTWFsQb2NBCemeCDSuKL72E8LfHqoxQCxnxmBbDG6WSHnDx1rWPUHNKwYvoL5qDmSysvarC1ock111111111111111111111111111111113Jzkz1f3Hy4uZNAG71HDa9pwivrCX7WLR5PoZJZVyAvs6aFutFMWR7PbWdBQhdfrcKrAor9WYa2twtSinTMb9tXv6MKBqwbRQSLisCGgtRjhBmAv7o6KtCWpWk7jTmob26WnHXbhpnLTxSDDkTg6deDpsXzJRBf8j7T6Dc3GidwrLWeoJ53kBEY831Mr3RdZtUjEkJeuweKNxTeYNbV9vLYLhp5W", 136 | "data": "DzUHxT3nqgc", 137 | "program_account": "Crt7UoUR6QgrFrN7j8rmSQpUTNWNSitSwWvsWGf1qZ5t", 138 | "program_index": 10 139 | }, 140 | { 141 | "account_indexes": [1, 4, 0, 0], 142 | "accounts": "7fDG38NmBGVgM4dnZJcv7ZJ1ZsX5Z8QX8ET79A7qfpqr6MKBqwbRQSLisCGgtRjhBmAv7o6KtCWpWk7jTmob26WnETd398KHD12CV9htTeADMBwNQfXVuYRLmomGUKpgcdVcETd398KHD12CV9htTeADMBwNQfXVuYRLmomGUKpgcdVc", 143 | "data": "XDKtopMv1Pm", 144 | "program_account": "Crt7UoUR6QgrFrN7j8rmSQpUTNWNSitSwWvsWGf1qZ5t", 145 | "program_index": 10 146 | } 147 | ] 148 | } 149 | ``` 150 | 151 | Each instruction contains one field called data, you can see it in the above example. This is the field indicating which function and params will be executed on this transaction. If the blind signing would be completely resolved, this kind of data should also be decoded. On ethereum, the contract abi can be used to decode the data. But on solana, since all the smart contracts are written by Rust. And this seems no existing solution to decode the instruction data for now. 152 | 153 | But fortunately currently there is a project like [`Anchor`](https://project-serum.github.io/anchor/) to help developers to build the program on solana. Anchor has introduced `IDL` to describe the program. For any programs built on `Anchor`, the IDLs have also been submitted to the [`Anchor` project](https://anchor.projectserum.com/). So these IDLs can be used just like ABI to decode the instruction data. But to achieve this, it would need some changes on the Anchor side to support this. 154 | 155 | So for the latest step, the wallet provider can work with the Anchor team to make the instruction data be fully decoded by using the IDL. 156 | 157 | These are three ways we propose to completely fix the blind signing issue on the Solana blockchain. And we are currently adding the Solana support on our Keystone wallet, we will continually introduce these ways on our product. 158 | -------------------------------------------------------------------------------- /research/ethereum-qr-data-protocol.md: -------------------------------------------------------------------------------- 1 | # Ethereum qr code data transmission protocol 2 | 3 | ## Simple Summary 4 | 5 | Currently more and more users would like to use complete offline singers like air gapped hardware wallets, mobile phones in offline mode to manage their private keys. In order to interact with blockchain. a "watch-only" wallet (like metamask etc.) which have network access are required to pair with these offline signers. Currently there is no standard for how the offline signer can work with "watch-only" wallets via QR Code. so This EIP aims to solve this issue. 6 | 7 | ## Abstract 8 | 9 | This is the process and data transmission standard via QR Code for offline signer to work with watch-only wallet 10 | 11 | ## Motivation 12 | 13 | Currently more and more users would like to use complete offline signers like hardware wallets, mobile phones on offline mode to manage their private keys. In order to sign transaction or data, these offline signers have to work with an watch-only wallet. these watch-only will pepare the data to be sign. currently the data trasmission method between offline signers and watch-only wallet will include QR Code, usb,bluetooth and file transfer.Compare with other data trasmission method like usd, bluetooth, and file transfer, the QR Code data transmission have these advantages. 14 | 15 | - Transparency and Security: Compared to usb or bluetooth, user can easily decode the data in QR Code (with the help of some tools), it can let user know what they are going to sign. this Transparency can provide more security. 16 | - Better Compatibility: Compared to usb and Bluetooth, the QR Code data transmission have better compatibility, normally it will not be break by other software change like browser upgrade. system upgrade etc. 17 | - Better User experience: The QR Code data transmission can provide more better user experience compare to usb, bluetooth and file transfer especially on the mobile environment. 18 | - Smaller attack surface. USB and Bluetooth have a higher attack surface than QR-Codes. 19 | 20 | Because of these advantages, the QR Code data transmission is a better choice. But currently there is no standard for how the offline signer work with watch-only wallet and how the data can be encoded. 21 | This EIP presents a standard process and data transmission protocol for offline signers to work with the watch-only wallet. 22 | 23 | ## Specification 24 | 25 | **Offline signer**: the offline signer is a device or application which holds user private keys and does not have network access. 26 | 27 | **Watch-only wallet**: the watch only wallet is the wallet which has network access and will interact with blockchain. 28 | 29 | ## Process: 30 | In order to work with offline signers, the watch-only wallet should follow the following process. 31 | 1. offline signers provide public key information to watch-only wallets to generate addresses and sync balance etc via QR Code. 32 | 2. a watch-only wallet generates the unsigned data and sends it to an offline signer to sign it including transaction, typed data etc via QR Code. 33 | 3. an offline signer signs the data and provides a signature back to the watch-only wallet via QR Code. 34 | 4. a watch-only wallet gets the signature and constructs the signed data (transaction) and performs the following action like broadcasting the transaction etc. 35 | 36 | ## Data transmission protocol 37 | 38 | Since one QR Code can contain a limited size of data, the animated QR Codes should be included for data transmission.The BC-UR defined by BlockchainCommons have published a series data transmission protocol called br-ur. It provides a basic method for encoding data to animated QR Code. this EIP will use the bc-ur and extend its current definition. all the data are encoded by CBOR and the CDDL is the data definition language for CBOR. For more info about bc-ur, please check out (here)[https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md]. 39 | 40 | 41 | ### Setup watch-only wallet by offline signer. 42 | In order to let a watch-only wallet collect information from blockchain, the offline signer should provide public keys to watch-only wallets which generate addresses from these keys and query info like balance from blockchain. Currently most wallet service providers are following BIP-44 to generate the address. 43 | 44 | In this case, offline signers will provide the extended public keys and derivation path. the UR Type called `crypto-hdkey` will be used to encode these data. and the derivation path will be encoded as `crypto-keypath` which defined in in bc-ur 45 | 46 | #### CDDL for Key Path 47 | The following specification is written in Concise Data Definition Language [CDDL]. 48 | 49 | ``` 50 | ; Metadata for the derivation path of a key. 51 | ; 52 | ; `source-fingerprint`, if present, is the fingerprint of the 53 | ; ancestor key from which the associated key was derived. 54 | ; 55 | ; If `components` is empty, then `source-fingerprint` MUST be a fingerprint of 56 | ; a master key. 57 | ; 58 | ; `depth`, if present, represents the number of derivation steps in 59 | ; the path of the associated key, even if not present in the `components` element 60 | ; of this structure. 61 | crypto-keypath = { 62 | components: [path-component], ; If empty, source-fingerprint MUST be present 63 | ? source-fingerprint: uint32 .ne 0 ; fingerprint of ancestor key, or master key if components is empty 64 | ? depth: uint8 ; 0 if this is a public key derived directly from a master key 65 | } 66 | 67 | path-component = ( 68 | child-index / child-index-range / child-index-wildcard-range, 69 | is-hardened 70 | ) 71 | 72 | uint32 = uint .size 4 73 | uint31 = uint32 .lt 2147483648 ;0x80000000 74 | child-index = uint31 75 | child-index-range = [child-index, child-index] ; [low, high] where low < high 76 | child-index-wildcard = [] 77 | 78 | is-hardened = bool 79 | 80 | components = 1 81 | source-fingerprint = 2 82 | depth = 3 83 | ``` 84 | 85 | #### CDDL for derivation key 86 | Since the main purpose of the key is to transfer public key data. the defination of crypto-hdkey will be kept on ly public keys. 87 | For HD-derivation-key, which will present the key data and its derivation path. 88 | The following specification is written in Concise Data Definition Language [CDDL] and includes the crypto-keypath spec above. 89 | ``` 90 | ; A derived key must be public, has an optional chain code, and 91 | ; may carry additional metadata about its use and derivation. 92 | ; To maintain isomorphism with [BIP32] and allow keys to be derived from 93 | ; this key `chain-code`, `origin`, and `parent-fingerprint` must be present. 94 | ; If `origin` contains only a single derivation step and also contains `source-fingerprint`, 95 | ; then `parent-fingerprint` MUST be identical to `source-fingerprint` or may be omitted. 96 | derived-key = ( 97 | key-data: key-data-bytes, 98 | ? chain-code: chain-code-bytes ; omit if no further keys may be derived from this key 99 | ? origin: #6.304(crypto-keypath), ; How the key was derived 100 | ? name: text, ; A short name for this key. 101 | ) 102 | 103 | ; If the `use-info` field is omitted, defaults (mainnet BTC key) are assumed. 104 | ; If `cointype` and `origin` are both present, then per [BIP44], the second path 105 | ; component's `child-index` must match `cointype`. 106 | 107 | key-data = 3 108 | chain-code = 4 109 | origin = 6 110 | name = 9 111 | 112 | uint8 = uint .size 1 113 | key-data-bytes = bytes .size 33 114 | chain-code-bytes = bytes .size 32 115 | ``` 116 | If the chain-code is provided is can be used to derive child keys and if the chain code is not provided it just an solo key and origin can be provided to indicate the derivation key path. 117 | 118 | #### Example: 119 | Test Data: 120 | ``` 121 | { 122 | "extendPublicKey": "xpub6Cq5iFcEz9gTANMrxck2Ee3zp18ZzfYNFU9aXxBi7kFYNY42FYaCr8fWBLkHo5Vw3MwWYeUjcVvkSonynexiHWEge4yfPP13J9JCB7pakEm", 123 | "path": "M/44'/60'/0'", 124 | "MasterFignerPrint":"cfc23f3f", 125 | } 126 | ``` 127 | CBOR Binary: 128 | 129 | ``` 130 | A303582103DA1A04CC1509CD716E215F1C8A3D1530A6B4EFDACB04D1641EAA117342EFA4B1045820FDCA62CADED4C32CD914A3CEF84529504BC534C721997E196BE421162F3EB81D06D90130A20186182CF5183CF500F5021ACFC23F3F 131 | ``` 132 | 133 | UR: 134 | 135 | ``` 136 | ur:crypto-public-key/otaxhdclaxtncyaasfbzassnjsjtclhecelefsbzdyolqzwstnsbaattieckpkbyjkfwwsoxpaaahdcxzcsgidsguetysrdwtabbottoyafedtgdgrskeestclnlkbcfjeveclcmdlfmrocaamtaaddyoeadlncsdwykcsfnykaeykaocytksafhfhgdlsvlpr 137 | ``` 138 | 139 | QR: 140 | ![](./hd-key.png) 141 | 142 | ### Sending the unsigned data from wallet-only wallet to offline signer. 143 | For sending the unsigned data from a watch-only wallet to an offline signer. a new bc-ur type `eth-sign-request` will be introduced for encoding the signing request. 144 | 145 | #### CDDL for Eth Sign Request. 146 | The following specification is written in Concise Data Definition Language [CDDL]. 147 | UUIDs in this specification notated uuid are CBOR binary strings tagged with #6.37, per the IANA CBOR Tags Registry. 148 | 149 | 150 | ``` 151 | ; Metadata for the signing request for ethereum. 152 | ; request-id is the identifier for this signing request. 153 | ; sign-data is the data to be signed 154 | ; data-type is to indicate what is the data to be signed. 155 | ; chain-id to show it is the mainnet or testnet 156 | ; derivation-path is the path of the private key to sign the data 157 | ; address is the ethereum address of the signing type for verification purpose which is optional 158 | 159 | 160 | ; `sign-data-type` is to indicate what is the data to be signed. 161 | ; current have three types transaction, EIP 712 typed data or raw types 162 | ; 163 | sign-data-type = { 164 | type: int .default 1 transaction data; type data defined as following value 165 | } 166 | 167 | eth-transaction-data = 1; for unsigned transaction if will be the rlp encoding bytes 168 | eth-typed-data = 2; 169 | eth-raw-bytes=3; 170 | eth-typed-transaction=4; 171 | 172 | 173 | eth-sign-request = ( 174 | sign-data: sign-data-bytes, ; sign-data is the data to be signed by offline signer, currently it can be unsigned transaction or typed data 175 | data-type: #3.401(sign-data-type), 176 | chain-id: int .default 1, 177 | derivation-path: #5.304(crypto-keypath), ;the key path for signing this request 178 | ?request-id: uuid, ; the uuid for this signing request 179 | ?address: eth-address-bytes, ;verification purpose for the address of the signing key 180 | ?origin: text ;the origin of this sign request, like a dapp 181 | ) 182 | 183 | request-id = 1 184 | sign-data = 2 185 | data-type = 3 186 | 187 | chain-id = 4 ;it will be the chain id of ethereum related blockchain 188 | derivation-path = 5 189 | address = 6 190 | origin = 7 191 | 192 | eth-address-bytes = bytes .size 20 193 | 194 | sign-data-bytes = bytes ; for unsigned transactions it will be the rlp encoding for unsigned transaction data and ERC 712 typed data it will be the bytes of json string. 195 | 196 | ``` 197 | the sign-data: the unsigned transactions it will be the rlp encoding for unsigned transaction data and ERC 712 typed data it will be the bytes of json string. and raw bytes can also supported. 198 | 199 | #### Example 200 | TBD 201 | 202 | ### Offline signers provide the signature to watch-only wallets. 203 | After signing the data offline signer should send the signature back to the watch-only wallet. and a new bc-ur type called `eth-signature` introduced here to encode the data. 204 | 205 | #### CDDL for Eth Signature. 206 | The following specification is written in Concise Data Definition Language [CDDL]. 207 | 208 | ``` 209 | eth-signature = ( 210 | request-id: uuid, 211 | signature: eth-signature-bytes 212 | ) 213 | 214 | eth-signature-bytes = bytes .size 65; the signature of the signing request (r,s,v) 215 | ``` 216 | 217 | ## Rationale 218 | 219 | ## Backwards Compatibility 220 | 221 | ## Test Cases 222 | 223 | ## Implementation 224 | 225 | ## Copyright 226 | Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). 227 | 228 | ## References 229 | BC-UR https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md 230 | 231 | 232 | -------------------------------------------------------------------------------- /research/ledger-solana-tx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/research/ledger-solana-tx.png -------------------------------------------------------------------------------- /research/near-qr-data-protocol.md: -------------------------------------------------------------------------------- 1 | # Near qr code data transmission protocol 2 | 3 | ## Abstract 4 | 5 | This is the process and data transmission standard via QR Code for offline signer to work with watch-only wallet on Near. 6 | 7 | ## Motivation 8 | 9 | Currently, more and more users would like to use complete offline signers like hardware wallets, mobile phones on offline mode to manage their private keys. In order to sign transaction or data, these offline signers have to work with a watch-only wallet. these watch-only will prepare the data to be sign. 10 | Currently, the data transmission method between offline signers and watch-only wallet will include QR Code, usb,bluetooth and file transfer. Compare with other data transmission method like usb, bluetooth, and file transfer, the QR Code data transmission have these advantages. 11 | 12 | - Transparency and Security: Compared to usb or bluetooth, user can easily decode the data in QR Code (with the help of some tools), it can let user know what they are going to sign. this transparency can provide more security. 13 | - Better Compatibility: Compared to usb and Bluetooth, the QR Code data transmission have better compatibility, normally it will not be broken by other software changes like browser upgrade, system upgrade etc. 14 | - Better User Experience: The QR Code data transmission can provide much better user experience compare to usb, bluetooth and file transfer especially on the mobile environment. 15 | - Smaller Attack Surface. usb and bluetooth have a higher attack surface than QR-Codes. 16 | 17 | Because of these advantages, the QR Code data transmission is a better choice. However, there is no standard specification for QR usage in Near. 18 | This article presents a standard process and data transmission protocol for offline signers to work with the watch-only wallet. 19 | 20 | ## Specification 21 | 22 | **Offline signer**: the offline signer is a device or application which holds user private keys and does not have network access. 23 | 24 | **Watch-only wallet**: the watch only wallet is the wallet which has network access and will interact with blockchain. 25 | 26 | ## Process: 27 | In order to work with offline signers, the watch-only wallet should follow the following process. 28 | 1. offline signers provide public key information to watch-only wallets to generate addresses and sync balance etc via QR Code. 29 | 2. a watch-only wallet generates the unsigned data and sends it to an offline signer to sign it via QR Code. 30 | 3. an offline signer signs the data and provides a signature back to the watch-only wallet via QR Code. 31 | 4. a watch-only wallet gets the signature and constructs the signed data (transaction) and performs the following actions like broadcasting the transaction etc. 32 | 33 | ## Data transmission protocol 34 | 35 | Since one QR Code can contain a limited size of data, the animated QR Codes should be included for data transmission.The BC-UR defined by BlockchainCommons have published a series data transmission protocol called br-ur. It provides a basic method for encoding data to animated QR Code. this article will use the bc-ur and extend its current definition. all the data are encoded by CBOR and the CDDL is the data definition language for CBOR. For more info about bc-ur, please check out (here)[https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md]. 36 | 37 | 38 | ### Setup watch-only wallet by offline signer. 39 | In order to let a watch-only wallet collect information from blockchain, the offline signer should provide public keys to watch-only wallets which generate addresses from these keys and query info like balance from blockchain. 40 | 41 | In this case, offline signers will provide the public keys and derivation path. the UR Type called `crypto-hdkey` will be used to encode these data. and the derivation path will be encoded as `crypto-keypath` which defined in bc-ur.Also, a new UR type `crypto-multi-accounts` will be used if we want to import multiple accounts in one animated QR. 42 | 43 | #### CDDL for Key Path 44 | The following specification is written in Concise Data Definition Language [CDDL]. 45 | 46 | ``` 47 | ; Metadata for the derivation path of a key. 48 | ; 49 | ; `source-fingerprint`, if present, is the fingerprint of the 50 | ; ancestor key from which the associated key was derived. 51 | ; 52 | ; If `components` is empty, then `source-fingerprint` MUST be a fingerprint of 53 | ; a master key. 54 | ; 55 | ; `depth`, if present, represents the number of derivation steps in 56 | ; the path of the associated key, even if not present in the `components` element 57 | ; of this structure. 58 | crypto-keypath = { 59 | components: [path-component], ; If empty, source-fingerprint MUST be present 60 | ? source-fingerprint: uint32 .ne 0 ; fingerprint of ancestor key, or master key if components is empty 61 | ? depth: uint8 ; 0 if this is a public key derived directly from a master key 62 | } 63 | 64 | path-component = ( 65 | child-index / child-index-range / child-index-wildcard-range, 66 | is-hardened 67 | ) 68 | 69 | uint32 = uint .size 4 70 | uint31 = uint32 .lt 2147483648 ;0x80000000 71 | child-index = uint31 72 | child-index-range = [child-index, child-index] ; [low, high] where low < high 73 | child-index-wildcard = [] 74 | 75 | is-hardened = bool 76 | 77 | components = 1 78 | source-fingerprint = 2 79 | depth = 3 80 | ``` 81 | 82 | #### CDDL for derivation key 83 | Since the main purpose of the key is to transfer public key data. the defination of crypto-hdkey will be kept only public keys. 84 | For HD-derivation-key, which will present the key data and its derivation path. 85 | The following specification is written in Concise Data Definition Language [CDDL] and includes the crypto-keypath spec above. 86 | ``` 87 | ; A derived key must be public, has an optional chain code, and 88 | ; may carry additional metadata about its use and derivation. 89 | ; To maintain isomorphism with [BIP32] and allow keys to be derived from 90 | ; this key `chain-code`, `origin`, and `parent-fingerprint` must be present. 91 | ; If `origin` contains only a single derivation step and also contains `source-fingerprint`, 92 | ; then `parent-fingerprint` MUST be identical to `source-fingerprint` or may be omitted. 93 | derived-key = ( 94 | key-data: key-data-bytes, 95 | ? chain-code: chain-code-bytes ; omit if no further keys may be derived from this key 96 | ? origin: #6.304(crypto-keypath), ; How the key was derived 97 | ? name: text, ; A short name for this key. 98 | ) 99 | 100 | ; If the `use-info` field is omitted, defaults (mainnet BTC key) are assumed. 101 | ; If `cointype` and `origin` are both present, then per [BIP44], the second path 102 | ; component's `child-index` must match `cointype`. 103 | 104 | key-data = 3 105 | chain-code = 4 106 | origin = 6 107 | name = 9 108 | 109 | uint8 = uint .size 1 110 | key-data-bytes = bytes .size 33 111 | chain-code-bytes = bytes .size 32 112 | ``` 113 | If the chain-code is provided is can be used to derive child keys and if the chain code is not provided it just an solo key and origin can be provided to indicate the derivation key path. 114 | 115 | #### Example: 116 | Test Data: 117 | > TBD 118 | 119 | QR: 120 | > TBD 121 | 122 | #### CDDL for multiple accounts 123 | 124 | ``` 125 | key_exp = #6.303(crypto-hdkey) 126 | 127 | accounts = { 128 | master-fingerprint: uint32, ; Master fingerprint (fingerprint for the master public key as per BIP32) 129 | keys: [+ key_exp] ; Different account keys for a offline signer. 130 | ? device: text ; Indicates the origin of these accounts, e.g. 'Keystone' 131 | } 132 | 133 | master-fingerprint = 1 134 | keys = 2 135 | device = 3 136 | ``` 137 | 138 | #### Example: 139 | Test Data: 140 | > TBD 141 | 142 | QR: 143 | > TBD 144 | 145 | ### Sending the unsigned data from wallet-only wallet to offline signer. 146 | For sending the unsigned data from a watch-only wallet to an offline signer. a new bc-ur type `near-sign-request` will be introduced for encoding the signing request, multiple sign requests are supported. 147 | 148 | #### CDDL for Near Sign Request. 149 | The following specification is written in Concise Data Definition Language [CDDL]. 150 | UUIDs in this specification notated uuid are CBOR binary strings tagged with #6.37, per the IANA CBOR Tags Registry. 151 | 152 | 153 | ``` 154 | ; Metadata for the signing request for Near. 155 | ; `request-id` is the identifier for this signing request. 156 | ; `sign-data` is the transaction data to be signed. 157 | ; `derivation-path` is the path of the private key to sign the data 158 | ; `origin` is the origin of this sign request. like watch-only wallet name. 159 | ; `account` is the Near account of the signing type for verification purpose which is optional 160 | 161 | near-sign-request = ( 162 | ?request-id: uuid, 163 | sign-data: [+ bytes], 164 | derivation-path: #5.304(crypto-keypath), ;the key path for signing this request 165 | ?origin: text, 166 | ?account: bytes, 167 | ) 168 | 169 | request-id = 1 170 | sign-data = 2 171 | derivation-path = 3 172 | account = 4 173 | origin = 5 174 | ``` 175 | 176 | #### Example 177 | TBD 178 | 179 | ### Offline signers provide the signature to watch-only wallets. 180 | After signing the data offline signer should send the signature back to the watch-only wallet. and a new bc-ur type called `near-signature` introduced here to encode the data, multiple signatures are supported. 181 | 182 | #### CDDL for Sol Signature. 183 | The following specification is written in Concise Data Definition Language [CDDL]. 184 | 185 | ``` 186 | near-signature = ( 187 | request-id: uuid, 188 | signature: [+ bytes] 189 | ) 190 | ``` 191 | 192 | ## Copyright 193 | Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). 194 | 195 | ## References 196 | BC-UR https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md 197 | 198 | 199 | -------------------------------------------------------------------------------- /research/solana-qr-data-protocol.md: -------------------------------------------------------------------------------- 1 | # Solana qr code data transmission protocol 2 | 3 | ## Abstract 4 | 5 | This is the process and data transmission standard via QR Code for offline signer to work with watch-only wallet on Solana. 6 | 7 | ## Motivation 8 | 9 | Currently, more and more users would like to use complete offline signers like hardware wallets, mobile phones on offline mode to manage their private keys. In order to sign transaction or data, these offline signers have to work with a watch-only wallet. these watch-only will prepare the data to be sign. 10 | Currently, the data transmission method between offline signers and watch-only wallet will include QR Code, usb,bluetooth and file transfer.Compare with other data transmission method like usd, bluetooth, and file transfer, the QR Code data transmission have these advantages. 11 | 12 | - Transparency and Security: Compared to usb or bluetooth, user can easily decode the data in QR Code (with the help of some tools), it can let user know what they are going to sign. this Transparency can provide more security. 13 | - Better Compatibility: Compared to usb and Bluetooth, the QR Code data transmission have better compatibility, normally it will not be break by other software change like browser upgrade. system upgrade etc. 14 | - Better User experience: The QR Code data transmission can provide much better user experience compare to usb, bluetooth and file transfer especially on the mobile environment. 15 | - Smaller attack surface. USB and Bluetooth have a higher attack surface than QR-Codes. 16 | 17 | Because of these advantages, the QR Code data transmission is a better choice. However, there is no standard specification for QR usage in Solana. 18 | This article presents a standard process and data transmission protocol for offline signers to work with the watch-only wallet. 19 | 20 | ## Specification 21 | 22 | **Offline signer**: the offline signer is a device or application which holds user private keys and does not have network access. 23 | 24 | **Watch-only wallet**: the watch only wallet is the wallet which has network access and will interact with blockchain. 25 | 26 | ## Process: 27 | In order to work with offline signers, the watch-only wallet should follow the following process. 28 | 1. offline signers provide public key information to watch-only wallets to generate addresses and sync balance etc via QR Code. 29 | 2. a watch-only wallet generates the unsigned data and sends it to an offline signer to sign it via QR Code. 30 | 3. an offline signer signs the data and provides a signature back to the watch-only wallet via QR Code. 31 | 4. a watch-only wallet gets the signature and constructs the signed data (transaction) and performs the following action like broadcasting the transaction etc. 32 | 33 | ## Data transmission protocol 34 | 35 | Since one QR Code can contain a limited size of data, the animated QR Codes should be included for data transmission.The BC-UR defined by BlockchainCommons have published a series data transmission protocol called br-ur. It provides a basic method for encoding data to animated QR Code. this article will use the bc-ur and extend its current definition. all the data are encoded by CBOR and the CDDL is the data definition language for CBOR. For more info about bc-ur, please check out (here)[https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md]. 36 | 37 | 38 | ### Setup watch-only wallet by offline signer. 39 | In order to let a watch-only wallet collect information from blockchain, the offline signer should provide public keys to watch-only wallets which generate addresses from these keys and query info like balance from blockchain. 40 | 41 | In this case, offline signers will provide the public keys and derivation path. the UR Type called `crypto-hdkey` will be used to encode these data. and the derivation path will be encoded as `crypto-keypath` which defined in bc-ur. Also, a new UR type `crypto-multi-accounts` will be used if we want to import multiple accounts in one animated QR. 42 | 43 | #### CDDL for Key Path 44 | The following specification is written in Concise Data Definition Language [CDDL]. 45 | 46 | ``` 47 | ; Metadata for the derivation path of a key. 48 | ; 49 | ; `source-fingerprint`, if present, is the fingerprint of the 50 | ; ancestor key from which the associated key was derived. 51 | ; 52 | ; If `components` is empty, then `source-fingerprint` MUST be a fingerprint of 53 | ; a master key. 54 | ; 55 | ; `depth`, if present, represents the number of derivation steps in 56 | ; the path of the associated key, even if not present in the `components` element 57 | ; of this structure. 58 | crypto-keypath = { 59 | components: [path-component], ; If empty, source-fingerprint MUST be present 60 | ? source-fingerprint: uint32 .ne 0 ; fingerprint of ancestor key, or master key if components is empty 61 | ? depth: uint8 ; 0 if this is a public key derived directly from a master key 62 | } 63 | 64 | path-component = ( 65 | child-index / child-index-range / child-index-wildcard-range, 66 | is-hardened 67 | ) 68 | 69 | uint32 = uint .size 4 70 | uint31 = uint32 .lt 2147483648 ;0x80000000 71 | child-index = uint31 72 | child-index-range = [child-index, child-index] ; [low, high] where low < high 73 | child-index-wildcard = [] 74 | 75 | is-hardened = bool 76 | 77 | components = 1 78 | source-fingerprint = 2 79 | depth = 3 80 | ``` 81 | 82 | #### CDDL for derivation key 83 | Since the main purpose of the key is to transfer public key data. the defination of crypto-hdkey will be kept on ly public keys. 84 | For HD-derivation-key, which will present the key data and its derivation path. 85 | The following specification is written in Concise Data Definition Language [CDDL] and includes the crypto-keypath spec above. 86 | ``` 87 | ; A derived key must be public, has an optional chain code, and 88 | ; may carry additional metadata about its use and derivation. 89 | derived-key = ( 90 | key-data: key-data-bytes, 91 | ? chain-code: chain-code-bytes ; omit if no further keys may be derived from this key 92 | ? origin: #6.304(crypto-keypath), ; How the key was derived 93 | ? name: text, ; A short name for this key. 94 | ) 95 | 96 | key-data = 3 97 | chain-code = 4 98 | origin = 6 99 | name = 9 100 | 101 | key-data-bytes = bytes .size 33 102 | chain-code-bytes = bytes .size 32 103 | ``` 104 | If the chain-code is provided is can be used to derive child keys and if the chain code is not provided it just an solo key and origin can be provided to indicate the derivation key path. 105 | 106 | #### CDDL for multiple accounts 107 | 108 | ``` 109 | key_exp = #6.303(crypto-hdkey) 110 | 111 | accounts = { 112 | master-fingerprint: uint32, ; Master fingerprint (fingerprint for the master public key as per BIP32) 113 | keys: [+ key_exp] ; Different account keys for a offline signer. 114 | ? device: text ; Indicates the origin of these accounts, e.g. 'Keystone' 115 | } 116 | 117 | master-fingerprint = 1 118 | keys = 2 119 | device = 3 120 | ``` 121 | 122 | #### Example: 123 | Test Data: 124 | > TBD 125 | 126 | QR: 127 | > TBD 128 | 129 | ### Sending the unsigned data from wallet-only wallet to offline signer. 130 | For sending the unsigned data from a watch-only wallet to an offline signer. a new bc-ur type `sol-sign-request` will be introduced for encoding the signing request. 131 | 132 | #### CDDL for Sol Sign Request. 133 | The following specification is written in Concise Data Definition Language [CDDL]. 134 | UUIDs in this specification notated uuid are CBOR binary strings tagged with #6.37, per the IANA CBOR Tags Registry. 135 | 136 | 137 | ``` 138 | ; Metadata for the signing request for Solana. 139 | ; `request-id` is the identifier for this signing request. 140 | ; `sign-data` is the transaction data to be signed. 141 | ; `derivation-path` is the path of the private key to sign the data 142 | ; `origin` is the origin of this sign request. like watch-only wallet name. 143 | ; `address` is the Solana address of the signing type for verification purpose which is optional 144 | 145 | sol-sign-request = ( 146 | ?request-id: uuid, 147 | sign-data: bytes, 148 | derivation-path: #5.304(crypto-keypath), ;the key path for signing this request 149 | ?origin: text, 150 | ?address: bytes 151 | ?type: int .default sign-type-transaction, ;sign type identifier 152 | ) 153 | 154 | request-id = 1 155 | sign-data = 2 156 | derivation-path = 3 157 | address = 4 158 | origin = 5 159 | type = 6 160 | 161 | sign-type-transaction = 1 162 | sign-type-message = 2 163 | ``` 164 | 165 | #### Example 166 | TBD 167 | 168 | ### Offline signers provide the signature to watch-only wallets. 169 | After signing the data offline signer should send the signature back to the watch-only wallet. and a new bc-ur type called `sol-signature` introduced here to encode the data. 170 | 171 | #### CDDL for Sol Signature. 172 | The following specification is written in Concise Data Definition Language [CDDL]. 173 | 174 | ``` 175 | sol-signature = ( 176 | request-id: uuid, 177 | signature: bytes 178 | ) 179 | ``` 180 | 181 | ## Copyright 182 | Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). 183 | 184 | ## References 185 | BC-UR https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md 186 | 187 | 188 | -------------------------------------------------------------------------------- /research/sui-qr-data-protocol.md: -------------------------------------------------------------------------------- 1 | # Sui qr code data transmission protocol 2 | 3 | ## Abstract 4 | 5 | This is the process and data transmission standard via QR Code for offline signer to work with watch-only wallet on Sui. 6 | 7 | ## Motivation 8 | 9 | Currently, more and more users would like to use complete offline signers like hardware wallets, mobile phones on offline mode to manage their private keys. In order to sign transaction or data, these offline signers have to work with a watch-only wallet. these watch-only will prepare the data to be sign. 10 | Currently, the data transmission method between offline signers and watch-only wallet will include QR Code, usb,bluetooth and file transfer. Compare with other data transmission method like usb, bluetooth, and file transfer, the QR Code data transmission have these advantages. 11 | 12 | - Transparency and Security: Compared to usb or bluetooth, user can easily decode the data in QR Code (with the help of some tools), it can let user know what they are going to sign. this transparency can provide more security. 13 | - Better Compatibility: Compared to usb and Bluetooth, the QR Code data transmission have better compatibility, normally it will not be broken by other software changes like browser upgrade, system upgrade etc. 14 | - Better User Experience: The QR Code data transmission can provide much better user experience compare to usb, bluetooth and file transfer especially on the mobile environment. 15 | - Smaller Attack Surface. usb and bluetooth have a higher attack surface than QR-Codes. 16 | 17 | Because of these advantages, the QR Code data transmission is a better choice. However, there is no standard specification for QR usage in Sui. 18 | This article presents a standard process and data transmission protocol for offline signers to work with the watch-only wallet. 19 | 20 | ## Specification 21 | 22 | **Offline signer**: the offline signer is a device or application which holds user private keys and does not have network access. 23 | 24 | **Watch-only wallet**: the watch only wallet is the wallet which has network access and will interact with blockchain. 25 | 26 | ## Process 27 | 28 | In order to work with offline signers, the watch-only wallet should follow the following process. 29 | 30 | 1. offline signers provide public key information to watch-only wallets to generate addresses and sync balance etc via QR Code. 31 | 2. a watch-only wallet generates the unsigned data and sends it to an offline signer to sign it via QR Code. 32 | 3. an offline signer signs the data and provides a signature back to the watch-only wallet via QR Code. 33 | 4. a watch-only wallet gets the signature and constructs the signed data (transaction) and performs the following actions like broadcasting the transaction etc. 34 | 35 | ## Data transmission protocol 36 | 37 | Since one QR Code can contain a limited size of data, the animated QR Codes should be included for data transmission.The BC-UR defined by BlockchainCommons have published a series data transmission protocol called br-ur. It provides a basic method for encoding data to animated QR Code. this article will use the bc-ur and extend its current definition. all the data are encoded by CBOR and the CDDL is the data definition language for CBOR. For more info about bc-ur, please check out [here](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md). 38 | 39 | ### Setup watch-only wallet by offline signer 40 | 41 | In order to let a watch-only wallet collect information from blockchain, the offline signer should provide public keys to watch-only wallets which generate addresses from these keys and query info like balance from blockchain. 42 | 43 | In this case, offline signers will provide the public keys and derivation path. the UR Type called `crypto-hdkey` will be used to encode these data. and the derivation path will be encoded as `crypto-keypath` which defined in bc-ur. Also, a new UR type `crypto-multi-accounts` will be used if we want to import multiple accounts in one animated QR. 44 | 45 | #### CDDL for Key Path 46 | 47 | The following specification is written in Concise Data Definition Language [CDDL]. 48 | 49 | ```cddl 50 | ; Metadata for the derivation path of a key. 51 | ; 52 | ; `source-fingerprint`, if present, is the fingerprint of the 53 | ; ancestor key from which the associated key was derived. 54 | ; 55 | ; If `components` is empty, then `source-fingerprint` MUST be a fingerprint of 56 | ; a master key. 57 | ; 58 | ; `depth`, if present, represents the number of derivation steps in 59 | ; the path of the associated key, even if not present in the `components` element 60 | ; of this structure. 61 | crypto-keypath = { 62 | components: [path-component], ; If empty, source-fingerprint MUST be present 63 | ? source-fingerprint: uint32 .ne 0 ; fingerprint of ancestor key, or master key if components is empty 64 | ? depth: uint8 ; 0 if this is a public key derived directly from a master key 65 | } 66 | 67 | path-component = ( 68 | child-index / child-index-range / child-index-wildcard-range, 69 | is-hardened 70 | ) 71 | 72 | uint32 = uint .size 4 73 | uint31 = uint32 .lt 2147483648 ;0x80000000 74 | child-index = uint31 75 | child-index-range = [child-index, child-index] ; [low, high] where low < high 76 | child-index-wildcard = [] 77 | 78 | is-hardened = bool 79 | 80 | components = 1 81 | source-fingerprint = 2 82 | depth = 3 83 | ``` 84 | 85 | #### CDDL for derivation key 86 | 87 | Since the main purpose of the key is to transfer public key data. the defination of crypto-hdkey will be kept only public keys. 88 | For HD-derivation-key, which will present the key data and its derivation path. 89 | The following specification is written in Concise Data Definition Language [CDDL] and includes the crypto-keypath spec above. 90 | 91 | ```cddl 92 | ; A derived key must be public, has an optional chain code, and 93 | ; may carry additional metadata about its use and derivation. 94 | ; To maintain isomorphism with [BIP32] and allow keys to be derived from 95 | ; this key `chain-code`, `origin`, and `parent-fingerprint` must be present. 96 | ; If `origin` contains only a single derivation step and also contains `source-fingerprint`, 97 | ; then `parent-fingerprint` MUST be identical to `source-fingerprint` or may be omitted. 98 | derived-key = ( 99 | key-data: key-data-bytes, 100 | ? chain-code: chain-code-bytes, ; omit if no further keys may be derived from this key 101 | ? origin: #6.304(crypto-keypath), ; How the key was derived 102 | ? name: text, ; A short name for this key. 103 | ) 104 | ; If the `use-info` field is omitted, defaults (mainnet BTC key) are assumed. 105 | ; If `coin-type` and `origin` are both present, then per [BIP44], the second path 106 | ; component's `child-index` must match `coin-type`. 107 | 108 | key-data = 3 109 | chain-code = 4 110 | origin = 6 111 | name = 9 112 | 113 | uint8 = uint .size 1 114 | key-data-bytes = bytes .size 33 115 | chain-code-bytes = bytes .size 32 116 | ``` 117 | 118 | If the chain-code is provided, it can be used to derive child keys, and if the chain code is not provided, it is just an solo key and origin can be provided to indicate the derivation key path. 119 | 120 | #### CDDL for multiple accounts 121 | 122 | The following specification is written in Concise Data Definition Language [CDDL]. 123 | 124 | ```cddl 125 | key_exp = #6.303(crypto-hdkey) 126 | 127 | accounts = { 128 | master-fingerprint: uint32, ; Master fingerprint (fingerprint for the master public key as per BIP32) 129 | keys: [+ key_exp] ; Different auth keys for a offline signer. 130 | ? device: text ; Indicates the origin of these accounts, e.g. 'Keystone' 131 | } 132 | 133 | master-fingerprint = 1 134 | keys = 2 135 | device = 3 136 | 137 | ``` 138 | 139 | ### Sending the unsigned data from wallet-only wallet to offline signer 140 | 141 | For sending the unsigned data from a watch-only wallet to an offline signer. a new bc-ur type `sui-sign-request` will be introduced for encoding the signing request, multiple sign requests are supported. 142 | 143 | #### CDDL for Sui Sign Request 144 | 145 | The following specification is written in Concise Data Definition Language [CDDL]. 146 | UUIDs in this specification notated uuid are CBOR binary strings tagged with #6.37, per the IANA CBOR Tags Registry. 147 | 148 | ```cddl 149 | ; Metadata for the signing request for sui. 150 | ; `request-id` is the identifier for this signing request. 151 | ; `sign-data` is the transaction data to be signed. 152 | ; `sign-type` is a field used to distinguish transaction types: single-sign or multi-sign or message. 153 | ; `derivation-paths` is the path of the private keys to sign the data. For sign-type-single type, there is only one value in the list. For sign-type-multi, there is N values in the list, N is the "K-of-N multisig authentication". 154 | ; `addresses ` is the Sui address of the signing type for verification purpose which is optional. 155 | ; `origin` is the origin of this sign request. like watch-only wallet name. 156 | 157 | path_exp = #6.304(crypto-keypath) 158 | 159 | sui-sign-request = ( 160 | ?request-id: uuid, 161 | sign-data: bytes, 162 | sign-type: int. default sign-type-single, ;sign type identifier 163 | derivation-paths: [+ path_exp], ;the key paths for signing this request 164 | ?addresses: [+ bytes], 165 | ?origin: text, 166 | ) 167 | 168 | request-id = 1 169 | sign-data = 2 170 | sign-type = 3 171 | derivation-paths = 4 172 | addresses = 5 173 | origin = 6 174 | 175 | sign-type-single = 1 176 | sign-type-multi = 2 177 | sign-type-message = 3 178 | ``` 179 | 180 | ### Offline signers provide the signature to watch-only wallets 181 | 182 | After signing the data offline signer should send the signature back to the watch-only wallet. and a new bc-ur type called `sui-signature` introduced here to encode the data, multiple signatures are supported. 183 | 184 | #### CDDL for Sui Signature 185 | 186 | The following specification is written in Concise Data Definition Language [CDDL]. 187 | 188 | ```cddl 189 | ; Metadata for the signature for sui. 190 | ; `request-id` is the identifier for this signature. 191 | ; `signature ` is the signature of the transaction. 192 | ; `public-key` is the public key corresponding to the private key that signed the transaction. 193 | sui-signature = ( 194 | ?request-id: uuid, 195 | signature: bytes, 196 | ?public-key: bytes, ;In case of multiple signatures, it must be passed to indicate which signer signed the transaction. 197 | ) 198 | 199 | request-id = 1 200 | signature = 2 201 | public-key = 3 202 | ``` 203 | 204 | ## Copyright 205 | 206 | Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). 207 | 208 | ## References 209 | 210 | BC-UR 211 | -------------------------------------------------------------------------------- /research/tron-qr-data-protocol.md: -------------------------------------------------------------------------------- 1 | # Tron qr code data transmission protocol 2 | 3 | ## Abstract 4 | 5 | This is the process and data transmission standard via QR Code for offline signer to work with watch-only wallet on Tron. 6 | 7 | ## Motivation 8 | 9 | Currently, more and more users would like to use complete offline signers like hardware wallets, 10 | mobile phones on offline mode to manage their private keys. In order to sign transaction or data, 11 | these offline signers have to work with a watch-only wallet. these watch-only will prepare the data to be sign. 12 | 13 | Currently, the data transmission method between offline signers and watch-only wallet will include QR Code, usb, bluetooth and file transfer. 14 | Compare with other data transmission method like usd, bluetooth, and file transfer, the QR Code data transmission have these advantages. 15 | 16 | - Transparency and Security: Compared to usb or bluetooth, user can easily decode the data in QR Code (with the help of some tools),it can let user know what they are going to sign. this Transparency can provide more security. 17 | - Better Compatibility: Compared to usb and Bluetooth, the QR Code data transmission have better compatibility, normally it will not be break by other software change like browser upgrade. system upgrade etc. 18 | - Better User experience: The QR Code data transmission can provide much better user experience compare to usb, bluetooth and file transfer especially on the mobile environment. 19 | - Smaller attack surface. USB and Bluetooth have a higher attack surface than QR-Codes. 20 | 21 | Because of these advantages, the QR Code data transmission is a better choice. However, there is no standard specification for QR usage in Tron. 22 | This article presents a standard process and data transmission protocol for offline signers to work with the watch-only wallet. 23 | 24 | ## Specification 25 | 26 | **Offline signer**: the offline signer is a device or application which holds user private keys and does not have network access. 27 | 28 | **Watch-only wallet**: the watch only wallet is the wallet which has network access and will interact with blockchain. 29 | 30 | ## Process 31 | In order to work with offline signers, the watch-only wallet should follow the following process. 32 | 1. offline signers provide public key information to watch-only wallets to generate addresses and sync balance etc via QR Code. 33 | 2. a watch-only wallet generates the unsigned data and sends it to an offline signer to sign it via QR Code. 34 | 3. an offline signer signs the data and provides a signature back to the watch-only wallet via QR Code. 35 | 4. a watch-only wallet gets the signature and constructs the signed data (transaction) and performs the following action like broadcasting the transaction etc. 36 | 37 | ## Data transmission protocol 38 | 39 | Since one QR Code can contain a limited size of data, the animated QR Codes should be included for data transmission. 40 | The BC-UR defined by BlockchainCommons have published a series data transmission protocol called br-ur. 41 | It provides a basic method for encoding data to animated QR Code. this article will use the bc-ur and extend its current definition. 42 | all the data are encoded by CBOR and the CDDL is the data definition language for CBOR. For more info about bc-ur, 43 | please check out [here](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md). 44 | 45 | ### Sending the unsigned data from wallet-only wallet to offline signer. 46 | For sending the unsigned data from a watch-only wallet to an offline signer. a new bc-ur type `tron-sign-request` will be introduced for encoding the signing request. 47 | 48 | #### CDDL for Tron Sign Request. 49 | The following specification is written in Concise Data Definition Language [CDDL]. 50 | UUIDs in this specification notated uuid are CBOR binary strings tagged with #6.37, per the IANA CBOR Tags Registry. 51 | 52 | ``` 53 | ; Metadata for the signing request for Tron. 54 | ; `request-id` is the identifier for this signing request. 55 | ; `sign-data` is the transaction data to be signed. 56 | ; `derivation-path` is the path of the private key to sign the data 57 | ; `origin` is the origin of this sign request. like watch-only wallet name. 58 | ; `address` is the Tron address of the signing type for verification purpose which is optional 59 | 60 | tron-sign-request = ( 61 | ?request-id: uuid, 62 | sign-data: bytes, 63 | derivation-path: #5.304(crypto-keypath), ;the key path for signing this request 64 | ?origin: text, 65 | ?address: bytes 66 | ) 67 | 68 | request-id = 1 69 | sign-data = 2 70 | derivation-path = 3 71 | address = 4 72 | origin = 5 73 | ``` 74 | 75 | `sign-data` currently supports transfer, includes Tron transfer, Trc10 and Trc20 token transfer. 76 | `sign-data` is JSON string in bytes, data structure 77 | 78 | ``` 79 | { 80 | "to": string, // to address 81 | "from": string, // from address 82 | "value": string, // send amount 83 | "fee": number, // fee 84 | "contractAddress": string, // optional, token contract address for TRC20 transfer only 85 | "latestBlock": { 86 | "hash": string // latest block hash in hex 87 | "number": number, // latest block number 88 | "timestamp": number, // latest block timestamp 89 | }, 90 | "token": string, // "TRX" for coin transfer, token id for TRC10, field can be undefined for TRC20 transfer 91 | "override": { // optional 92 | "tokenShortName": string, // the short name of token 93 | "tokenFullName": string, // the full name of token 94 | "decimals": 0 // the decimals of token 95 | } 96 | } 97 | ``` 98 | 99 | TRC10 transfer example 100 | ```json 101 | { 102 | "to": "TKCsXtfKfH2d6aEaQCctybDC9uaA3MSj2h", 103 | "from": "TXhtYr8nmgiSp3dY3cSfiKBjed3zN8teHS", 104 | "value": "1", 105 | "fee": 100000, 106 | "latestBlock": { 107 | "hash": "6886a76fcae677e3543e546a43ad4e5fc6920653b56b713542e0bf64e0ff85ce", 108 | "number": 16068126, 109 | "timestamp": 1578459699000 110 | }, 111 | "token": "1001090", 112 | "override": { 113 | "tokenShortName": "TONE", 114 | "tokenFullName": "TronOne", 115 | "decimals": 18 116 | } 117 | } 118 | ``` 119 | 120 | #### Example 121 | TBD 122 | 123 | ### Offline signers provide the signature to watch-only wallets. 124 | After signing the data offline signer should send the signature back to the watch-only wallet. and a new bc-ur type called `tron-signature` introduced here to encode the data. 125 | 126 | #### CDDL for Sol Signature. 127 | The following specification is written in Concise Data Definition Language [CDDL]. 128 | 129 | ``` 130 | tron-signature = ( 131 | request-id: uuid, 132 | signature: bytes 133 | ) 134 | ``` 135 | 136 | ## Copyright 137 | Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). 138 | 139 | ## References 140 | BC-UR https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md 141 | -------------------------------------------------------------------------------- /se/Keystone_SE_Firmware_Update_Package_Verification.md: -------------------------------------------------------------------------------- 1 | # Keystone Secure Element Firmware Upgrade Package Verification 2 | 3 | ## Introduction 4 | Keystone offers a method for verifying official release upgrade packages. You can compare a version package you compiled from Github source code with the official release update package to accomplish this. 5 | 6 | We have built the shell script for the verification. you can check the file [here](https://github.com/KeystoneHQ/keystone-se-firmware/blob/bitcoin/verify.sh). Before run the sctipt, make sure the docker is installed. 7 | 8 | 9 | Refer to the below sections for instructions. 10 | 11 | ## Download official release update package 12 | - [Firmware upgrades on the official Keystone website](https://keyst.one/firmware) 13 | 14 | ## Unzip official release update package 15 | Use the public key defined in the code to unzip upgrade package update.zip 16 | 17 | [public key for all-coin version](https://github.com/KeystoneHQ/keystone-cold-app/blob/master/app/build.gradle#L112) 18 | 19 | [public key for btc-only version](https://github.com/KeystoneHQ/keystone-cold-app-btc/blob/master/app/build.gradle#L112) 20 | 21 | An upgrade package consists of the following parts: 22 | - `app_[version_code]_[version_name]_[git_commit_id]_[apk_sha1_checksum].apk` : Keystone cold upgrade version package 23 | - `manifest.json` : Upgrade package digest information 24 | - `serial_[version]_*.bin` : Keystone Secure Element upgrade version package 25 | - `signed.rsa` : Signature for upgrade package 26 | 27 | ## Download source code 28 | Download the code which is the corresponding to the official upgrade package version from Github. For example, if the official upgrade package version is `v1.5.0`, you can get the tag v1.5.0 for the commit. 29 | Run the following command to download the code: 30 | 31 | ``` 32 | git clone git@github.com:KeystoneHQ/keystone-se-firmware.git 33 | git checkout v1.5.0 34 | ``` 35 | 36 | ## Build secure element firmware 37 | Build with ARM IDEs like "Keil MDK V4.x". 38 | 1. Download Keil MDK4.x [here](https://www.keil.com/demo/eval/armv4.htm). 39 | 2. Install MDK and register license. 40 | 3. Run MDK, and add firmware project. Open the dialog `Project - Open Project`, select `mason.uvproj` in directory `keystone-se-firmware/`. 41 | 4. Build the firmware project. Select the dialog `Project - Rebuild all target files` to compile the source files. 42 | 5. Find the firmware image `mason_app.hex` and `mason_app.bin` in directory `keystone-se-firmware/`. 43 | 44 | ## Make upgrade package 45 | Run the shell script `verify.sh` from the project root folder, after execution, you can find the `unsigned_firmware_*.bin` file which is the unsigned package. 46 | 47 | The unsigned package is consist of the following parts: 48 | | Index | Part | Length | Description 49 | |:-------:|:-----------------:|:-----------------:|:----------------- 50 | 1 | Header | 128Bytes | version info and signature for verifying 51 | 2 | Body | 528Bytes*n | version package encrypted and checksum 52 | 53 | Update Package Header's length is 128 bytes. It is consist of the following parts: 54 | | Index | Item | Length | Description 55 | |:-------:|:-----------------:|:-----------------:|:----------------- 56 | 1 | ver | 4Bytes | version BCD encode 57 | 2 | ver_checksum | 4Bytes | front 4 bytes of ver sha256 58 | 3 | reserve | 24Bytes | reserve 59 | 4 | body_hash | 32Bytes | sha256 value of entire body 60 | 5 | signature | 64Bytes | signature of body_hash 61 | 62 | Update Package Body has several 528 bytes blocks. Each block is consist of the following parts: 63 | | Index | Item | Sub Item| Length | Description 64 | |:-------:|:-----------------:|:-----------------:|:-----------------:|:----------------- 65 | 1 | block_content | block_addr | 8Bytes | flash address of block (3des encrypt) 66 | 2 | block_content | block_bin | 512Bytes | package bin of block (3des encrypt) 67 | 2 | bloc_checksum | / | 8Bytes | front 8 bytes of block_content(3des encrypt) sha256 68 | 69 | ## Verify update package 70 | After compare the update package with the `serial_*.bin` unzipped from official release update package, 71 | You will find the "signature" in update Package Header is different. 72 | 73 | Beyond that, the other parts should be same. 74 | It could prove the official release update package was built by Github source code. -------------------------------------------------------------------------------- /se/Keystone_Secure_Element_Datasheet.md: -------------------------------------------------------------------------------- 1 | # Keystone Secure Element Datasheet 2 | 3 | ## 1. Abstract 4 | 5 | Low power 32-bit SoC security microcontroller, 256KB flash, 16KB SRAM, USB2.0 full speed, ISO7816, SPI, UART, I2C, PWM, TIMER, TRNG, DES/TDES, SM1, SM4, AES128/192/256, RSA4096, SM2/ECC, SM3/SHA1/256/384/512. 6 | 7 | ## 2. Features 8 | 9 | ### 2.1. Processor 10 | 11 | - 32-bit ARM Cortex-M0 12 | - Clock frequency up to 48MHz 13 | - Three-stage pipeline, Thumb/Thumb-2 instruction set 14 | - NVIC interrupt controller 15 | - SysTick timer 16 | 17 | ### 2.2. Memory 18 | 19 | - 16KB ROM 20 | - 16KB + 4KB SRAM 21 | - Capacity: 256KB 22 | - Page size: 512B 23 | - Data bit width: 32bits 24 | - Page erasing time: 2ms 25 | - Word programming time: 30us 26 | - Max number of page erasures: 100,000 times 27 | - Data retention time: 10 years 28 | 29 | ### 2.3. Timer 30 | 31 | - Three 32-bit decreasing/increasing timers 32 | - Timer 0/1 can be configured as input capture and PWM with the output compare module 33 | - 32-bit watchdog timer 34 | 35 | ### 2.4. Cryptographic Algorithms 36 | 37 | - Symmetric algorithms: DES/3DES, SM1, AES, SM4 38 | - Asymmetric algorithms: RSA, ECC Prime/Binary Field, SM2 39 | - Digest algorithms: SM3, SHA-1/256/384/512 40 | - Random number generator: HRNG (FIPS 140-2 compliant) 41 | - CRC16-CCITT verification unit 42 | 43 | ### 2.5. Peripheral Logic Circuit and Clock 44 | 45 | - Built-in 48MHz and 32KHz RC oscillator, can be connected with external 12M crystal oscillator (QFN40) 46 | - USB ports: USB2.0 full speed, 1 control port and 4 bidirectional bulk ports, supports crystal-free mode 47 | - ISO7816: supports master/slave mode, ISO7816-3 protocol, Smart Card Protocol T0/T1 48 | - SPI: two-channel SPI interface, selectable master/slave mode, supports the mode 0/1/2/3 transmission protocol, supports SPI 1/2/4 line transmission 49 | - 31 GPIO (multiplex included), supports edge/level triggered interrupt 50 | - UART: two-channel RS232 serial ports, one channel supports CTS/RTS 51 | - I2C: master/slave interface, supports standard/fast/HS three speed modes, supports 7bit device address 52 | - Battery Monitor: range 2.5-4.4V, accuracy 10mV 53 | - Comparator: comparison accuracy 10mV, hysteresis interval 10mV 54 | - Audio interface: supports MIC/GND adaption 55 | 56 | ### 2.6. Security Features 57 | 58 | - Memory protection unit (MPU) 59 | - Voltage/frequency/temperature/photosensitive detection function 60 | - Power glitch detection 61 | - External clock glitch detection 62 | - Active metal shield 63 | - Bus encryption crosstalk, memory check function 64 | - 128-bit unique chip serial number 65 | 66 | ### 2.7. Electrical Parameters 67 | 68 | - ESD protection: 4KV (HBM) 69 | - Operating voltage: 2.7V ~ 5.5V (USB requires more than 3V) 70 | - Operating temperature: -40~85°C 71 | - Power: 72 | - Typical current 5mA@48Mhz, 10mA@48Mhz (PKI ON) 73 | - StandBy current 120uA 74 | - PowerOff current 1uA (battery) 75 | 76 | ### 2.8. Package 77 | 78 | - QFN40 79 | 80 | ### 2.9. Development 81 | 82 | - ROM boot,support USB/SPI/7816 Download 83 | - JTAG-SWD debug/download interface (EVB only) 84 | - Evaluation board/release development kit 85 | - ARM Keil MDK (4.0+) 86 | 87 | ## 3. Description 88 | 89 | Keystone's Secure Element is a 32-bit security microcontroller, which is specifically targeted at low-cost and low-power fields. The Secure Element is an ARM Cortex M0 microcontroller integrated with a variety of secure cryptographic modules, including the SM1, SM2, SM3, SM4 algorithm, as well as RSA/ECC, DES/3DES, AES128, AES192/256, SHA1/256, SHA384/512 and other internationally recognized security algorithms. It supports true random number generation (TNRG). The Secure Element provides a variety of peripheral interfaces: USB2.0 full speed, SPI, UART, ISO7816, I2C, etc. built-in ROSC, and also supports crystal-free applications. 90 | 91 | Keystone's Secure Element has a 256K byte on-chip eFlash, 16K bytes of ROM, 16K bytes of on-chip SRAM, and 4K bytes of dedicated SRAM algorithm, of which on-chip ROM provides various algorithm interface programs for developers. It improves the development efficiency and optimizes system performance. 92 | 93 | ## 4. Performance 94 | 95 | | Module | algorithm | performance (System 48MHz, algorithm 48Mhz) | 96 | | --------------------------------- | ------------------------------------------- | ------------------------------------------ | 97 | | PKI | 1024-bit RSA key generation speed (CRT) | 305.9 ms | 98 | | | 2048-bit RSA key generation speed (CRT) | 2.3 s | 99 | | | 4096-bit RSA key generation speed (CRT) | 26.2 s | 100 | | | 1024-bit RSA algorithm signature speed (CRT) | 9.36 ms | 101 | | | 2048-bit RSA algorithm signature speed (CRT) | 46.6 ms | 102 | | | 4096-bit RSA algorithm signature speed (CRT) | 286.5 ms | 103 | | | 192 bit (prime field) dot multiply | 4.5 ms | 104 | | | 256 bit (prime field) dot multiply | 7.4 ms | 105 | | | 384 bit (prime field) dot multiply | 19.3 ms | 106 | | | 521 bit (prime field) dot multiply | 45.2 ms | 107 | | | 113 bit (binary field) dot multiply | 0.36 ms | 108 | | | 239 bit (binary field) dot multiply | 1.0 ms | 109 | | | 571 bit (binary field) dot multiply | 6.6 ms | 110 | | | SM2 Signature speed | 8.3 ms | 111 | | | SM2 Signature verification speed | 15.8 ms | 112 | | Symmetric cryptographic algorithm | SM1 encryption (decryption) | 32.5Mbps | 113 | | | SM4 encryption (decryption) | 32.5Mbps | 114 | | | DES encryption (decryption) | 25.6Mbps | 115 | | | AES encryption (decryption) | 30.2Mbps | 116 | 117 | ## 5. Functional Block Diagram 118 | 119 | ![Functional block diagram](./pics/datasheet/Functional_block_diagram.jpg) 120 | 121 | ## 6. Package 122 | 123 | ### 6.1. Package Pin Layout 124 | 125 | ![QFN40](./pics/datasheet/QFN40.jpg) 126 | 127 | ### 6.2. Pin Description 128 | 129 | | Pin Function | | | Package pin number | | IO Type | Reset status | | Function Description | 130 | | -------------------- | ------------- | ------------- | ------------------ | ---- | -------- | ------------ | ----- | ------------------------------------------------------------ | 131 | | Function 1 (Default) | Function 2 | Function 3 | QFN40 | TBD | | DIR | PU PD | | 132 | | DP | UARTB_TX | GPIO0 | 24 | | I/O | AZ | - |
  • USB differential signal D +
  • UARTB TX signal
  • GPIO0
  • | 133 | | DM | UARTB_RX | GPIO1 | 23 | | I/O | AZ | - |
  • USB differential signal D -
  • UARTB RX signal
  • GPIO1
  • | 134 | | GPIO2 | CCK | - | 21 | | I/O | DI | PU |
  • GPIO2
  • ISO7816MS master-slave CCK
  • | 135 | | GPIO3 | RST | - | 22 | | I/O | DI | PU |
  • GPIO3
  • ISO7816MS master-slave RST
  • | 136 | | GPIO4 | CIO | - | 6 | | I/O | DI | PU |
  • GPIO4
  • ISO7816MS master-slave CIO
  • | 137 | | GPIO5 | SPIA_SCK | - | 7 | | I/O | DI | PU |
  • GPIO5
  • SPIA clock signal
  • | 138 | | GPIO6 | SPIA_SS | - | 8 | | I/O | DI | PU |
  • GPIO6
  • chip select signal
  • | 139 | | GPIO7 | SPIA_MISO | - | 9 | | I/O | DI | PU |
  • GPIO7
  • SPIA IO1 (MISO) signal
  • | 140 | | GPIO8 | SPIA_MOSI | - | 10 | | I/O | DI | PU |
  • GPIO8
  • SPIA IO0 (MOSI) signal
  • | 141 | | GPIO9 | SPIA_IO2 | - | 11 | | I/O | DI | PU |
  • GPIO9
  • SPIA IO2 (WP) signal
  • | 142 | | GPIO10 | SPIA_IO3 | - | 12 | | I/O | DI | PU |
  • GPIO10
  • SPIA IO3 (HOLD) signal
  • | 143 | | GPIO11 | UARTA_TX | - | 13 | | I/O | DI | PU |
  • GPIO11
  • UARTA TX signal
  • | 144 | | GPIO12 | UARTA_RX | - | 14 | | I/O | DI | PU |
  • GPIO12
  • UARTA RX signal
  • | 145 | | GPIO13 | UARTA_RTS | - | 15 | | I/O | DI | PU |
  • GPIO13
  • UARTA RTS signal
  • | 146 | | GPIO14 | UARTA_CTS | - | 16 | | I/O | DI | PU |
  • GPIO14
  • UARTA CTS signal
  • | 147 | | GPIO15 | SPIB_SCK | I2C_SCL | 19 | | I/O | DI | PU |
  • GPIO15
  • SPIB clock signal
  • I2C SCL signal
  • | 148 | | GPIO16 | SPIB_SS | I2C_SDA | 20 | | I/O | DI | PU |
  • GPIO16
  • SPIB chip select signal
  • I2C SDA signal
  • | 149 | | GPIO17 | AUDIO_DM | - | 32 | | I/O | DI | PU |
  • GPIO17
  • AUDIO Comparator input DM (Automatically turn off the pull-up resistor)*1
  • | 150 | | GPIO18 | AUDIO_DP | - | 33 | | I/O | DI | PU |
  • GPIO18
  • AUDIO Comparator input DP (Automatically turn off the pull-up resistor)*1
  • | 151 | | GPIO19 | UARTB_TX | PWM0 | 34 | | I/O | DI | PU |
  • GPIO19
  • UARTB TX signal
  • Timer0 IC/PWM channel
  • | 152 | | GPIO20 | UARTB_RX | PWM1 | 35 | | I/O | DI | PU |
  • GPIO20
  • UARTB RX signal
  • Timer1 IC/PWM channel
  • | 153 | | SWDIO | GPIO21 | SPIB_MISO | 36 | | I/O | DI | PU |
  • GPIO21
  • SWDIO (only applicable to the development version, this feature is reserved for the production version)
  • SPIB IO1 (MISO) signal
  • | 154 | | SWCLK | GPIO22 | SPIB_MOSI | 37 | | I/O | DI | PU |
  • GPIO22
  • SWCLK (only applicable to the development version, this feature is reserved for the production version)
  • SPIB IO0 (MOSI) signal
  • | 155 | | CLKOUT | GPIO23 | - | 5 | | I/O | DO | PU |
  • Chip system clock output
  • GPIO23
  • | 156 | | RSTN | GPIO24 | - | 38 | | I/O | DI | PU |
  • Chip reset input
  • GPIO24 (recommended output)
  • | 157 | | REMAP | GPIO25 | AUDIO_RCV OUT | 39 | | I/O | DO | PU |
  • Chip start mode output
  • GPIO25 (supports low level Standby wakeup)
  • AUDIO_RCV comparator output
  • | 158 | | MODE | GPIO26 | - | 40 | | I/O | DI | PU |
  • Chip startup mode (resets latch, suitable for Boot programs)
  • GPIO26 (recommended output)
  • | 159 | | GPIO27 | USB_RCVO UT - | - | 1 | | I/O | DI | PU |
  • GPIO27
  • USB_RCV comparator output
  • | 160 | | RST_OUT | GPIO28 | - | 2 | | I/O | DO | PU |
  • RST_OUT
  • GPIO28
  • | 161 | | GPIO29 | M_DET | SPIB_IO2 | 3 | | I/O | DI | PU |
  • GPIO29
  • ISO7816MS main DETECT card arrival detection signal
  • SPIB_IO2 (WP) signal
  • | 162 | | GPIO30 | M_VCCEN | SPIB_IO3 | 4 | | I/O | DI | PU |
  • GPIO30 (supports low level Standby wakeup)
  • ISO7816MS VCCEN
  • SPIB_IO3 (HOLD) signal
  • | 163 | | MICA | - | - | 29 | | A | AZ | |
  • MICA signal (MIC and GND detection signals)
  • | 164 | | MICB | - | - | 30 | | A | AZ | |
  • MICB signal (MIC and GND detection signals)
  • | 165 | | WAKEUP | - | - | 31 | | A | AI | |
  • Power Down wake-up signal, up pulse wake-up
  • | 166 | | VBAT | - | - | 28 | | A | AI | |
  • Battery power detection signal input pin
  • | 167 | | VCC | - | - | 27 | | P | AP | |
  • Power input 2.7V-5.5V
  • | 168 | | VDD33 | - | - | 26 | | P | AO | |
  • Power output 3.3V (VDD33OUT and VDDIO Double Bonding)
  • | 169 | | VREF | - | - | 25 | | P | AO | |
  • Internal reference voltage, connect 1uF capacitor to GND
  • | 170 | | GND | - | - | EPA D | | G | G | |
  • Chip GND (EPAD and GND are already wired inside the chip when they are packaged)
  • | 171 | | XIN | - | - | 17 | | A | AI | |
  • External 12MHz crystal input, connect to GND when there is no external crystal
  • | 172 | | XOUT | - | - | 18 | | A | AO | |
  • External 12MHz crystal output
  • | 173 | 174 | Note: A – Analog signal; D – Digital signal; I – Input; O – Output; G – Ground; P – Power. 175 | 176 | GPIO drive capability: GPIO23, GPIO25, GPIO28 and GPIO30 are 16mA, and the remaining GPIOs are 8mA. 177 | 178 | *Switching to the RCV pull-up resistor automatically turns off and is not controlled by registers; switching back to GPIO is controlled by registers. 179 | 180 | 181 | 182 | ## 7. Electrical Parameters 183 | 184 | ### 7.1. Absolute Maximum Ratings 185 | 186 | Do not exceed these parameters during actual operation, otherwise the Secure Element will be permanently damaged. 187 | 188 | | Symbol | Description | Min | Max | Unit | 189 | | ------ | --------------------- | ---- | ---- | ---- | 190 | | Tstg | Storage Temperature | -40 | 125 | ℃ | 191 | | VCC | Power Voltage | -0.5 | 6 | V | 192 | | VDDIO | IO Voltage | -0.5 | 4.6 | V | 193 | | ESD | Max ESD Voltage (HBM) | - | 4000 | V | 194 | 195 | ### 7.2. Typical Operating Conditions 196 | 197 | | Symbol | Description | Min | Typical | Max | Unit | 198 | | ------ | ------------- | ---- | ------- | ---- | ---- | 199 | | VCC | Power Voltage | 2.7 | - | 5.5 | V | 200 | | VDDIO | IO Voltage | 2.97 | 3.3 | 3.63 | V | 201 | | Tj | Junction Temp | -40 | - | 85 | ℃ | 202 | | Ta | Ambient Temp | -40 | - | 85 | ℃ | 203 | 204 | ### 7.3. DC Parameters 205 | 206 | - IO 207 | 208 | | Symbol | Description | Min | Typical | Max | Unit | 209 | | ------ | ----------------------- | ---- | ------- | ---- | ---- | 210 | | VIH | I/O Input High Voltage | 2.0 | - | 3.63 | V | 211 | | VIL | I/O Input Low Voltage | -0.3 | - | 0.8 | V | 212 | | VHYS | Input Schmidt Window | - | 0.35 | - | V | 213 | | IL | Input Leakage Current | - | - | ±10 | uA | 214 | | VOH | I/O Output High Voltage | 2.4 | - | - | V | 215 | | VOL | I/O Output Low Voltage | - | - | 0.4 | V | 216 | | RPu | Pull-Up Resistor | 28 | 41 | 65 | KΩ | 217 | 218 | 219 | 220 | - LDO33 221 | 222 | | Symbol | Description | Conditions | Min | Typical | Max | Unit | 223 | | ------ | -------------------------------- | -------------------- | ---- | ------- | ---- | ---- | 224 | | VCC | Power Voltage | - | 3.6 | 5 | 5.5 | V | 225 | | VDD33 | Output Voltage | VCC=3.6V,ILOAD=80mA | 3.2 | 3.3 | 3.4 | V | 226 | | IMAX | Maximum Output Current | VCC=3.6V | - | - | 80 | mA | 227 | | IOCP | Overcurrent Protection Threshold | ILIM_TRIM\<1:0>=00 | - | 177 | - | mA | 228 | | | | ILIM_TRIM\<1:0>=01 | - | 203 | - | mA | 229 | | | | ILIM_TRIM\<1:0>=10 | - | 229 | - | mA | 230 | | | | ILIM_TRIM\<1:0>=11 | - | 259 | - | mA | 231 | | COUT | External Capacitor | - | - | 4.7 | - | uF | 232 | 233 | - Voltage abnormality alarm 234 | 235 | | Symbol | Description | Conditions| Min | Typical | Max | Unit | 236 | | ------- | ------------------------------------ | --------- | ---- | ------- | ---- | ---- | 237 | | VTH1_OV | High Voltage Alarm Threshold | - | - | 6 | - | V | 238 | | VHYS_OV | High Voltage Alarm Hysteresis Window | - | - | 100 | - | mV | 239 | | VTH1_UV | Low Pressure Alarm Threshold | - | - | 2.5 | - | V | 240 | | VHYS_UV | Low Voltage Alarm Hysteresis Window | - | - | 100 | - | mV | 241 | 242 | - Temperature abnormality alarm 243 | 244 | | Symbol | Description | Conditions | Min | Typical | Max | Unit | 245 | | ------ | -------------------------------- | --------- | ---- | ------- | ---- | ---- | 246 | | TDH | High Temperature Alarm Threshold | - | - | 85 | - | ℃ | 247 | | TDL | Low Temperature Alarm Threshold | - | - | -40 | - | ℃ | 248 | 249 | 250 | ## 8. Package Size 251 | - QFN40 (5mm*5mm) 252 | ![qfn40](./pics/datasheet/QFN40_size.jpg) 253 | -------------------------------------------------------------------------------- /se/pics/datasheet/Functional_block_diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/se/pics/datasheet/Functional_block_diagram.jpg -------------------------------------------------------------------------------- /se/pics/datasheet/QFN40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/se/pics/datasheet/QFN40.jpg -------------------------------------------------------------------------------- /se/pics/datasheet/QFN40_size.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/se/pics/datasheet/QFN40_size.jpg -------------------------------------------------------------------------------- /signed_41262fb9.psbt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/signed_41262fb9.psbt -------------------------------------------------------------------------------- /system-arch-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeystoneHQ/Keystone-developer-hub/397d300315ee9d8c2278c7784be007e039f052f0/system-arch-chart.png -------------------------------------------------------------------------------- /unsigned_multisig_psbt.psbt: -------------------------------------------------------------------------------- 1 | cHNidP8BAIkCAAAAAag0ySJL/fg1Y2iYTEkoKEVouLX3LCMM2xynmbkPHKHwAAAAAAD+////AugDAAAAAAAAIgAgzhhAiA7vEoKmrpUzdiO/b8OWkVecputJA8WkxfQkwIb8HgAAAAAAACIAIEPh8NNJQsJ6MTUcvB+FVtJLq8A8t8vzKZqqUpMCPH0gAAAAAE8BBDWHzwRz2FcOgAAAAqC8+tOsAUSpjPV++z6sAKb8EUabsccEopkHweMKctQXAqKKXMWVe7P6HgHLWXu/ICcfZV2F+QjRYuXwpPOQdhfYFHSMxqowAACAAQAAgAAAAIACAACATwEENYfPBI79X3aAAAACEhIkT58/sCz9y0rna/XnbOpxokKALAzHxZnhE26O0+UDfjmxDujeQ0BWl0ryfAuRwTpfnfzPArheCeG9rxXQYXUUUnHAcTAAAIABAACAAAAAgAIAAIAAAQErpyMAAAAAAAAiACCCz75du5tfHz6q+r8zHMbEkkzVzPlkcxIT6JFjoW/UvQEFR1IhAvgviufivXXMGrfyAvTOtbdw+S27ovMBRVCzl5eQLin6IQP+hE3HQFbj4SMS2Qxdw05UiYkoWmunXvVBSGVnpFSICFKuIgYC+C+K5+K9dcwat/IC9M61t3D5Lbui8wFFULOXl5AuKfocUnHAcTAAAIABAACAAAAAgAIAAIABAAAABgAAACIGA/6ETcdAVuPhIxLZDF3DTlSJiShaa6de9UFIZWekVIgIHHSMxqowAACAAQAAgAAAAIACAACAAQAAAAYAAAAAAQFHUiEDEK7ThbCKmkGgIWmJ0t6+hMzY4k3l8+80ItafSeia5owhAzQ0HXikSGOKYTlhjRBiYfcqewv3L3K7gVsqN87g55YXUq4iAgMQrtOFsIqaQaAhaYnS3r6EzNjiTeXz7zQi1p9J6JrmjBxSccBxMAAAgAEAAIAAAACAAgAAgAAAAAAFAAAAIgIDNDQdeKRIY4phOWGNEGJh9yp7C/cvcruBWyo3zuDnlhccdIzGqjAAAIABAACAAAAAgAIAAIAAAAAABQAAAAABAUdSIQKaLMRiK/7GCAUM1gHwjXOF8kQvKWYrlxtXsUU6hD9OWCECn8cBrmI/TWft6D9xCWUcyRyQf6pMae6Jyv3gvDT8BrJSriICAposxGIr/sYIBQzWAfCNc4XyRC8pZiuXG1exRTqEP05YHFJxwHEwAACAAQAAgAAAAIACAACAAQAAAAgAAAAiAgKfxwGuYj9NZ+3oP3EJZRzJHJB/qkxp7onK/eC8NPwGshx0jMaqMAAAgAEAAIAAAACAAgAAgAEAAAAIAAAAAA== -------------------------------------------------------------------------------- /unsigned_single_sig_psbt.psbt: -------------------------------------------------------------------------------- 1 | cHNidP8BAHECAAAAAf0sAIHsVtROz2izomXxGYDqfg4x8iXS8ENjHeWhHvDkAQAAAAD+////AuqMRQAAAAAAFgAU2DypGzMQypoH7oAQX2qJvqxNVJ3cBQAAAAAAABYAFHAvM1n6aWzDzJDNiRh5o1pmo5ciAAAAAAABAR9Uk0UAAAAAABYAFBWfq0EMde9L+nZETUEaABX9CZMCIgYCQ3OHOSUpNTxPk4Cegg2XESI2DC04m0pkRCFJybiFdx4YUnHAcVQAAIABAACAAAAAgAEAAAABAAAAACICAo579onSnie9oA8oLQqxoRYW82KV3OQh5m+DG0wagnBKGFJxwHFUAACAAQAAgAAAAIABAAAABwAAAAAiAgKRmfAXA3on95A3NPFek62hv+CWIF/Pp2nEYyShkH8fdhhSccBxVAAAgAEAAIAAAACAAAAAAAEAAAAA --------------------------------------------------------------------------------