kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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