forked from cryptape/ckb-auth
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add tests for secp256r1 fix secp256r1 test create separated auth programs remove lazy static remove verbose outputs, add more comments add docs for secp256r1
- Loading branch information
Showing
12 changed files
with
590 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#ifndef _CBK_ERRORS_H_ | ||
#define _CBK_ERRORS_H_ | ||
enum AuthErrorCodeType { | ||
ERROR_NOT_IMPLEMENTED = 100, | ||
ERROR_MISMATCHED, | ||
ERROR_INVALID_ARG, | ||
ERROR_WRONG_STATE, | ||
// spawn | ||
ERROR_SPAWN_INVALID_LENGTH, | ||
ERROR_SPAWN_SIGN_TOO_LONG, | ||
ERROR_SPAWN_INVALID_ALGORITHM_ID, | ||
ERROR_SPAWN_INVALID_SIG, | ||
ERROR_SPAWN_INVALID_MSG, | ||
ERROR_SPAWN_INVALID_PUBKEY, | ||
// schnorr | ||
ERROR_SCHNORR, | ||
}; | ||
#endif // _CBK_ERRORS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#include <stdio.h> | ||
|
||
#include "errors.h" | ||
|
||
#include "lib_ecc_types.h" | ||
#include "libec.h" | ||
#include "libsig.h" | ||
|
||
#define SECP256R1_SIGNATURE_SIZE 64 | ||
#define SECP256R1_PUBKEY_SIZE 64 | ||
#define SECP256R1_DATA_SIZE (SECP256R1_SIGNATURE_SIZE + SECP256R1_PUBKEY_SIZE) | ||
|
||
static const char *ec_name = "SECP256R1"; | ||
static const char *ec_sig_name = "ECDSA"; | ||
static const char *hash_algorithm = "SHA256"; | ||
|
||
const uint32_t projective_buffer_size = 96; | ||
const uint32_t affine_buffer_size = 64; | ||
|
||
int get_random(unsigned char *buf, u16 len) { | ||
for (int i = 0; i < len; i++) { | ||
buf[i] = 0; | ||
} | ||
return 0; | ||
} | ||
|
||
static int string_to_params(const char *ec_name, const char *ec_sig_name, | ||
ec_sig_alg_type *sig_type, | ||
const ec_str_params **ec_str_p, | ||
const char *hash_name, hash_alg_type *hash_type) { | ||
const ec_str_params *curve_params; | ||
const ec_sig_mapping *sm; | ||
const hash_mapping *hm; | ||
uint32_t curve_name_len; | ||
|
||
if (sig_type != NULL) { | ||
sm = get_sig_by_name(ec_sig_name); | ||
if (!sm) { | ||
return ERROR_INVALID_ARG; | ||
} | ||
*sig_type = sm->type; | ||
} | ||
|
||
if (ec_str_p != NULL) { | ||
curve_name_len = local_strlen((const char *)ec_name) + 1; | ||
if (curve_name_len > 255) { | ||
return ERROR_INVALID_ARG; | ||
} | ||
curve_params = ec_get_curve_params_by_name((const uint8_t *)ec_name, | ||
(uint8_t)curve_name_len); | ||
if (!curve_params) { | ||
return ERROR_INVALID_ARG; | ||
} | ||
*ec_str_p = curve_params; | ||
} | ||
|
||
if (hash_type != NULL) { | ||
hm = get_hash_by_name(hash_name); | ||
if (!hm) { | ||
return ERROR_INVALID_ARG; | ||
} | ||
*hash_type = hm->type; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
void convert_aff_buf_to_prj_buf(const uint8_t *aff_buf, uint32_t aff_buf_len, | ||
uint8_t *prj_buf, uint32_t prj_buf_len) { | ||
static const uint8_t z_buf[] = { | ||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; | ||
MUST_HAVE(aff_buf_len == affine_buffer_size); | ||
MUST_HAVE(prj_buf_len == projective_buffer_size); | ||
memcpy(prj_buf, aff_buf, aff_buf_len); | ||
memcpy(prj_buf + aff_buf_len, z_buf, sizeof(z_buf)); | ||
} | ||
|
||
int secp256r1_verify_signature(const uint8_t *sig, uint8_t siglen, | ||
const uint8_t *pk, uint32_t pklen, | ||
const uint8_t *m, uint32_t mlen) { | ||
const ec_str_params *ec_str_p; | ||
ec_sig_alg_type sig_type; | ||
hash_alg_type hash_type; | ||
ec_pub_key pub_key; | ||
ec_params params; | ||
int ret; | ||
|
||
uint8_t pj_pk_buf[projective_buffer_size]; | ||
convert_aff_buf_to_prj_buf(pk, pklen, pj_pk_buf, sizeof(pj_pk_buf)); | ||
|
||
MUST_HAVE(ec_name != NULL); | ||
|
||
ret = string_to_params(ec_name, ec_sig_name, &sig_type, &ec_str_p, | ||
hash_algorithm, &hash_type); | ||
if (ret) { | ||
return ERROR_INVALID_ARG; | ||
} | ||
import_params(¶ms, ec_str_p); | ||
|
||
ret = ec_pub_key_import_from_buf(&pub_key, ¶ms, pj_pk_buf, | ||
sizeof(pj_pk_buf), sig_type); | ||
if (ret) { | ||
return ERROR_INVALID_ARG; | ||
} | ||
|
||
ret = ec_verify(sig, siglen, &pub_key, m, mlen, sig_type, hash_type); | ||
if (ret) { | ||
return ERROR_SPAWN_INVALID_SIG; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# ckb-auth secp256r1 interoperability | ||
Ckb-auth library is able to verify ECDSA signatures | ||
A simple way to use litecoin signature algorithm to lock ckb cells | ||
is to sign the transaction hash (or maybe `sighash_all`, i.e. hashing all fields | ||
including transaction hash and other witnesses in this input group) | ||
with `litecoin-cli`, and then leverage ckb-auth to check the validity of this signature. | ||
See [the docs](./auth.md) for more details. | ||
|
||
# Generate signature with openssl | ||
|
||
## Install openssl | ||
Openssl is available from most operating systems. Refer to your favorite package manager to install it. | ||
|
||
## Creating or importing secp256r1 private key | ||
You may follow the instructions here to import your existing secp256r1 private key. | ||
Or you can generate a new one with | ||
``` | ||
openssl ecparam -name prime256v1 -genkey -noout -out private.pem | ||
``` | ||
|
||
|
||
## Obtaining the public key hash | ||
We can create a public key file (`public.pem`) corresponding to the private key file (`private.pem`) with the command | ||
``` | ||
openssl ec -in private.pem -pubout -out public.pem | ||
``` | ||
|
||
To show the detailed information about this public key. We can run | ||
``` | ||
openssl ec -text -inform PEM -in public.pem -pubin | ||
``` | ||
|
||
Below is a sample output | ||
|
||
``` | ||
read EC key | ||
Public-Key: (256 bit) | ||
pub: | ||
04:1c:cb:e9:1c:07:5f:c7:f4:f0:33:bf:a2:48:db: | ||
8f:cc:d3:56:5d:e9:4b:bf:b1:2f:3c:59:ff:46:c2: | ||
71:bf:83:ce:40:14:c6:88:11:f9:a2:1a:1f:db:2c: | ||
0e:61:13:e0:6d:b7:ca:93:b7:40:4e:78:dc:7c:cd: | ||
5c:a8:9a:4c:a9 | ||
ASN1 OID: prime256v1 | ||
NIST CURVE: P-256 | ||
writing EC key | ||
-----BEGIN PUBLIC KEY----- | ||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHMvpHAdfx/TwM7+iSNuPzNNWXelL | ||
v7EvPFn/RsJxv4POQBTGiBH5ohof2ywOYRPgbbfKk7dATnjcfM1cqJpMqQ== | ||
-----END PUBLIC KEY----- | ||
``` | ||
|
||
Here the binary string `04:1c:...:a9` is a binary representation of the public key, where `04` represents uncompressed public key, | ||
i.e. both x and y coordinates are given in the following binary string. | ||
And the public key hash is the blake2b 256 hash of the binary string excluding the first byte `04`. | ||
That is the pubkey hash is just the blake2b 256 hash of `1ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9`. | ||
|
||
## Sign the message | ||
To sign the message with hex `29553f9e37fa16e45f1d3e616ac5366f6afd9936477f2d6fc870f49bdf540157`, we can run | ||
|
||
``` | ||
xxd -r -p <<< 29553f9e37fa16e45f1d3e616ac5366f6afd9936477f2d6fc870f49bdf540157 > message | ||
``` | ||
to save this message into file `message` and then run | ||
|
||
``` | ||
openssl dgst -sha256 -sign private.pem message > signature | ||
``` | ||
to save the signature into file `signature` | ||
|
||
The final signature field of the ckb transaction should be this signature concatenated with the above public key. |
Oops, something went wrong.