Skip to content

Latest commit

 

History

History
197 lines (190 loc) · 11.9 KB

README.org

File metadata and controls

197 lines (190 loc) · 11.9 KB

sr25519-donna

This is a pure C implementation of polkadot’s key derivation and signing algorithm schnorrkel. The goal is to fully compatible with the original rust version. The curve operations are based on ed25519-donna. https://github.com/w3f/Grants-Program/blob/master/static/img/Grants_Program.png?raw=true

Compilation

Default Options

git clone [email protected]:TerenceGe/sr25519-donna.git
cd sr25519-donna
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=. && make install # The options "-DCMAKE_INSTALL_PREFIX=." will install library in the build folder, you can change the location if you want.

Random Options

This library uses a build-in random number generator by default. To use a custom random function, add -DSR25519_CUSTOMRANDOM=true for cmake

cmake .. -DSR25519_CUSTOMRANDOM=true

put your custom random implementation in sr25519-randombytes-custom.h. The random function must implement:

void sr25519_randombytes(void *p, size_t len);

Hash Options

This library uses a build-in sha2 hash function by default. To use a custom hash function, add -DSR25519_CUSTOMHASH=true for cmake

cmake .. -DSR25519_CUSTOMRANDOM=true

put your custom random implementation in sr25519-hash-custom.h. The random function must implement:

struct sr25519_hash_context;

void sr25519_hash_init(sr25519_hash_context *ctx);
void sr25519_hash_update(sr25519_hash_context *ctx, const uint8_t *in, size_t inlen);
void sr25519_hash_final(sr25519_hash_context *ctx, uint8_t *hash);
void sr25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);

Curve Operation Options

This library supports both 32bit and 64bit curve operations, the default is according to your machine. Add -DSR25519_FORCE_32BIT to force the use of 32 bit routines even when compiling for 64 bit.

cmake .. -DSR25519_FORCE_32BIT=true

Test

./sr25519DonnaTests

Integration

include_directories(../build/include/) # replace it with your sr25519-donna installed location if required
link_directories(../build/lib/) # replace it with your sr25519-donna installed location if required

add_executable(yourApp ${SOURCE_FILES})
target_link_libraries(yourApp libsr25519_donna.dylib) # replace it with libsr25519_donna_static.a if you want to use static lib.

example

Usage

include

#include "sr25519-donna.h"

sr25519 types

typedef uint8_t sr25519_mini_secret_key[32];
typedef uint8_t sr25519_secret_key[64];
typedef uint8_t sr25519_secret_key_key[32];
typedef uint8_t sr25519_secret_key_nonce[32];
typedef uint8_t sr25519_chain_code[32];
typedef uint8_t sr25519_public_key[32];
typedef uint8_t sr25519_keypair[96];
typedef uint8_t sr25519_signature[64];
typedef uint8_t sr25519_vrf_output[32];
typedef uint8_t sr25519_vrf_io[64];
typedef uint8_t sr25519_vrf_proof[64];
typedef uint8_t sr25519_vrf_out_and_proof[96];
typedef uint8_t sr25519_vrf_proof_batchable[96];
typedef uint8_t sr25519_vrf_raw_output[16];
typedef uint8_t sr25519_vrf_threshold[16];

create keypair from seed

paramdescription
keypairthe output ed25519 compatible keypair, 96 bytes long
seedthe input mini secret key, 32 bytes long
void sr25519_keypair_from_seed(sr25519_keypair keypair, const sr25519_mini_secret_key seed);

example

sign message

paramdescription
signaturethe signature ouput, 64 bytes long
public_keythe public key of the keypair to sign the message, 32 bytes long
message and message_lengthmessage arrary and length
void sr25519_sign(sr25519_signature signature, const sr25519_public_key public_key, const sr25519_secret_key secret, const uint8_t *message, unsigned long message_length);

example

verify message

paramdescription
signaturethe signature bytes to verify, 64 bytes long
message and message_lengthmessage arrary and length
public_keythe corresponding public key that signing the message, 32 bytes long
bool sr25519_verify(const sr25519_signature signature, const uint8_t *message, unsigned long message_length, const sr25519_public_key public_key);

example

soft derive keypair

paramdescription
derivedthe derived keypair, 96 bytes long
keypairthe input keypair, 96 bytes long
chain_codethe input chain code, 32 bytes long
void sr25519_derive_keypair_soft(sr25519_keypair derived, const sr25519_keypair keypair, const sr25519_chain_code chain_code);

example

soft derive public key

paramdescription
derived_publicthe derived public key, 32 bytes long
public_keythe input public key, 32 bytes long
chain_codethe input chain code, 32 bytes long
void sr25519_derive_public_soft(sr25519_public_key derived_public, const sr25519_public_key public_key, const sr25519_chain_code chain_code);

example

hard derive keypair

paramdescription
derivedthe derived keypair, 96 bytes long
keypairthe input keypair, 96 bytes long
chain_codethe input chain code, 32 bytes long
void sr25519_derive_keypair_hard(sr25519_keypair derived, const sr25519_keypair keypair, const sr25519_chain_code chain_code);

example

random number generator

void sr25519_randombytes(void *p, size_t len);

vrf sign

paramdescription
out_and_proofoutput combination of vrf output (32 bytes long) and vrf proof (64 bytes long)
keypairkeypair for signing, it should be an uniform keypair instead of ed25519 compatible, you can generated by sr25519_uniform_keypair_from_seed or converted by sr25519_keypair_ed25519_to_uniform
message and message_lengthmessage arrary and length
thresholdthe vrf threshold, 16 bytes long, if the raw output bytes is less than threshold, the is_less field of result strcut will be true
VrfResult sr25519_vrf_sign_if_less(sr25519_vrf_out_and_proof out_and_proof, const sr25519_keypair keypair, const uint8_t *message, unsigned long message_length, const sr25519_vrf_threshold limit);

example

vrf verify

paramdescription
public_keythe corresponding public key that signing the message
message and message_lengthmessage arrary and length
outputthe signature for the message
proofthe proof of the signature
thresholdthe vrf threshold, 16 bytes long, if the raw output bytes is less than threshold, the is_less field of result structure will be true. If errors, is_less field of the returned structure is not meant to contain a valid value
VrfResult sr25519_vrf_verify(const sr25519_public_key public_key, const uint8_t *message, unsigned long message_length, const sr25519_vrf_output output, const sr25519_vrf_proof proof, const sr25519_vrf_threshold threshold);

example

vrf result

The vrf result contains signature result and is_less:

resultthe result of the signature currently compatible with the c-binding repo (https://github.com/Warchant/sr25519-crust/blob/2947abb8367d57cd712e8bc80687d224ccd86ccf/src/lib.rs#L31)
is_lessindicate whether the raw output bytes is less than the threshold
typedef enum Sr25519SignatureResult {
    Ok,
    EquationFalse,
    PointDecompressionError,
    ScalarFormatError,
    BytesLengthError,
    NotMarkedSchnorrkel,
    MuSigAbsent,
    MuSigInconsistent,
} Sr25519SignatureResult;

typedef struct VrfResult {
    Sr25519SignatureResult result;
    bool is_less;
} VrfResult;

vrf keypair

By default, the sr25519_keypair_from_seed functon creates keypair that contains half ed25519 bytes (which is compatible with the wasm crypto lib), vrf requires the keypair is uniform. In this case, you can use sr25519_uniform_keypair_from_seed for keypair creating or sr25519_keypair_ed25519_to_uniform for converting.

paramdescription
keypairthe output uniform keypair, 96 bytes long
seedthe input mini secret key, 32 bytes long
void sr25519_uniform_keypair_from_seed(sr25519_keypair keypair, const sr25519_mini_secret_key seed);
paramdescription
uniform_keypairthe output uniform keypair, 96 bytes long
ed25519_keypairthe ed25519 compatible keypair, 96 bytes long
void sr25519_keypair_ed25519_to_uniform(sr25519_keypair uniform_keypair, const sr25519_keypair ed25519_keypair);

example

Author

Terence Ge

License

Apache License