minisig.h (3292B)
1 #ifndef KIT_DIST_MINISIG_H 2 #define KIT_DIST_MINISIG_H 3 4 #include <kit/core.h> 5 #include <stddef.h> 6 #include <stdint.h> 7 8 #include "dist.h" 9 10 /* minisign key and signature files, using minisign's exact on-disk byte 11 * layout: 12 * - public key : base64( "Ed" || keyid[8] || pk[32] ) 13 * - signature : base64( "ED" || keyid[8] || sig[64] ) over stock 14 * minisign's 64-byte prehash, plus a global signature over 15 * the trusted comment 16 * - secret key : base64( "Ed" || kdf_alg[2] || "B2" || salt[32] || 17 * opslimit[8] || memlimit[8] || keyid[8] || sk[64] || 18 * chk[32] ), passwordless (kdf_alg = {0,0}, no scrypt). 19 * 20 * These files are interchangeable with stock `minisign`: a passwordless 21 * minisign key/sig can be pointed at directly. Password-encrypted secret keys 22 * (kdf_alg = "Sc") are recognized and rejected with a clear error until scrypt 23 * is vendored. See doc/DISTRIBUTE.md. */ 24 25 /* parse_seckey return codes beyond DIST_OK/DIST_ERR. */ 26 #define DIST_ENCRYPTED 2 /* kdf_alg = "Sc": needs scrypt (not yet vendored) */ 27 28 #define DIST_TRUSTED_COMMENT_MAX 512u 29 #define DIST_UNTRUSTED_COMMENT_MAX 512u 30 31 typedef struct DistKeypair { 32 uint8_t pk[DIST_ED25519_PK_LEN]; 33 uint8_t sk[DIST_ED25519_SK_LEN]; 34 uint8_t keyid[DIST_KEYID_LEN]; 35 } DistKeypair; 36 37 /* Build a keypair from a 32-byte seed and a (random) 8-byte key id. Both are 38 * supplied by the caller from the host CSPRNG; this layer sources no entropy. 39 * The key id is stored in the key files (minisign-style), not derived. */ 40 void dist_minisig_keygen(DistKeypair* out, 41 const uint8_t seed[DIST_ED25519_SEED_LEN], 42 const uint8_t keyid[DIST_KEYID_LEN]); 43 44 int dist_minisig_emit_pubkey(KitWriter* out, const DistKeypair* kp); 45 int dist_minisig_emit_seckey(KitWriter* out, const DistKeypair* kp); 46 47 int dist_minisig_parse_pubkey(const uint8_t* data, size_t len, 48 uint8_t pk[DIST_ED25519_PK_LEN], 49 uint8_t keyid[DIST_KEYID_LEN]); 50 int dist_minisig_parse_seckey(const uint8_t* data, size_t len, 51 uint8_t sk[DIST_ED25519_SK_LEN], 52 uint8_t keyid[DIST_KEYID_LEN]); 53 54 /* Write a detached signature over `msg` to `out`. The trusted comment is 55 * signed (covered by the global signature); the untrusted comment is not. */ 56 int dist_minisig_sign(KitWriter* out, const uint8_t* msg, size_t msglen, 57 const uint8_t sk[DIST_ED25519_SK_LEN], 58 const uint8_t keyid[DIST_KEYID_LEN], 59 const char* untrusted_comment, 60 const char* trusted_comment); 61 62 /* Extract the signing key id from a signature file (to pick a trusted key). */ 63 int dist_minisig_sig_keyid(const uint8_t* sig, size_t siglen, 64 uint8_t out_keyid[DIST_KEYID_LEN]); 65 66 /* Verify a detached signature file over `msg` against `pk`. On success returns 67 * DIST_OK and copies the (signed) trusted comment into `out_trusted`. */ 68 int dist_minisig_verify(const uint8_t* sig, size_t siglen, const uint8_t* msg, 69 size_t msglen, const uint8_t pk[DIST_ED25519_PK_LEN], 70 char* out_trusted, size_t trusted_cap); 71 72 #endif