90 lines
3.8 KiB
C
90 lines
3.8 KiB
C
#ifndef __FSTOKEN_H__
|
|
#define __FSTOKEN_H__
|
|
#include "blst/blst.h"
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
// only used for debugging
|
|
#include <stdio.h>
|
|
#include "debugprint.h"
|
|
|
|
// Note: In constrained environments where the IDBITS and HASHBITS values of the tokens in use are known, such as in fsp, these can be set exactly.
|
|
// However, that may render some structs (such as the request descriptor) incompatible if moved to an environment where this is nonstandard.
|
|
#define IDBITS_DEFAULT 128
|
|
#define IDBITS_MAX 256
|
|
#define HASHBITS_DEFAULT 256
|
|
#define HASHBITS_MAX 256
|
|
|
|
#define IDBYTES_MAX (IDBITS_MAX + 7) / 8
|
|
#define HASHBYTES_MAX (HASHBITS_MAX + 7) / 8
|
|
|
|
#define FSTOKEN_DST ((byte*) "MY-DST")
|
|
|
|
// For efficiency's sake, structs intended for use with the FemtoStar Protocol must be strictly-aligned without padding, with little-endian byte ordering.
|
|
// This avoids wasting network capacity on padding, and avoids the performance impact of reordering on most modern platforms (most importantly x86 and RISC-V)
|
|
// while ensuring compatibility with strict-alignment architectures. Take note: This is NOT typical network-order!
|
|
|
|
// Additionally, note that most structs do not explicitly include what target they are for (even the target descriptor!). Tracking what is for what target is
|
|
// not a core part of fstoken, and is the responsibility of the software using fstoken (e.g. ctm or an implementation of fsp). This keeps tokens light in
|
|
// situations where which target is relevant is unambiguous (e.g. in the session setup with a satellite, where the satellite is always the same target).
|
|
|
|
// A target_descriptor is a stored description of a target, which can be used to request, verify, and sometimes sign tokens for it.
|
|
typedef struct{
|
|
#pragma scalar_storage_order little-endian
|
|
|
|
uint8_t target_descriptor_version;
|
|
bool sk_available;
|
|
uint16_t idbits;
|
|
uint16_t hashbits;
|
|
byte sk[32];
|
|
byte pk[96];
|
|
} fstoken_target_descriptor;
|
|
|
|
// A request descriptor is a structure held privately by the requester until they receive a signature for their request - it is then used to generate a token
|
|
typedef struct{
|
|
#pragma scalar_storage_order little-endian
|
|
|
|
byte blinding_factor[32];
|
|
byte token_id[IDBYTES_MAX];
|
|
} fstoken_request_descriptor;
|
|
|
|
// A request is a structure sent by the requester to the signer, to be signed and a signature returned. It need not be kept private.
|
|
typedef struct{
|
|
#pragma scalar_storage_order little-endian
|
|
|
|
byte id_blind[48];
|
|
} fstoken_request;
|
|
|
|
// I'm unsure if these "single-item structs" make any sense - signatures in blst are independent of system or scalar_storage_order endianness anyway
|
|
typedef struct{
|
|
#pragma scalar_storage_order little-endian
|
|
|
|
byte signature[48];
|
|
} fstoken_signature;
|
|
|
|
typedef struct{
|
|
#pragma scalar_storage_order little-endian
|
|
|
|
byte signature[48];
|
|
byte token_id[IDBYTES_MAX];
|
|
} fstoken_token;
|
|
|
|
typedef struct{
|
|
#pragma scalar_storage_order little-endian
|
|
|
|
byte hash[HASHBYTES_MAX];
|
|
byte token_id[IDBYTES_MAX];
|
|
} fstoken_short_token;
|
|
|
|
void fstoken_keygen(byte* ikm, byte* sk_byte, byte* pk_byte);
|
|
void fstoken_get_pk_from_sk(byte* sk_byte, byte* pk_byte);
|
|
void bit_truncated_copy(byte* src, byte* dest, size_t destlen, int bits);
|
|
void fstoken_gen_request(fstoken_request* req, fstoken_request_descriptor* reqdesc, fstoken_target_descriptor* target, byte* token_id, byte* blinding_factor);
|
|
int fstoken_sign_request(fstoken_request* req, fstoken_signature* sig, fstoken_target_descriptor* targ);
|
|
int fstoken_gen_token(fstoken_request_descriptor* req, fstoken_signature* sig, fstoken_token* token);
|
|
int fstoken_verify_token(fstoken_token* token, fstoken_target_descriptor* targ);
|
|
int fstoken_shorten_token(fstoken_token* token, fstoken_short_token short_token);
|
|
int fstoken_target_token_length(fstoken_target_descriptor* target);
|
|
|
|
#endif |