Longfellow ZK 0290cb32
Loading...
Searching...
No Matches
sha3_circuit.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_CIRCUITS_SHA3_SHA3_CIRCUIT_H_
16#define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_SHA3_SHA3_CIRCUIT_H_
17
18// arithmetized sha3 using logic bitvectors
19#include <stddef.h>
20
21#include <cstdint>
22
23#include "circuits/sha3/sha3_round_constants.h"
24
25namespace proofs {
26template <class LogicCircuit>
27class Sha3Circuit {
28 typedef typename LogicCircuit::template bitvec<64> v64;
29
30 const LogicCircuit& lc_;
31
32 v64 of_scalar(uint64_t x) const { return lc_.template vbit<64>(x); }
33
34 public:
35 explicit Sha3Circuit(const LogicCircuit& lc) : lc_(lc) {}
36
37 void keccak_f_1600(v64 A[5][5]) {
38 for (size_t round = 0; round < 24; ++round) {
39 // FIPS 202 3.2.1, theta
40 v64 C[5];
41 for (size_t x = 0; x < 5; ++x) {
42 auto a01 = lc_.vxor(&A[x][0], A[x][1]);
43 auto a23 = lc_.vxor(&A[x][2], A[x][3]);
44 C[x] = lc_.vxor(&a01, lc_.vxor(&a23, A[x][4]));
45 }
46
47 for (size_t x = 0; x < 5; ++x) {
48 v64 D_x = lc_.vxor(&C[(x + 4) % 5], lc_.vrotl(C[(x + 1) % 5], 1));
49 for (size_t y = 0; y < 5; ++y) {
50 A[x][y] = lc_.vxor(&A[x][y], D_x);
51 }
52 }
53
54 // FIPS 202 3.2.2, rho
55 {
56 size_t x = 1, y = 0;
57 for (size_t t = 0; t < 24; ++t) {
58 A[x][y] = lc_.vrotl(A[x][y], sha3_rotc[t]);
59 size_t nx = y, ny = (2 * x + 3 * y) % 5;
60 x = nx;
61 y = ny;
62 }
63 }
64
65 // FIPS 202 3.2.3, pi
66 v64 A1[5][5];
67 for (size_t x = 0; x < 5; ++x) {
68 for (size_t y = 0; y < 5; ++y) {
69 A1[x][y] = A[(x + 3 * y) % 5][x];
70 }
71 }
72
73 // FIPS 202 3.2.4, chi
74 for (size_t x = 0; x < 5; ++x) {
75 for (size_t y = 0; y < 5; ++y) {
76 A[x][y] = lc_.vxor(&A1[x][y], lc_.vand(&A1[(x + 2) % 5][y],
77 lc_.vnot(A1[(x + 1) % 5][y])));
78 }
79 }
80
81 // FIPS 202 3.2.5, iota
82 A[0][0] = lc_.vxor(&A[0][0], of_scalar(sha3_rc[round]));
83 }
84 }
85};
86
87} // namespace proofs
88
89#endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_SHA3_SHA3_CIRCUIT_H_