aboutsummaryrefslogtreecommitdiff
path: root/content/posts/2023-09-05-c11-sha3.md
blob: f38013293074c4f492fc3bdec6b6dd50b29a8394 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
---
slug: c11-sha3
title: "C11 Sha3"
date: "2023-09-05T02:25:14-04:00"
---
This weekend I put together a [C11][] implementation of the following
[SHA-3][] algorithms from [FIPS 202][] and [SP 800-185][800-185]:

* SHA3-224
* SHA3-256
* SHA3-384
* SHA3-512
* HMAC-SHA3-224
* HMAC-SHA3-256
* HMAC-SHA3-384
* HMAC-SHA3-512
* SHAKE128 and SHAKE128-XOF
* SHAKE256 and SHAKE256-XOF
* cSHAKE128 and cSHAKE128-XOF
* cSHAKE256 and cSHAKE256-XOF
* KMAC128 and KMAC128-XOF
* KMAC256 and KMAC256-XOF
* TupleHash128 and TupleHash128-XOF
* TupleHash256 and TupleHash256-XOF
* ParallelHash128 and ParallelHash128-XOF
* ParallelHash256 and ParallelHash256-XOF

The code is available in the [Git repository][repo].

## Features

* [MIT licensed][mit]
* Standard [C11][] with no external dependencies.
* No allocations.
* Easy to embed; drop `sha3.h` and `sha3.c` into your application.
* Full Doxygen-friendly API documentation.
* Full test suite based on test vectors from the [NIST CSRC Examples
  with Intermediate Values][csrc-examples] page.

## Example

```c
// example.c: print hex-encode sha3-256 hash of each command-line argument
//
// build:
//   cc -o example -std=c11 -O3 -W -Wall -Wextra -Werror -pedantic -march=native -mtune=native example.c sha3.c
#include <stdint.h> // uint8_t
#include <stdio.h> // printf()
#include <string.h> // strlen()
#include "sha3.h" // sha3_256()

// print hex-encoded buffer to stdout.
static void print_hex(const uint8_t * const buf, const size_t len) {
  for (size_t i = 0; i < len; i++) {
    printf("%02x", buf[i]);
  }
}

int main(int argc, char *argv[]) {
  // loop over command-line arguments
  for (int i = 1; i < argc; i++) {
    // hash argument
    uint8_t buf[32] = { 0 };
    sha3_256((uint8_t*) argv[i], strlen(argv[i]), buf);

    // print argument and hex-encoded hash
    printf("\"%s\",", argv[i]);
    print_hex(buf, sizeof(buf));
    fputs("\n", stdout);
  }

  // return success
  return 0;
}
```

Output:

```sh
> ./example asdf foo bar
"asdf",dd2781f4c51bccdbe23e4d398b8a82261f585c278dbb4b84989fea70e76723a9
"foo",76d3bc41c9f588f7fcd0d5bf4718f8f84b1c41b20882703100b9eb9413807c01
"bar",cceefd7e0545bcf8b6d19f3b5750c8a3ee8350418877bc6fb12e32de28137355
```

[C11]: https://en.wikipedia.org/wiki/C11_(C_standard_revision)
  "ISO/IEC 9899:2011"
[SHA-3]: https://en.wikipedia.org/wiki/SHA-3
  "Secure Hash Algorithm 3"
[FIPS 202]: https://csrc.nist.gov/pubs/fips/202/final
  "SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions"
[800-185]: https://csrc.nist.gov/pubs/sp/800/185/final
  "SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash, and ParallelHash"
[repo]: https://github.com/pablotron/sha3
  "sha3 github repository"
[mit]: https://opensource.org/license/mit-0/
  "MIT No Attribution License"
[csrc-examples]: https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
  "NIST CSRC: Cryptographic Standards and Guidelines: Examples with Intermediate Values"