Longfellow ZK 0290cb32
Loading...
Searching...
No Matches
crypto.h
1// Copyright 2025 Google LLC.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef PRIVACY_PROOFS_ZK_LIB_UTIL_CRYPTO_H_
16#define PRIVACY_PROOFS_ZK_LIB_UTIL_CRYPTO_H_
17
18// Encapsulates all of the cryptographic primitives used by this library.
19// Specifically, for the collision-resistant hash function, this library uses
20// SHA256. For a pseudo-random function, this library uses AES in ECB mode.
21// Finally, this library provides a method to generate random bytes using the
22// openssl library.
23
24#include <cstddef>
25#include <cstdint>
26#include <cstring>
27
28#include "util/panic.h"
29#include "openssl/sha.h"
30#include "openssl/evp.h"
31#include "openssl/aes.h"
32
33namespace proofs {
34
35constexpr size_t kSHA256DigestSize = 32;
36constexpr size_t kPRFKeySize = 32;
37constexpr size_t kPRFInputSize = 16;
38constexpr size_t kPRFOutputSize = 16;
39
40class SHA256 {
41 public:
42 SHA256() { SHA256_Init(&sha_); }
43
44 // Disable copy for good measure.
45 SHA256(const SHA256&) = delete;
46 SHA256& operator=(const SHA256&) = delete;
47
48 void Update(const uint8_t bytes[/*n*/], size_t n) { SHA256_Update(&sha_, bytes, n); }
49 void DigestData(uint8_t digest[/* kSHA256DigestSize */]) {
50 SHA256_Final(digest, &sha_);
51 }
52 void CopyState(const SHA256& src) { sha_ = src.sha_; }
53
54 void Update8(uint64_t x) {
55 uint8_t buf[8];
56 for (size_t i = 0; i < 8; ++i) {
57 buf[i] = x & 0xff;
58 x >>= 8;
59 }
60 Update(buf, 8);
61 }
62
63 private:
64 SHA256_CTX sha_;
65};
66
67// A pseudo-random function interface. This implementation uses AES in ECB mode.
68// The caller must ensure that arguments are not reused.
69class PRF {
70 public:
71 explicit PRF(const uint8_t key[/*kPRFKeySize*/]) {
72 ctx_ = EVP_CIPHER_CTX_new();
73 int ret =
74 EVP_EncryptInit_ex(ctx_, EVP_aes_256_ecb(), nullptr, key, nullptr);
75 check(ret == 1, "EVP_EncryptInit_ex failed");
76 }
77
78 ~PRF() { EVP_CIPHER_CTX_free(ctx_); }
79
80 // Disable copy for good measure.
81 PRF(const PRF&) = delete;
82 PRF& operator=(const PRF&) = delete;
83
84 // Evaluate the PRF on the input and write the output to the output buffer.
85 // This method should only be used internally by the Transcript class. The
86 // caller must ensure that the input and output buffers are different.
87 // This function implements a permutation, but we only need to exploit its
88 // pseudo-random function property in this application.
89 void Eval(uint8_t out[/*kPRFOutputSize*/], uint8_t in[/*kPRFInputSize*/]) {
90 int out_len = static_cast<int>(kPRFOutputSize);
91 int ret = EVP_EncryptUpdate(ctx_, out, &out_len, in,
92 static_cast<int>(kPRFInputSize));
93 check(ret == 1, "EVP_EncryptUpdate failed");
94 }
95
96 private:
97 EVP_CIPHER_CTX* ctx_;
98};
99
100// Generate n random bytes, following the openssl API convention.
101// This method will panic if the openssl library fails.
102void rand_bytes(uint8_t out[/*n*/], size_t n);
103
104void hex_to_str(char out[/* 2*n + 1*/], const uint8_t in[/*n*/], size_t n);
105
106} // namespace proofs
107
108#endif // PRIVACY_PROOFS_ZK_LIB_UTIL_CRYPTO_H_