-
Notifications
You must be signed in to change notification settings - Fork 12
/
EnumOps.hpp
118 lines (100 loc) · 3.24 KB
/
EnumOps.hpp
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#ifndef _SNARKFRONT_ENUM_OPS_HPP_
#define _SNARKFRONT_ENUM_OPS_HPP_
#include <cstdint>
#include <cryptl/BitwiseINT.hpp>
#include <snarklib/FpModel.hpp>
namespace snarkfront {
// logical and arithmetic
enum class LogicalOps { AND, OR, XOR, SAME, CMPLMNT };
enum class ScalarOps { ADD, SUB, MUL };
enum class FieldOps { ADD, SUB, MUL, INV };
enum class BitwiseOps { AND, OR, XOR, SAME, CMPLMNT,
ADDMOD, MULMOD,
SHL, SHR, ROTL, ROTR };
// comparison
enum class EqualityCmp { EQ, NEQ };
enum class ScalarCmp { EQ, NEQ, LT, LE, GT, GE };
// number of operator input arguments
template <typename ENUM_OPS> std::size_t opArgc(const ENUM_OPS op);
// returns true for shift and rotate
bool isPermute(const BitwiseOps op);
// EQ --> SAME
// NEQ --> XOR
LogicalOps eqToLogical(const EqualityCmp op);
LogicalOps eqToLogical(const ScalarCmp op);
// evaluate logical operations
template <typename T>
T evalOp(const LogicalOps op, const T& x, const T& y)
{
switch (op) {
case (LogicalOps::AND) : return x && y;
case (LogicalOps::OR) : return x || y;
case (LogicalOps::XOR) : return x != y;
case (LogicalOps::SAME) : return x == y;
case (LogicalOps::CMPLMNT) : return ! x;
}
}
// evaluate scalar arithmetic operations
template <typename T>
T evalOp(const ScalarOps op, const T& x, const T& y)
{
switch (op) {
case (ScalarOps::ADD) : return x + y;
case (ScalarOps::SUB) : return x - y;
case (ScalarOps::MUL) : return x * y;
}
}
// evaluate finite scalar field arithmetic operations
template <typename T>
T evalOp(const FieldOps op, const T& x, const T& y)
{
switch (op) {
case (FieldOps::ADD) : return x + y;
case (FieldOps::SUB) : return x - y;
case (FieldOps::MUL) : return x * y;
case (FieldOps::INV) : return snarklib::inverse(x);
}
}
// evaluate bitwise word operations
template <typename T>
T evalOp(const BitwiseOps op, const T& x, const T& y)
{
typedef cryptl::BitwiseINT<T> B;
switch (op) {
case (BitwiseOps::AND) : return B::AND(x, y);
case (BitwiseOps::OR) : return B::OR(x, y);
case (BitwiseOps::XOR) : return B::XOR(x, y);
case (BitwiseOps::SAME) : return B::CMPLMNT(B::XOR(x, y));
case (BitwiseOps::CMPLMNT) : return B::CMPLMNT(x);
case (BitwiseOps::ADDMOD) : return B::ADDMOD(x, y);
case (BitwiseOps::MULMOD) : return B::MULMOD(x, y);
case (BitwiseOps::SHL) : return B::SHL(x, y);
case (BitwiseOps::SHR) : return B::SHR(x, y);
case (BitwiseOps::ROTL) : return B::ROTL(x, y);
case (BitwiseOps::ROTR) : return B::ROTR(x, y);
}
}
// evaluate equality comparison operations
template <typename T>
bool evalOp(const EqualityCmp op, const T& x, const T& y)
{
switch (op) {
case (EqualityCmp::EQ) : return x == y;
case (EqualityCmp::NEQ) : return x != y;
}
}
// evaluate scalar comparsion operations
template <typename T>
bool evalOp(const ScalarCmp op, const T& x, const T& y)
{
switch (op) {
case (ScalarCmp::EQ) : return x == y;
case (ScalarCmp::NEQ) : return x != y;
case (ScalarCmp::LT) : return x < y;
case (ScalarCmp::LE) : return (x < y) || (x == y);
case (ScalarCmp::GT) : return y < x;
case (ScalarCmp::GE) : return (y < x) || (x == y);
}
}
} // namespace snarkfront
#endif