Guide: How to Use Auth Library
It is a common task to write signature validation procedures in almost every lock script. Here we introduce a new library called auth
to complete this task.
Basic Information
The followings are PR and corresponding RFC:
PR: https://github.com/nervosnetwork/ckb-production-scripts/pull/37
RFC: https://github.com/XuJiandong/docs-bank/blob/master/auth.md
Quick Start
We have provided a demo example illustrating how to use this library. Here are some basic steps of usage.
Step 1, include necessary header files.
#include "ckb_auth.h"
// and some other library, e.g. #include "blake2b.h"
Step 2, Construct a CkbEntryType
and an auth
variables.
CkbEntryType entry;
// code_hash can be hard-coded
entry.code_hash[0] = 0xAA;
entry.code_hash[1] = 0xBB;
// ...
entry.code_hash[31] = 0xFF;
entry.hash_type = 1; // type. possible value: 0(data), 1(type), 2(data1)
entry.entry_category = 0; // via exec. possible value: 0(exec), 1(dynamic linking)
CkbAuthType auth;
auth.algorithm_id = 1; // AuthAlgorithmIdEthereum
memcpy(auth.content, pubkey_hash, 20); // copy pubkey hash
The code above is to construct an entry with Ethereum style signature via exec. The hash_type
of auth
library is 1 (type) and code_hash is 0xAABB ....FF
. Since auth
library is deployed beforehand, the hash_type
and code_hash
can be hard-coded.
Step 3, validate the signature using entry
and auth
variables provided above.
uint8_t msg32[32];
generate_sighash_all(msg32, 32);
return ckb_auth(&entry, &auth, lock_bytes_seg.ptr, lock_bytes_seg.size,
msg32);
The msg32
can be calculated from generate_sighash_all, a common convention in the CKB ecosystem. The 20-byte public key hash is provided by lock_bytes_seg
. That’s all. The returned code of ckb_auth
is the signature validation result.
It is possible to use Rust in the host script. Developers need to implement the function ckb_auth
in Rust by themself.
Parameters Explained
The cell location is denoted by entry.code_hash
and entry.hash_type
. It is strongly recommended to set hash_type
to 1(type) or 2(data1). Don’t set it to 0(data) which will force the script to run in old ckb-vm before hard-fork. See more from the source code.
The entry.entry_category
can be 0(exec) or 1(dynamic linking). Here is some information about exec and dynamic linking. It is strongly recommended to use exec. The disadvantage of dynamic linking:
- Not secure enough
When a shared library is called from the host script, any code in the shared library can change any state in the host script.
- Taint memory
When a shared library is loaded into memory, the target memory can’t be re-used again: no writing is allowed anymore and the memory is tainted. The reason is that ckb-vm adopts W^X memory protection for security.
The disadvantage of exec:
- Not convenience
The invoked script can’t call functions in the host script. This is allowed in dynamic linking.
The Benefit of Using Auth Library
Since the auth
library is deployed separately, the code size for the host script will be reduced significantly. For example, a normal lock script with secp256k1 signature validation can take around 100K bytes. The auth_demo
which contains some functionality only takes 16K bytes. We can save a lot of money (CKBytes) to deploy scripts.
Normally it’s very difficult to optimize a cryptography algorithm library. With auth
library as a standalone library, developers don’t need to care about how to optimize the library.
Deployment on Testnet
An implementation of auth library above has been deployed to Pudge testnet:
parameter | value |
---|---|
code_hash | 0xacce61a57538c073759e1f05f9cbcaa650f40a8eb6493c422ff017bda9803152 |
hash_type | type |
tx_hash | 0x0bd64e4efa6dd19ac41b8e6d5b5754ce357fef1a99ab4a8319225cf50b8d6399 |
index | 0x0 |
dep_type | code |
It can be viewed on CKB explorer.
The reproducible build is supported to verify the deploy script. To build the deployed the script above, one can use the following steps:
$ git clone https://github.com/nervosnetwork/ckb-production-scripts
$ cd ckb-production-scripts
$ git checkout 9785769ded9404985531925d66043320af71adbf
$ git submodule update --init --recursive
$ make all-via-docker