# The Sigsum C library

The Sigsum C library (libsigsum) supports offline verification of
Sigsum proofs, and related operations. Sigsum is a minimal
transparency log that provides key usage transparency, which is also a
useful building block for additional transparency applications. See
[sigsum.org][] for more information.

[sigsum.org]: https://www.sigsum.org/

## Installing the library

Prerequisites include autoconf, GNU make, the GNU Nettle library, and
the testsuite also needs the `jq` tool.

You will most likely build the library from a git checkout. In this
case, the first build step is to run `autoreconf` to generate the
configure script. Next, the library can be built using `./configure &&
make && make check && make install`. If you prefer to have a separate
build directory, create an empty directory and invoke the configure
script from there. This is particularly useful if you want to build
several different configurations of the library.

To get a list of configure options, run `./configure --help`. The
options include:

| Option              |                                      |
|---------------------|--------------------------------------|
| `--prefix`          | Specify install location             |
| `--disable-shared`  | Don't build shared library           |
| `--disable-static`  | Don't build static library           |
| `--disable-parsers` | Exclude all text parsing functions   |
| `--host`            | Specify target for cross compilation |

### Linking

To link with the installed library, use `-lsigsum`, or use `pkg-config
... sigsum` to query for appropriate flags (in some cases, explicit
linking with dependency libraries like `-lsigsum -lhogweed -lnettle
-lgmp` is required).

## Library reference

This section briefly describes all library functions and features.
Please refer to corresponding header files for details on function
prototypes and struct contents.

### General conventions

For memory allocation, only the text parsing functions allocate
storage on the heap, using `malloc`. Some functions take a scratch
parameter, when they need temporary storage of varying size, depending
on the complexity of the input policy. There's then a corresponding
itch function that returns the amount of needed scratch.

Functions return true for success, e.g., a valid proof, and false on
failure. Some functions have an additional error pointer argument; if
the function fails and the error pointer is non-NULL, it is used to
return a statically allocated error message, to aid trouble shooting.

### Public keys

The [<sigsum/key-map.h>][] header file defines the types `struct
sigsum_key_with_hash` and `struct sigsum_key_map`, used to represent
known public keys, to be indexed by key hash.

A `struct sigsum_key_map` includes a pointer to a list of `struct
sigsum_key_with_hash`, which must be lexicographically sorted by key
hash. To lookup a public key by hash, use the utility function
`sigsum_key_map_lookup`.

To read a public key file with one or more Ed25519 public keys in
OpenSSH format, use the function `sigsum_key_map_parse_ssh`. This
allocates storage for the parsed keys and corresponding hashes. Call
`sigsum_key_map_clear`to deallocate when done.

[<sigsum/key-map.h>]: ../lib/key-map.h

### Sigsum policy

Functions and types defining a Sigsum policy are declared in the
header file [<sigsum/policy.h>][]. A policy is represented as a
`struct sigsum_policy`, including pointers to the public keys and key
hashes of configured logs and witnesses, and a compiled quorum.

The public keys must be sorted by key hash, and the quorum is
represented using [quorum bytecode][].

To process a [Sigsum policy file][], use the function
`sigsum_policy_parse`. This allocates storage for the processed
representation. Call `sigsum_policy_clear` to deallocate storage when
done.

To apply a policy to a cosigned tree head, call
`sigsum_policy_verify_tree_head`. This function returns true if the
tree head is properly signed by one of the logs specified in the
policy, and cosigned by a valid quorum of witnesses. This function
needs some scratch space, depending on the complexity of the policy.
This must be allocated by the caller, and the amount of scratch space
needed is returned by the `sigsum_policy_verify_tree_head_itch`.

[<sigsum/policy.h>]: ../lib/policy.h
[quorum bytecode]: ./quorum-bytecode.md
[Sigsum policy file]: https://git.glasklar.is/sigsum/core/sigsum-go/-/blob/main/doc/policy.md

### Sigsum proof

Functions and types defining a Sigsum proof are declared in the header
file [<sigsum/proof.h>][]. A proof is represented as a `struct
sigsum_proof`, including key hashes, (co)signatures, and an inclusion
proof. See [Sigsum proof][] for the verification procedure and the
text representation.

To process a [Sigsum proof][] file, use the function `sigsum_proof_parse`.
This allocates storage for the processed representation. Call
`sigsum_proof_clear` to deallocate storage when done.

To verify a Sigsum proof, use the function `sigsum_proof_verify`. This
function returns true if the proof is valid. The inputs to this
function includes:

* The Sigsum proof to be verified.
* The logged message (32 octets, often a hash of a larger artifact).
  Note that the `checksum` that is stored in the log is the hash of
  this message, i.e., typically a double hash of the artifact.
* The authorized submitter keys and their hashes, as a `struct
  sigsum_key_map` (see above).
* A Sigsum policy, specifying log and witness keys and the quorum.

The verification process includes a call to
`sigsum_policy_verify_tree_head`, which needs scratch space. This
scratch must be provided by the caller of `sigsum_proof_verify`.

[<sigsum/proof.h>]: ../lib/proof.h
[Sigsum proof]: https://git.glasklar.is/sigsum/core/sigsum-go/-/blob/main/doc/sigsum-proof.md

### Lower-level utilities

The [<sigsum/ascii.h>][] header file declares the `struct
sigsum_error` type used to report parsing errors. It also declares
utility functions to parse ascii representation of Sigsum types:
`sigsum_decode_hex_key`, `sigsum_decode_hex_hash`,
`sigsum_decode_hex_signature`, and `sigsum_decode_decimal`.

The [<sigsum/crypto.h>][] header file defines types `sigsum_size_t`,
`struct sigsum_hash`, `struct sigsum_pubkey`, `struct
sigsum_signature`, and `struct sigsum_cosignature`. These are used as
building blocks for the top-level types and functions. This header
also declares the utility function: `sigsum_hash_key`.

The [<sigsum/merkle.h>][] header file defines the type `struct
sigsum_tree_head`, and merkle tree functions `sigsum_verify_inclusion`
and `sigsum_verify_consistency`.

[<sigsum/ascii.h>]: ../lib/ascii.h
[<sigsum/crypto.h>]: ../lib/crypto.h
[<sigsum/merkle.h>]: ../lib/merkle.h

## Embedded usage

For embedded applications, one may want to work with some suitable
binary serialization of policies and proofs. The text formats can be
parsed and serialized on a "normal" computer, and deserialized on the
device that will use the policy to verify proofs. That way, the device
need not know the text representation, and the device library can be
configured with `--disable-parsers`.
