Coverage Report

Created: 2025-04-24 07:09

/src/cryptofuzz/modules/constantine/module.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "module.h"
2
#include <cryptofuzz/util.h>
3
#include <cryptofuzz/crypto.h>
4
#include <boost/multiprecision/cpp_int.hpp>
5
6
extern "C" {
7
    #include <constantine_harness.h>
8
}
9
extern "C" {
10
    //#include "cryptofuzz.h"
11
}
12
13
namespace cryptofuzz {
14
namespace module {
15
16
Constantine::Constantine(void) :
17
4
    Module("Constantine") {
18
4
    NimMain();
19
4
}
20
21
namespace Constantine_detail {
22
567
    static std::vector<uint8_t> Pad(Datasource& ds, const std::vector<uint8_t> v) {
23
567
        return v;
24
567
    }
25
    template <size_t N = 32>
26
138k
    static std::optional<std::array<uint8_t, N>> LoadField(const component::Bignum& bn) {
27
138k
        (void)bn;
28
138k
        std::optional<std::array<uint8_t, N>> ret = std::nullopt;
29
138k
        std::array<uint8_t, N> r;
30
31
138k
        std::optional<std::vector<uint8_t>> bytes;
32
138k
        CF_CHECK_NE(bytes = util::DecToBin(bn.ToTrimmedString(), N), std::nullopt);
33
137k
        memcpy(r.data(), bytes->data(), N);
34
137k
        ret = r;
35
138k
end:
36
138k
        return ret;
37
137k
    }
module.cpp:std::__1::optional<std::__1::array<unsigned char, 32ul> > cryptofuzz::module::Constantine_detail::LoadField<32ul>(cryptofuzz::Bignum const&)
Line
Count
Source
26
11.6k
    static std::optional<std::array<uint8_t, N>> LoadField(const component::Bignum& bn) {
27
11.6k
        (void)bn;
28
11.6k
        std::optional<std::array<uint8_t, N>> ret = std::nullopt;
29
11.6k
        std::array<uint8_t, N> r;
30
31
11.6k
        std::optional<std::vector<uint8_t>> bytes;
32
11.6k
        CF_CHECK_NE(bytes = util::DecToBin(bn.ToTrimmedString(), N), std::nullopt);
33
11.4k
        memcpy(r.data(), bytes->data(), N);
34
11.4k
        ret = r;
35
11.6k
end:
36
11.6k
        return ret;
37
11.4k
    }
module.cpp:std::__1::optional<std::__1::array<unsigned char, 48ul> > cryptofuzz::module::Constantine_detail::LoadField<48ul>(cryptofuzz::Bignum const&)
Line
Count
Source
26
127k
    static std::optional<std::array<uint8_t, N>> LoadField(const component::Bignum& bn) {
27
127k
        (void)bn;
28
127k
        std::optional<std::array<uint8_t, N>> ret = std::nullopt;
29
127k
        std::array<uint8_t, N> r;
30
31
127k
        std::optional<std::vector<uint8_t>> bytes;
32
127k
        CF_CHECK_NE(bytes = util::DecToBin(bn.ToTrimmedString(), N), std::nullopt);
33
126k
        memcpy(r.data(), bytes->data(), N);
34
126k
        ret = r;
35
127k
end:
36
127k
        return ret;
37
126k
    }
38
    template <size_t N = 32>
39
14.7k
    static std::optional<std::array<uint8_t, N*2>> LoadG1(const component::G1& g1) {
40
14.7k
        std::optional<std::array<uint8_t, N*2>> ret = std::nullopt;
41
14.7k
        std::array<uint8_t, N*2> r;
42
43
14.7k
        std::optional<std::array<uint8_t, N>> x_bytes, y_bytes;
44
14.7k
        CF_CHECK_NE(x_bytes = LoadField<N>(g1.first.ToTrimmedString()), std::nullopt);
45
14.5k
        CF_CHECK_NE(y_bytes = LoadField<N>(g1.second.ToTrimmedString()), std::nullopt);
46
14.4k
        memcpy(r.data(), x_bytes->data(), N);
47
14.4k
        memcpy(r.data() + N, y_bytes->data(), N);
48
14.4k
        ret = r;
49
14.7k
end:
50
14.7k
        return ret;
51
14.4k
    }
Unexecuted instantiation: module.cpp:std::__1::optional<std::__1::array<unsigned char, (32ul)*(2)> > cryptofuzz::module::Constantine_detail::LoadG1<32ul>(cryptofuzz::component::BignumPair const&)
module.cpp:std::__1::optional<std::__1::array<unsigned char, (48ul)*(2)> > cryptofuzz::module::Constantine_detail::LoadG1<48ul>(cryptofuzz::component::BignumPair const&)
Line
Count
Source
39
14.7k
    static std::optional<std::array<uint8_t, N*2>> LoadG1(const component::G1& g1) {
40
14.7k
        std::optional<std::array<uint8_t, N*2>> ret = std::nullopt;
41
14.7k
        std::array<uint8_t, N*2> r;
42
43
14.7k
        std::optional<std::array<uint8_t, N>> x_bytes, y_bytes;
44
14.7k
        CF_CHECK_NE(x_bytes = LoadField<N>(g1.first.ToTrimmedString()), std::nullopt);
45
14.5k
        CF_CHECK_NE(y_bytes = LoadField<N>(g1.second.ToTrimmedString()), std::nullopt);
46
14.4k
        memcpy(r.data(), x_bytes->data(), N);
47
14.4k
        memcpy(r.data() + N, y_bytes->data(), N);
48
14.4k
        ret = r;
49
14.7k
end:
50
14.7k
        return ret;
51
14.4k
    }
52
53
    template <size_t N = 32>
54
19.5k
    static std::optional<std::array<uint8_t, N * 4>> LoadG2(const component::G2& g2) {
55
19.5k
        std::optional<std::array<uint8_t, N * 4>> ret = std::nullopt;
56
19.5k
        std::array<uint8_t, N * 4> r;
57
58
19.5k
        std::optional<std::array<uint8_t, N>> v_bytes, w_bytes, x_bytes, y_bytes;
59
19.5k
        CF_CHECK_NE(v_bytes = LoadField<N>(g2.first.first.ToTrimmedString()), std::nullopt);
60
19.4k
        CF_CHECK_NE(w_bytes = LoadField<N>(g2.first.second.ToTrimmedString()), std::nullopt);
61
19.4k
        CF_CHECK_NE(x_bytes = LoadField<N>(g2.second.first.ToTrimmedString()), std::nullopt);
62
19.3k
        CF_CHECK_NE(y_bytes = LoadField<N>(g2.second.second.ToTrimmedString()), std::nullopt);
63
19.2k
        memcpy(r.data(), v_bytes->data(), N);
64
19.2k
        memcpy(r.data() + N, w_bytes->data(), N);
65
19.2k
        memcpy(r.data() + (N * 2), x_bytes->data(), N);
66
19.2k
        memcpy(r.data() + (N * 3), y_bytes->data(), N);
67
19.2k
        ret = r;
68
19.5k
end:
69
19.5k
        return ret;
70
19.2k
    }
module.cpp:std::__1::optional<std::__1::array<unsigned char, (32ul)*(4)> > cryptofuzz::module::Constantine_detail::LoadG2<32ul>(cryptofuzz::component::G2 const&)
Line
Count
Source
54
33
    static std::optional<std::array<uint8_t, N * 4>> LoadG2(const component::G2& g2) {
55
33
        std::optional<std::array<uint8_t, N * 4>> ret = std::nullopt;
56
33
        std::array<uint8_t, N * 4> r;
57
58
33
        std::optional<std::array<uint8_t, N>> v_bytes, w_bytes, x_bytes, y_bytes;
59
33
        CF_CHECK_NE(v_bytes = LoadField<N>(g2.first.first.ToTrimmedString()), std::nullopt);
60
29
        CF_CHECK_NE(w_bytes = LoadField<N>(g2.first.second.ToTrimmedString()), std::nullopt);
61
27
        CF_CHECK_NE(x_bytes = LoadField<N>(g2.second.first.ToTrimmedString()), std::nullopt);
62
25
        CF_CHECK_NE(y_bytes = LoadField<N>(g2.second.second.ToTrimmedString()), std::nullopt);
63
24
        memcpy(r.data(), v_bytes->data(), N);
64
24
        memcpy(r.data() + N, w_bytes->data(), N);
65
24
        memcpy(r.data() + (N * 2), x_bytes->data(), N);
66
24
        memcpy(r.data() + (N * 3), y_bytes->data(), N);
67
24
        ret = r;
68
33
end:
69
33
        return ret;
70
24
    }
module.cpp:std::__1::optional<std::__1::array<unsigned char, (48ul)*(4)> > cryptofuzz::module::Constantine_detail::LoadG2<48ul>(cryptofuzz::component::G2 const&)
Line
Count
Source
54
19.5k
    static std::optional<std::array<uint8_t, N * 4>> LoadG2(const component::G2& g2) {
55
19.5k
        std::optional<std::array<uint8_t, N * 4>> ret = std::nullopt;
56
19.5k
        std::array<uint8_t, N * 4> r;
57
58
19.5k
        std::optional<std::array<uint8_t, N>> v_bytes, w_bytes, x_bytes, y_bytes;
59
19.5k
        CF_CHECK_NE(v_bytes = LoadField<N>(g2.first.first.ToTrimmedString()), std::nullopt);
60
19.4k
        CF_CHECK_NE(w_bytes = LoadField<N>(g2.first.second.ToTrimmedString()), std::nullopt);
61
19.3k
        CF_CHECK_NE(x_bytes = LoadField<N>(g2.second.first.ToTrimmedString()), std::nullopt);
62
19.2k
        CF_CHECK_NE(y_bytes = LoadField<N>(g2.second.second.ToTrimmedString()), std::nullopt);
63
19.2k
        memcpy(r.data(), v_bytes->data(), N);
64
19.2k
        memcpy(r.data() + N, w_bytes->data(), N);
65
19.2k
        memcpy(r.data() + (N * 2), x_bytes->data(), N);
66
19.2k
        memcpy(r.data() + (N * 3), y_bytes->data(), N);
67
19.2k
        ret = r;
68
19.5k
end:
69
19.5k
        return ret;
70
19.2k
    }
71
72
73
    template <size_t N = 32>
74
6.58k
    static component::G1 SaveG1(const std::array<uint8_t, N*2>& g1) {
75
6.58k
        const auto p = g1.data();
76
6.58k
        return component::G1{
77
6.58k
            util::BinToDec(p, N),
78
6.58k
            util::BinToDec(p + N, N),
79
6.58k
        };
80
6.58k
    }
Unexecuted instantiation: module.cpp:cryptofuzz::component::BignumPair cryptofuzz::module::Constantine_detail::SaveG1<32ul>(std::__1::array<unsigned char, (32ul)*(2)> const&)
module.cpp:cryptofuzz::component::BignumPair cryptofuzz::module::Constantine_detail::SaveG1<48ul>(std::__1::array<unsigned char, (48ul)*(2)> const&)
Line
Count
Source
74
6.58k
    static component::G1 SaveG1(const std::array<uint8_t, N*2>& g1) {
75
6.58k
        const auto p = g1.data();
76
6.58k
        return component::G1{
77
6.58k
            util::BinToDec(p, N),
78
6.58k
            util::BinToDec(p + N, N),
79
6.58k
        };
80
6.58k
    }
81
82
    template <size_t N = 32>
83
2.47k
    static component::G2 SaveG2(const std::array<uint8_t, N*4>& g2) {
84
2.47k
        const auto p = g2.data();
85
2.47k
        return component::G2{
86
2.47k
            util::BinToDec(p , N),
87
2.47k
            util::BinToDec(p + N, N),
88
2.47k
            util::BinToDec(p + (N * 2), N),
89
2.47k
            util::BinToDec(p + (N * 3), N),
90
2.47k
        };
91
2.47k
    }
Unexecuted instantiation: module.cpp:cryptofuzz::component::G2 cryptofuzz::module::Constantine_detail::SaveG2<32ul>(std::__1::array<unsigned char, (32ul)*(4)> const&)
module.cpp:cryptofuzz::component::G2 cryptofuzz::module::Constantine_detail::SaveG2<48ul>(std::__1::array<unsigned char, (48ul)*(4)> const&)
Line
Count
Source
83
2.47k
    static component::G2 SaveG2(const std::array<uint8_t, N*4>& g2) {
84
2.47k
        const auto p = g2.data();
85
2.47k
        return component::G2{
86
2.47k
            util::BinToDec(p , N),
87
2.47k
            util::BinToDec(p + N, N),
88
2.47k
            util::BinToDec(p + (N * 2), N),
89
2.47k
            util::BinToDec(p + (N * 3), N),
90
2.47k
        };
91
2.47k
    }
92
93
    template <size_t N = 32>
94
584
    static component::Fp12 SaveFp12(const std::array<uint8_t, N * 12>& fp12) {
95
584
        const auto p = fp12.data();
96
584
        return component::Fp12{
97
584
            util::BinToDec(p + (0 * N), N),
98
584
            util::BinToDec(p + (1 * N), N),
99
584
            util::BinToDec(p + (2 * N), N),
100
584
            util::BinToDec(p + (3 * N), N),
101
584
            util::BinToDec(p + (4 * N), N),
102
584
            util::BinToDec(p + (5 * N), N),
103
#if 0
104
            std::string("0"),
105
            std::string("0"),
106
            std::string("0"),
107
            std::string("0"),
108
            std::string("0"),
109
            std::string("0"),
110
#else
111
584
            util::BinToDec(p + (6 * N), N),
112
584
            util::BinToDec(p + (7 * N), N),
113
584
            util::BinToDec(p + (8 * N), N),
114
584
            util::BinToDec(p + (9 * N), N),
115
584
            util::BinToDec(p + (10 * N), N),
116
584
            util::BinToDec(p + (11 * N), N),
117
584
#endif
118
584
        };
119
584
    }
Unexecuted instantiation: module.cpp:cryptofuzz::component::Fp12 cryptofuzz::module::Constantine_detail::SaveFp12<32ul>(std::__1::array<unsigned char, (32ul)*(12)> const&)
module.cpp:cryptofuzz::component::Fp12 cryptofuzz::module::Constantine_detail::SaveFp12<48ul>(std::__1::array<unsigned char, (48ul)*(12)> const&)
Line
Count
Source
94
584
    static component::Fp12 SaveFp12(const std::array<uint8_t, N * 12>& fp12) {
95
584
        const auto p = fp12.data();
96
584
        return component::Fp12{
97
584
            util::BinToDec(p + (0 * N), N),
98
584
            util::BinToDec(p + (1 * N), N),
99
584
            util::BinToDec(p + (2 * N), N),
100
584
            util::BinToDec(p + (3 * N), N),
101
584
            util::BinToDec(p + (4 * N), N),
102
584
            util::BinToDec(p + (5 * N), N),
103
#if 0
104
            std::string("0"),
105
            std::string("0"),
106
            std::string("0"),
107
            std::string("0"),
108
            std::string("0"),
109
            std::string("0"),
110
#else
111
584
            util::BinToDec(p + (6 * N), N),
112
584
            util::BinToDec(p + (7 * N), N),
113
584
            util::BinToDec(p + (8 * N), N),
114
584
            util::BinToDec(p + (9 * N), N),
115
584
            util::BinToDec(p + (10 * N), N),
116
584
            util::BinToDec(p + (11 * N), N),
117
584
#endif
118
584
        };
119
584
    }
120
121
    template <size_t N = 32>
122
1.33k
    static std::optional<std::array<uint8_t, N * 12>> LoadFp12(const component::Fp12& fp12) {
123
1.33k
        std::optional<std::array<uint8_t, N * 12>> ret = std::nullopt;
124
1.33k
        std::array<uint8_t, N * 12> r;
125
126
1.33k
        std::optional<std::array<uint8_t, N>> bytes;
127
128
1.33k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn1.ToTrimmedString()), std::nullopt);
129
1.31k
        memcpy(r.data() + (0 * N), bytes->data(), bytes->size());
130
131
1.31k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn2.ToTrimmedString()), std::nullopt);
132
1.30k
        memcpy(r.data() + (1 * N), bytes->data(), bytes->size());
133
134
1.30k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn3.ToTrimmedString()), std::nullopt);
135
1.28k
        memcpy(r.data() + (2 * N), bytes->data(), bytes->size());
136
137
1.28k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn4.ToTrimmedString()), std::nullopt);
138
1.26k
        memcpy(r.data() + (3 * N), bytes->data(), bytes->size());
139
140
1.26k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn5.ToTrimmedString()), std::nullopt);
141
1.24k
        memcpy(r.data() + (4 * N), bytes->data(), bytes->size());
142
143
1.24k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn6.ToTrimmedString()), std::nullopt);
144
1.22k
        memcpy(r.data() + (5 * N), bytes->data(), bytes->size());
145
146
1.22k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn7.ToTrimmedString()), std::nullopt);
147
1.20k
        memcpy(r.data() + (6 * N), bytes->data(), bytes->size());
148
149
1.20k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn8.ToTrimmedString()), std::nullopt);
150
1.18k
        memcpy(r.data() + (7 * N), bytes->data(), bytes->size());
151
152
1.18k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn9.ToTrimmedString()), std::nullopt);
153
1.17k
        memcpy(r.data() + (8 * N), bytes->data(), bytes->size());
154
155
1.17k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn10.ToTrimmedString()), std::nullopt);
156
1.15k
        memcpy(r.data() + (9 * N), bytes->data(), bytes->size());
157
158
1.15k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn11.ToTrimmedString()), std::nullopt);
159
1.13k
        memcpy(r.data() + (10 * N), bytes->data(), bytes->size());
160
161
1.13k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn12.ToTrimmedString()), std::nullopt);
162
1.11k
        memcpy(r.data() + (11 * N), bytes->data(), bytes->size());
163
164
1.11k
        ret = r;
165
1.33k
end:
166
1.33k
        return ret;
167
1.11k
    }
Unexecuted instantiation: module.cpp:std::__1::optional<std::__1::array<unsigned char, (32ul)*(12)> > cryptofuzz::module::Constantine_detail::LoadFp12<32ul>(cryptofuzz::component::Fp12 const&)
module.cpp:std::__1::optional<std::__1::array<unsigned char, (48ul)*(12)> > cryptofuzz::module::Constantine_detail::LoadFp12<48ul>(cryptofuzz::component::Fp12 const&)
Line
Count
Source
122
1.33k
    static std::optional<std::array<uint8_t, N * 12>> LoadFp12(const component::Fp12& fp12) {
123
1.33k
        std::optional<std::array<uint8_t, N * 12>> ret = std::nullopt;
124
1.33k
        std::array<uint8_t, N * 12> r;
125
126
1.33k
        std::optional<std::array<uint8_t, N>> bytes;
127
128
1.33k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn1.ToTrimmedString()), std::nullopt);
129
1.31k
        memcpy(r.data() + (0 * N), bytes->data(), bytes->size());
130
131
1.31k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn2.ToTrimmedString()), std::nullopt);
132
1.30k
        memcpy(r.data() + (1 * N), bytes->data(), bytes->size());
133
134
1.30k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn3.ToTrimmedString()), std::nullopt);
135
1.28k
        memcpy(r.data() + (2 * N), bytes->data(), bytes->size());
136
137
1.28k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn4.ToTrimmedString()), std::nullopt);
138
1.26k
        memcpy(r.data() + (3 * N), bytes->data(), bytes->size());
139
140
1.26k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn5.ToTrimmedString()), std::nullopt);
141
1.24k
        memcpy(r.data() + (4 * N), bytes->data(), bytes->size());
142
143
1.24k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn6.ToTrimmedString()), std::nullopt);
144
1.22k
        memcpy(r.data() + (5 * N), bytes->data(), bytes->size());
145
146
1.22k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn7.ToTrimmedString()), std::nullopt);
147
1.20k
        memcpy(r.data() + (6 * N), bytes->data(), bytes->size());
148
149
1.20k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn8.ToTrimmedString()), std::nullopt);
150
1.18k
        memcpy(r.data() + (7 * N), bytes->data(), bytes->size());
151
152
1.18k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn9.ToTrimmedString()), std::nullopt);
153
1.17k
        memcpy(r.data() + (8 * N), bytes->data(), bytes->size());
154
155
1.17k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn10.ToTrimmedString()), std::nullopt);
156
1.15k
        memcpy(r.data() + (9 * N), bytes->data(), bytes->size());
157
158
1.15k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn11.ToTrimmedString()), std::nullopt);
159
1.13k
        memcpy(r.data() + (10 * N), bytes->data(), bytes->size());
160
161
1.13k
        CF_CHECK_NE(bytes = LoadField<N>(fp12.bn12.ToTrimmedString()), std::nullopt);
162
1.11k
        memcpy(r.data() + (11 * N), bytes->data(), bytes->size());
163
164
1.11k
        ret = r;
165
1.33k
end:
166
1.33k
        return ret;
167
1.11k
    }
168
169
    template <size_t N>
170
2.72k
    static component::Bignum SaveField(const std::array<uint8_t, N>& field) {
171
2.72k
        return util::BinToDec(field.data(), N);
172
2.72k
    }
module.cpp:cryptofuzz::Bignum cryptofuzz::module::Constantine_detail::SaveField<32ul>(std::__1::array<unsigned char, 32ul> const&)
Line
Count
Source
170
1.26k
    static component::Bignum SaveField(const std::array<uint8_t, N>& field) {
171
1.26k
        return util::BinToDec(field.data(), N);
172
1.26k
    }
module.cpp:cryptofuzz::Bignum cryptofuzz::module::Constantine_detail::SaveField<48ul>(std::__1::array<unsigned char, 48ul> const&)
Line
Count
Source
170
1.45k
    static component::Bignum SaveField(const std::array<uint8_t, N>& field) {
171
1.45k
        return util::BinToDec(field.data(), N);
172
1.45k
    }
173
}
174
175
1.87k
std::optional<bool> Constantine::OpBLS_IsG1OnCurve(operation::BLS_IsG1OnCurve& op) {
176
1.87k
    std::optional<bool> ret = std::nullopt;
177
178
1.87k
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
179
0
        std::optional<std::array<uint8_t, 64>> g1_bytes;
180
0
        CF_CHECK_NE(g1_bytes = Constantine_detail::LoadG1(op.g1), std::nullopt);
181
182
0
        const auto r = cryptofuzz_constantine_bls_isg1oncurve(0, g1_bytes->data(), 64);
183
0
        CF_CHECK_NE(r, -1);
184
0
        ret = r == 1;
185
1.87k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
186
1.87k
        std::optional<std::array<uint8_t, 96>> g1_bytes;
187
1.87k
        CF_CHECK_NE(g1_bytes = Constantine_detail::LoadG1<48>(op.g1), std::nullopt);
188
189
1.84k
        const auto r = cryptofuzz_constantine_bls_isg1oncurve(1, g1_bytes->data(), 96);
190
1.84k
        CF_CHECK_NE(r, -1);
191
1.84k
        ret = r == 1;
192
1.84k
    }
193
194
1.87k
end:
195
1.87k
    return ret;
196
1.87k
}
197
198
3.53k
std::optional<component::G1> Constantine::OpBLS_G1_Add(operation::BLS_G1_Add& op) {
199
3.53k
    std::optional<component::G1> ret = std::nullopt;
200
201
3.53k
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
202
0
        std::optional<std::array<uint8_t, 64>> a_bytes, b_bytes;
203
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1(op.a), std::nullopt);
204
0
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG1(op.b), std::nullopt);
205
0
        std::array<uint8_t, 64> result;
206
207
0
        CF_CHECK_EQ(
208
0
                cryptofuzz_constantine_bls_g1_add(
209
0
                    0,
210
0
                    a_bytes->data(), a_bytes->size(),
211
0
                    b_bytes->data(), b_bytes->size(),
212
0
                    result.data()), 0);
213
0
        ret = Constantine_detail::SaveG1(result);
214
215
3.53k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
216
3.53k
        std::optional<std::array<uint8_t, 96>> a_bytes, b_bytes;
217
3.53k
        std::array<uint8_t, 96> result;
218
219
3.53k
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1<48>(op.a), std::nullopt);
220
3.51k
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG1<48>(op.b), std::nullopt);
221
3.49k
        CF_CHECK_EQ(
222
3.49k
                cryptofuzz_constantine_bls_g1_add(
223
3.49k
                    1,
224
3.49k
                    a_bytes->data(), a_bytes->size(),
225
3.49k
                    b_bytes->data(), b_bytes->size(),
226
3.49k
                    result.data()), 0);
227
228
3.49k
        ret = Constantine_detail::SaveG1<48>(result);
229
3.49k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_377")) ) {
230
0
        std::optional<std::array<uint8_t, 96>> a_bytes, b_bytes;
231
0
        std::array<uint8_t, 96> result;
232
233
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1<48>(op.a), std::nullopt);
234
0
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG1<48>(op.b), std::nullopt);
235
0
        CF_CHECK_EQ(
236
0
                cryptofuzz_constantine_bls_g1_add(
237
0
                    2,
238
0
                    a_bytes->data(), a_bytes->size(),
239
0
                    b_bytes->data(), b_bytes->size(),
240
0
                    result.data()), 0);
241
242
0
        ret = Constantine_detail::SaveG1<48>(result);
243
0
    }
244
245
3.53k
end:
246
3.53k
    return ret;
247
3.53k
}
248
249
2.16k
std::optional<component::G1> Constantine::OpBLS_G1_Mul(operation::BLS_G1_Mul& op) {
250
2.16k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
251
2.16k
    std::optional<component::G1> ret = std::nullopt;
252
253
2.16k
    uint8_t which = 0;
254
255
2.16k
    try {
256
2.16k
        which = ds.Get<uint8_t>() % 7;
257
2.16k
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
258
1.54k
    }
259
260
2.16k
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
261
0
        std::optional<std::array<uint8_t, 64>> a_bytes;
262
0
        std::optional<std::array<uint8_t, 32>> b_bytes;
263
0
        std::array<uint8_t, 64> result;
264
265
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1(op.a), std::nullopt);
266
0
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadField(op.b), std::nullopt);
267
268
0
        CF_CHECK_EQ(
269
0
                cryptofuzz_constantine_bls_g1_mul(
270
0
                    0,
271
0
                    a_bytes->data(), a_bytes->size(),
272
0
                    b_bytes->data(), b_bytes->size(),
273
0
                    which,
274
0
                    result.data()), 0);
275
276
0
        ret = Constantine_detail::SaveG1(result);
277
2.16k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
278
2.16k
        std::optional<std::array<uint8_t, 96>> a_bytes;
279
2.16k
        std::optional<std::array<uint8_t, 48>> b_bytes;
280
2.16k
        std::array<uint8_t, 96> result;
281
282
2.16k
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1<48>(op.a), std::nullopt);
283
2.14k
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadField<48>(op.b), std::nullopt);
284
2.14k
        CF_CHECK_EQ(
285
2.14k
                cryptofuzz_constantine_bls_g1_mul(
286
2.14k
                    1,
287
2.14k
                    a_bytes->data(), a_bytes->size(),
288
2.14k
                    b_bytes->data(), b_bytes->size(),
289
2.14k
                    which,
290
2.14k
                    result.data()), 0);
291
292
78
        ret = Constantine_detail::SaveG1<48>(result);
293
78
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_377")) ) {
294
0
        std::optional<std::array<uint8_t, 96>> a_bytes;
295
0
        std::optional<std::array<uint8_t, 48>> b_bytes;
296
0
        std::array<uint8_t, 96> result;
297
298
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1<48>(op.a), std::nullopt);
299
0
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadField<48>(op.b), std::nullopt);
300
0
        CF_CHECK_EQ(
301
0
                cryptofuzz_constantine_bls_g1_mul(
302
0
                    2,
303
0
                    a_bytes->data(), a_bytes->size(),
304
0
                    b_bytes->data(), b_bytes->size(),
305
0
                    which,
306
0
                    result.data()), 0);
307
308
0
        ret = Constantine_detail::SaveG1<48>(result);
309
0
    }
310
311
2.16k
end:
312
2.16k
    return ret;
313
2.16k
}
314
315
0
std::optional<component::G1> Constantine::OpBLS_G1_MultiExp(operation::BLS_G1_MultiExp& op) {
316
0
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
317
0
    std::optional<component::G1> ret = std::nullopt;
318
319
0
    std::vector<uint8_t> points, scalars;
320
321
0
    const size_t num = op.points_scalars.points_scalars.size();
322
323
0
    uint8_t which = 0;
324
325
0
    try {
326
0
        which = ds.Get<uint8_t>() % 4;
327
0
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
328
0
    }
329
330
0
    CF_CHECK_NE(num, 0);
331
332
0
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
333
0
        for (size_t i = 0; i < num; i++) {
334
0
            std::optional<std::array<uint8_t, 64>> a_bytes;
335
0
            std::optional<std::array<uint8_t, 32>> b_bytes;
336
337
0
            const auto& cur = op.points_scalars.points_scalars[i];
338
339
0
            CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1<32>(cur.first), std::nullopt);
340
0
            points.insert(points.end(), a_bytes->begin(), a_bytes->end());
341
342
0
            CF_CHECK_NE(b_bytes = Constantine_detail::LoadField<32>(cur.second), std::nullopt);
343
0
            scalars.insert(scalars.end(), b_bytes->begin(), b_bytes->end());
344
0
        }
345
346
0
        std::array<uint8_t, 64> result;
347
348
0
        CF_CHECK_EQ(
349
0
                cryptofuzz_constantine_bls_g1_multiexp(
350
0
                    0,
351
0
                    points.data(), points.size(),
352
0
                    scalars.data(), scalars.size(),
353
0
                    num,
354
0
                    which,
355
0
                    result.data()), 0);
356
357
0
        ret = Constantine_detail::SaveG1<32>(result);
358
0
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
359
0
        for (size_t i = 0; i < num; i++) {
360
0
            std::optional<std::array<uint8_t, 96>> a_bytes;
361
0
            std::optional<std::array<uint8_t, 32>> b_bytes;
362
363
0
            const auto& cur = op.points_scalars.points_scalars[i];
364
365
0
            CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1<48>(cur.first), std::nullopt);
366
0
            points.insert(points.end(), a_bytes->begin(), a_bytes->end());
367
368
0
            CF_CHECK_NE(b_bytes = Constantine_detail::LoadField<32>(cur.second), std::nullopt);
369
0
            scalars.insert(scalars.end(), b_bytes->begin(), b_bytes->end());
370
0
        }
371
372
0
        std::array<uint8_t, 96> result;
373
374
0
        CF_CHECK_EQ(
375
0
                cryptofuzz_constantine_bls_g1_multiexp(
376
0
                    1,
377
0
                    points.data(), points.size(),
378
0
                    scalars.data(), scalars.size(),
379
0
                    num,
380
0
                    which,
381
0
                    result.data()), 0);
382
383
0
        ret = Constantine_detail::SaveG1<48>(result);
384
0
    }
385
386
0
    if ( which == 1 ) return std::nullopt;
387
0
end:
388
0
    return ret;
389
0
}
390
391
2.50k
std::optional<component::G1> Constantine::OpBLS_G1_Neg(operation::BLS_G1_Neg& op) {
392
2.50k
    std::optional<component::G1> ret = std::nullopt;
393
394
2.50k
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
395
0
        std::optional<std::array<uint8_t, 64>> a_bytes;
396
0
        std::array<uint8_t, 64> result;
397
398
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1(op.a), std::nullopt);
399
400
0
        CF_CHECK_EQ(
401
0
                cryptofuzz_constantine_bls_g1_neg(
402
0
                    0,
403
0
                    a_bytes->data(), a_bytes->size(),
404
0
                    result.data()), 0);
405
406
0
        ret = Constantine_detail::SaveG1(result);
407
2.50k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
408
2.50k
        std::optional<std::array<uint8_t, 96>> a_bytes;
409
2.50k
        std::array<uint8_t, 96> result;
410
411
2.50k
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1<48>(op.a), std::nullopt);
412
413
2.47k
        CF_CHECK_EQ(
414
2.47k
                cryptofuzz_constantine_bls_g1_neg(
415
2.47k
                    1,
416
2.47k
                    a_bytes->data(), a_bytes->size(),
417
2.47k
                    result.data()), 0);
418
419
2.47k
        ret = Constantine_detail::SaveG1<48>(result);
420
2.47k
    }
421
422
2.50k
end:
423
2.50k
    return ret;
424
2.50k
}
425
426
133
std::optional<bool> Constantine::OpBLS_G1_IsEq(operation::BLS_G1_IsEq& op) {
427
133
    std::optional<bool> ret = std::nullopt;
428
429
133
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
430
0
        std::optional<std::array<uint8_t, 64>> a_bytes, b_bytes;
431
432
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1(op.a), std::nullopt);
433
0
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG1(op.b), std::nullopt);
434
435
0
        const auto r = cryptofuzz_constantine_bls_g1_iseq(
436
0
                    0,
437
0
                    a_bytes->data(), a_bytes->size(),
438
0
                    b_bytes->data(), b_bytes->size());
439
440
0
        CF_CHECK_NE(r, -1);
441
0
        ret = r == 1;
442
133
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
443
133
        std::optional<std::array<uint8_t, 96>> a_bytes, b_bytes;
444
445
133
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG1<48>(op.a), std::nullopt);
446
116
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG1<48>(op.b), std::nullopt);
447
448
98
        const auto r = cryptofuzz_constantine_bls_g1_iseq(
449
98
                    1,
450
98
                    a_bytes->data(), a_bytes->size(),
451
98
                    b_bytes->data(), b_bytes->size());
452
453
98
        CF_CHECK_NE(r, -1);
454
98
        ret = r == 1;
455
98
    }
456
457
133
end:
458
133
    return ret;
459
133
}
460
461
2.46k
std::optional<bool> Constantine::OpBLS_IsG2OnCurve(operation::BLS_IsG2OnCurve& op) {
462
2.46k
    std::optional<bool> ret = std::nullopt;
463
464
2.46k
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
465
35
        std::optional<std::array<uint8_t, 128>> g2_bytes;
466
467
        /* XXX */
468
35
        if ( op.g2.first.first.ToTrimmedString() == "0" &&
469
35
                op.g2.first.second.ToTrimmedString() == "1" &&
470
35
                op.g2.second.first.ToTrimmedString() == "0" &&
471
35
                op.g2.second.second.ToTrimmedString() == "0" ) {
472
2
            return ret;
473
2
        }
474
475
33
        CF_CHECK_NE(g2_bytes = Constantine_detail::LoadG2(op.g2), std::nullopt);
476
477
24
        const auto r = cryptofuzz_constantine_bls_isg2oncurve(0, g2_bytes->data(), 32 * 4);
478
24
        CF_CHECK_NE(r, -1);
479
24
        ret = r == 1;
480
2.43k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
481
2.24k
        std::optional<std::array<uint8_t, 48 * 4>> g2_bytes;
482
483
2.24k
        CF_CHECK_NE(g2_bytes = Constantine_detail::LoadG2<48>(op.g2), std::nullopt);
484
485
2.21k
        const auto r = cryptofuzz_constantine_bls_isg2oncurve(1, g2_bytes->data(), 48 * 4);
486
2.21k
        CF_CHECK_NE(r, -1);
487
2.21k
        ret = r == 1;
488
2.21k
    }
489
490
2.46k
end:
491
2.46k
    return ret;
492
2.46k
}
493
494
3.63k
std::optional<component::G2> Constantine::OpBLS_G2_Add(operation::BLS_G2_Add& op) {
495
3.63k
    std::optional<component::G2> ret = std::nullopt;
496
497
3.63k
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
498
0
        std::optional<std::array<uint8_t, 128>> a_bytes, b_bytes;
499
0
        std::array<uint8_t, 128> result;
500
501
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG2(op.a), std::nullopt);
502
0
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG2(op.b), std::nullopt);
503
504
0
        CF_CHECK_EQ(
505
0
                cryptofuzz_constantine_bls_g2_add(
506
0
                    0,
507
0
                    a_bytes->data(), 128,
508
0
                    b_bytes->data(), 128,
509
0
                    result.data()), 0);
510
511
0
        ret = Constantine_detail::SaveG2(result);
512
3.63k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
513
3.63k
        std::optional<std::array<uint8_t, 48 * 4>> a_bytes, b_bytes;
514
3.63k
        std::array<uint8_t, 48 * 4> result;
515
516
3.63k
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG2<48>(op.a), std::nullopt);
517
3.60k
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG2<48>(op.b), std::nullopt);
518
519
3.56k
        CF_CHECK_EQ(
520
3.56k
                cryptofuzz_constantine_bls_g2_add(
521
3.56k
                    1,
522
3.56k
                    a_bytes->data(), 48 * 4,
523
3.56k
                    b_bytes->data(), 48 * 4,
524
3.56k
                    result.data()), 0);
525
526
13
        ret = Constantine_detail::SaveG2<48>(result);
527
13
    }
528
529
3.63k
end:
530
3.63k
    return ret;
531
3.63k
}
532
533
7.44k
std::optional<component::G2> Constantine::OpBLS_G2_Mul(operation::BLS_G2_Mul& op) {
534
7.44k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
535
7.44k
    std::optional<component::G2> ret = std::nullopt;
536
537
7.44k
    uint8_t which = 0;
538
539
7.44k
    try {
540
7.44k
        which = ds.Get<uint8_t>() % 7;
541
7.44k
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
542
6.30k
    }
543
544
7.44k
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
545
0
        std::optional<std::array<uint8_t, 128>> a_bytes;
546
0
        std::optional<std::array<uint8_t, 32>> b_bytes;
547
0
        std::array<uint8_t, 128> result;
548
549
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG2(op.a), std::nullopt);
550
0
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadField(op.b), std::nullopt);
551
552
0
        CF_CHECK_EQ(
553
0
                cryptofuzz_constantine_bls_g2_mul(
554
0
                    0,
555
0
                    a_bytes->data(), 128,
556
0
                    b_bytes->data(), 32,
557
0
                    which,
558
0
                    result.data()), 0);
559
560
0
        ret = Constantine_detail::SaveG2(result);
561
7.44k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
562
7.44k
        std::optional<std::array<uint8_t, 48 * 4>> a_bytes;
563
7.44k
        std::optional<std::array<uint8_t, 32>> b_bytes;
564
7.44k
        std::array<uint8_t, 48 * 4> result;
565
566
7.44k
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG2<48>(op.a), std::nullopt);
567
7.40k
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadField(op.b), std::nullopt);
568
569
7.39k
        CF_CHECK_EQ(
570
7.39k
                cryptofuzz_constantine_bls_g2_mul(
571
7.39k
                    1,
572
7.39k
                    a_bytes->data(), 48 * 4,
573
7.39k
                    b_bytes->data(), 32,
574
7.39k
                    which,
575
7.39k
                    result.data()), 0);
576
577
24
        ret = Constantine_detail::SaveG2<48>(result);
578
24
    }
579
580
7.44k
end:
581
7.44k
    return ret;
582
7.44k
}
583
584
2.30k
std::optional<component::G2> Constantine::OpBLS_G2_Neg(operation::BLS_G2_Neg& op) {
585
2.30k
    std::optional<component::G2> ret = std::nullopt;
586
587
2.30k
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
588
0
        std::optional<std::array<uint8_t, 128>> a_bytes;
589
0
        std::array<uint8_t, 128> result;
590
591
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG2(op.a), std::nullopt);
592
593
0
        CF_CHECK_EQ(
594
0
                cryptofuzz_constantine_bls_g2_neg(
595
0
                    0,
596
0
                    a_bytes->data(), 128,
597
0
                    result.data()), 0);
598
599
0
        ret = Constantine_detail::SaveG2(result);
600
2.30k
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
601
2.30k
        std::optional<std::array<uint8_t, 48 * 4>> a_bytes;
602
2.30k
        std::array<uint8_t, 48 * 4> result;
603
604
2.30k
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG2<48>(op.a), std::nullopt);
605
606
2.26k
        CF_CHECK_EQ(
607
2.26k
                cryptofuzz_constantine_bls_g2_neg(
608
2.26k
                    1,
609
2.26k
                    a_bytes->data(), 48 * 4,
610
2.26k
                    result.data()), 0);
611
612
2.26k
        ret = Constantine_detail::SaveG2<48>(result);
613
2.26k
    }
614
615
2.30k
end:
616
2.30k
    return ret;
617
2.30k
}
618
619
129
std::optional<bool> Constantine::OpBLS_G2_IsEq(operation::BLS_G2_IsEq& op) {
620
129
    std::optional<bool> ret = std::nullopt;
621
622
129
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
623
0
        std::optional<std::array<uint8_t, 128>> a_bytes, b_bytes;
624
625
0
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG2(op.a), std::nullopt);
626
0
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG2(op.b), std::nullopt);
627
628
0
        const auto r = cryptofuzz_constantine_bls_g2_iseq(
629
0
                    0,
630
0
                    a_bytes->data(), a_bytes->size(),
631
0
                    b_bytes->data(), b_bytes->size());
632
633
0
        CF_CHECK_NE(r, -1);
634
0
        ret = r == 1;
635
129
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
636
129
        std::optional<std::array<uint8_t, 48 * 4>> a_bytes, b_bytes;
637
638
129
        CF_CHECK_NE(a_bytes = Constantine_detail::LoadG2<48>(op.a), std::nullopt);
639
84
        CF_CHECK_NE(b_bytes = Constantine_detail::LoadG2<48>(op.b), std::nullopt);
640
641
50
        const auto r = cryptofuzz_constantine_bls_g2_iseq(
642
50
                    1,
643
50
                    a_bytes->data(), a_bytes->size(),
644
50
                    b_bytes->data(), b_bytes->size());
645
646
50
        CF_CHECK_NE(r, -1);
647
50
        ret = r == 1;
648
50
    }
649
650
129
end:
651
129
    return ret;
652
129
}
653
654
123
std::optional<component::Fp12> Constantine::OpBLS_Pairing(operation::BLS_Pairing& op) {
655
123
    std::optional<component::Fp12> ret = std::nullopt;
656
    /* Disabled until https://github.com/mratsim/constantine/issues/454 is implemented */
657
123
    return ret;
658
659
0
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
660
0
        std::optional<std::array<uint8_t, 64>> g1_bytes;
661
0
        std::optional<std::array<uint8_t, 128>> g2_bytes;
662
0
        std::array<uint8_t, 32 * 12> result;
663
664
0
        CF_CHECK_NE(g1_bytes = Constantine_detail::LoadG1(op.g1), std::nullopt);
665
0
        CF_CHECK_NE(g2_bytes = Constantine_detail::LoadG2(op.g2), std::nullopt);
666
667
0
        CF_CHECK_EQ(
668
0
                cryptofuzz_constantine_bls_pairing(
669
0
                    0,
670
0
                    g1_bytes->data(), g1_bytes->size(),
671
0
                    g2_bytes->data(), g2_bytes->size(),
672
0
                    result.data()), 0);
673
674
0
        ret = Constantine_detail::SaveFp12(result);
675
0
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
676
0
        std::optional<std::array<uint8_t, 48 * 2>> g1_bytes;
677
0
        std::optional<std::array<uint8_t, 48 * 4>> g2_bytes;
678
0
        std::array<uint8_t, 48 * 12> result;
679
680
0
        CF_CHECK_NE(g1_bytes = Constantine_detail::LoadG1<48>(op.g1), std::nullopt);
681
0
        CF_CHECK_NE(g2_bytes = Constantine_detail::LoadG2<48>(op.g2), std::nullopt);
682
683
0
        CF_CHECK_EQ(
684
0
                cryptofuzz_constantine_bls_pairing(
685
0
                    1,
686
0
                    g1_bytes->data(), g1_bytes->size(),
687
0
                    g2_bytes->data(), g2_bytes->size(),
688
0
                    result.data()), 0);
689
690
0
        ret = Constantine_detail::SaveFp12<48>(result);
691
0
    }
692
693
0
end:
694
0
    return ret;
695
0
}
696
697
181
std::optional<component::Fp12> Constantine::OpBLS_FinalExp(operation::BLS_FinalExp& op) {
698
181
    std::optional<component::Fp12> ret = std::nullopt;
699
700
181
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
701
0
        std::optional<std::array<uint8_t, 32 * 12>> fp12_bytes;
702
703
0
        CF_CHECK_NE(fp12_bytes = Constantine_detail::LoadFp12(op.fp12), std::nullopt);
704
0
        std::array<uint8_t, 32 * 12> result;
705
706
0
        CF_CHECK_EQ(
707
0
                cryptofuzz_constantine_bls_finalexp(
708
0
                    0,
709
0
                    fp12_bytes->data(), fp12_bytes->size(),
710
0
                    result.data()), 0);
711
712
0
        ret = Constantine_detail::SaveFp12(result);
713
181
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
714
181
        std::optional<std::array<uint8_t, 48 * 12>> fp12_bytes;
715
716
181
        CF_CHECK_NE(fp12_bytes = Constantine_detail::LoadFp12<48>(op.fp12), std::nullopt);
717
136
        std::array<uint8_t, 48 * 12> result;
718
719
136
        CF_CHECK_EQ(
720
136
                cryptofuzz_constantine_bls_finalexp(
721
136
                    1,
722
136
                    fp12_bytes->data(), fp12_bytes->size(),
723
136
                    result.data()), 0);
724
725
136
        ret = Constantine_detail::SaveFp12<48>(result);
726
136
    }
727
728
181
end:
729
181
    return ret;
730
181
}
731
732
149
std::optional<component::G1> Constantine::OpBLS_HashToG1(operation::BLS_HashToG1& op) {
733
149
    std::optional<component::G1> ret = std::nullopt;
734
735
149
    auto aug = op.aug.Get();
736
149
    auto msg = op.cleartext.Get();
737
149
    auto dst = op.dest.Get();
738
739
149
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
740
0
        std::array<uint8_t, 64> result;
741
0
        CF_CHECK_EQ(
742
0
                cryptofuzz_constantine_bls_hashtog1(
743
0
                    0,
744
0
                    aug.data(), aug.size(),
745
0
                    msg.data(), msg.size(),
746
0
                    dst.data(), dst.size(),
747
0
                    result.data()), 0);
748
0
        ret = Constantine_detail::SaveG1(result);
749
149
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
750
149
        std::array<uint8_t, 96> result;
751
149
        CF_CHECK_EQ(
752
149
                cryptofuzz_constantine_bls_hashtog1(
753
149
                    1,
754
149
                    aug.data(), aug.size(),
755
149
                    msg.data(), msg.size(),
756
149
                    dst.data(), dst.size(),
757
149
                    result.data()), 0);
758
149
        ret = Constantine_detail::SaveG1<48>(result);
759
149
    }
760
761
149
end:
762
149
    return ret;
763
149
}
764
765
171
std::optional<component::G2> Constantine::OpBLS_HashToG2(operation::BLS_HashToG2& op) {
766
171
    std::optional<component::G2> ret = std::nullopt;
767
768
171
    auto aug = op.aug.Get();
769
171
    auto msg = op.cleartext.Get();
770
171
    auto dst = op.dest.Get();
771
772
171
    if ( op.curveType.Is(CF_ECC_CURVE("alt_bn128")) ) {
773
0
        std::array<uint8_t, 128> result;
774
775
0
        CF_CHECK_EQ(
776
0
                cryptofuzz_constantine_bls_hashtog2(
777
0
                    0,
778
0
                    aug.data(), aug.size(),
779
0
                    msg.data(), msg.size(),
780
0
                    dst.data(), dst.size(),
781
0
                    result.data()), 0);
782
783
0
        ret = Constantine_detail::SaveG2(result);
784
171
    } else if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
785
171
        std::array<uint8_t, 48 * 4> result;
786
787
171
        CF_CHECK_EQ(
788
171
                cryptofuzz_constantine_bls_hashtog2(
789
171
                    1,
790
171
                    aug.data(), aug.size(),
791
171
                    msg.data(), msg.size(),
792
171
                    dst.data(), dst.size(),
793
171
                    result.data()), 0);
794
795
171
        ret = Constantine_detail::SaveG2<48>(result);
796
171
    }
797
798
171
end:
799
171
    return ret;
800
171
}
801
802
93
std::optional<component::BLS_KeyPair> Constantine::OpBLS_GenerateKeyPair(operation::BLS_GenerateKeyPair& op) {
803
93
    std::optional<component::BLS_KeyPair> ret = std::nullopt;
804
805
93
    if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
806
45
        std::array<uint8_t, 32> result_priv;
807
45
        std::array<uint8_t, 48 * 2> result_pub;
808
45
        CF_CHECK_EQ(op.info.GetSize(), 0);
809
810
25
        auto ikm = op.ikm.Get();
811
812
25
        CF_CHECK_EQ(
813
25
                cryptofuzz_constantine_bls_generatekeypair(
814
25
                    ikm.data(),
815
25
                    ikm.size(),
816
25
                    result_priv.data(),
817
25
                    result_pub.data()), 0);
818
15
        ret = {
819
15
            Constantine_detail::SaveField(result_priv),
820
15
            Constantine_detail::SaveG1<48>(result_pub)};
821
15
    }
822
823
93
end:
824
93
    return ret;
825
93
}
826
827
186
std::optional<component::G1> Constantine::OpBLS_Decompress_G1(operation::BLS_Decompress_G1& op) {
828
186
    std::optional<component::G1> ret = std::nullopt;
829
830
186
    if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
831
46
        std::optional<std::array<uint8_t, 48>> compressed;
832
46
        std::array<uint8_t, 48 * 2> result;
833
834
46
        CF_CHECK_NE(compressed = Constantine_detail::LoadField<48>(op.compressed), std::nullopt);
835
836
44
        CF_CHECK_EQ(
837
44
                cryptofuzz_constantine_bls_decompress_g1(
838
44
                    compressed->data(), compressed->size(),
839
44
                    result.data()), 0);
840
841
9
        ret = Constantine_detail::SaveG1<48>(result);
842
9
    }
843
844
186
end:
845
186
    return ret;
846
186
}
847
848
79
std::optional<component::Bignum> Constantine::OpBLS_Compress_G1(operation::BLS_Compress_G1& op) {
849
79
    std::optional<component::Bignum> ret = std::nullopt;
850
851
79
    if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
852
39
        std::optional<std::array<uint8_t, 96>> g1_bytes;
853
39
        std::array<uint8_t, 48> result;
854
855
39
        CF_CHECK_NE(g1_bytes = Constantine_detail::LoadG1<48>(op.uncompressed), std::nullopt);
856
857
25
        CF_CHECK_EQ(
858
25
                cryptofuzz_constantine_bls_compress_g1(
859
25
                    g1_bytes->data(), g1_bytes->size(),
860
25
                    result.data()), 0);
861
862
25
        ret = Constantine_detail::SaveField<48>(result);
863
25
    }
864
865
79
end:
866
79
    return ret;
867
79
}
868
869
112
std::optional<component::G2> Constantine::OpBLS_Decompress_G2(operation::BLS_Decompress_G2& op) {
870
112
    std::optional<component::G2> ret = std::nullopt;
871
872
112
    if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
873
29
        std::optional<std::array<uint8_t, 48>> a, b;
874
29
        std::array<uint8_t, 48 * 4> result;
875
29
        std::vector<uint8_t> compressed;
876
877
29
        CF_CHECK_NE(a = Constantine_detail::LoadField<48>(op.compressed.first), std::nullopt);
878
27
        CF_CHECK_NE(b = Constantine_detail::LoadField<48>(op.compressed.second), std::nullopt);
879
880
20
        compressed.insert(compressed.end(), a->begin(), a->end());
881
20
        compressed.insert(compressed.end(), b->begin(), b->end());
882
883
20
        CF_CHECK_EQ(
884
20
                cryptofuzz_constantine_bls_decompress_g2(
885
20
                    compressed.data(), compressed.size(),
886
20
                    result.data()), 0);
887
888
3
        ret = Constantine_detail::SaveG2<48>(result);
889
3
    }
890
891
112
end:
892
112
    return ret;
893
112
}
894
895
98
std::optional<component::G1> Constantine::OpBLS_Compress_G2(operation::BLS_Compress_G2& op) {
896
98
    std::optional<component::G1> ret = std::nullopt;
897
898
98
    if ( op.curveType.Is(CF_ECC_CURVE("BLS12_381")) ) {
899
67
        std::optional<std::array<uint8_t, 48 * 4>> g2_bytes;
900
67
        std::array<uint8_t, 96> result;
901
902
67
        CF_CHECK_NE(g2_bytes = Constantine_detail::LoadG2<48>(op.uncompressed), std::nullopt);
903
904
39
        CF_CHECK_EQ(
905
39
                cryptofuzz_constantine_bls_compress_g2(
906
39
                    g2_bytes->data(), g2_bytes->size(),
907
39
                    result.data()), 0);
908
909
39
        ret = Constantine_detail::SaveG1<48>(result);
910
39
    }
911
912
98
end:
913
98
    return ret;
914
98
}
915
916
namespace Constantine_detail {
917
12.8k
    std::optional<component::Bignum> OpBignumCalc_Mod(operation::BignumCalc& op) {
918
12.8k
        Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
919
12.8k
        std::optional<component::Bignum> ret = std::nullopt;
920
12.8k
        bool alt = false;
921
922
12.8k
        uint8_t calcop;
923
12.8k
        switch ( op.calcOp.Get() ) {
924
286
            case    CF_CALCOP("Add(A,B)"):
925
286
                calcop = 0;
926
286
                break;
927
275
            case    CF_CALCOP("Sub(A,B)"):
928
275
                calcop = 1;
929
275
                break;
930
961
            case    CF_CALCOP("Mul(A,B)"):
931
961
                calcop = 2;
932
961
                break;
933
553
            case    CF_CALCOP("InvMod(A,B)"):
934
553
                calcop = 3;
935
553
                break;
936
158
            case    CF_CALCOP("Sqr(A)"):
937
158
                calcop = 4;
938
158
                break;
939
108
            case    CF_CALCOP("IsEq(A,B)"):
940
108
                calcop = 5;
941
108
                break;
942
1.05k
            case    CF_CALCOP("Sqrt(A)"):
943
1.05k
                calcop = 6;
944
1.05k
                break;
945
80
            case    CF_CALCOP("Not(A)"):
946
80
                calcop = 7;
947
80
                break;
948
56
            case    CF_CALCOP("IsOne(A)"):
949
56
                calcop = 8;
950
56
                break;
951
75
            case    CF_CALCOP("IsZero(A)"):
952
75
                calcop = 9;
953
75
                break;
954
67
            case    CF_CALCOP("Exp(A,B)"):
955
67
                calcop = 10;
956
67
                break;
957
9.19k
            default:
958
9.19k
                return ret;
959
12.8k
        }
960
961
3.67k
        try {
962
3.67k
            alt = ds.Get<bool>();
963
3.67k
        } catch ( fuzzing::datasource::Datasource::OutOfData ) {
964
2.58k
        }
965
966
3.67k
        if ( op.modulo->ToTrimmedString() == "21888242871839275222246405745257275088548364400416034343698204186575808495617" ) {
967
0
            std::optional<std::array<uint8_t, 32>> bn0_bytes, bn1_bytes;
968
0
            std::array<uint8_t, 32> result;
969
0
            CF_CHECK_NE(bn0_bytes = Constantine_detail::LoadField<32>(op.bn0), std::nullopt);
970
0
            CF_CHECK_NE(bn1_bytes = Constantine_detail::LoadField<32>(op.bn1), std::nullopt);
971
0
            CF_CHECK_EQ(
972
0
                    cryptofuzz_constantine_bignumcalc_fr(
973
0
                        0,
974
0
                        calcop,
975
0
                        bn0_bytes->data(), 32,
976
0
                        bn1_bytes->data(), 32,
977
0
                        alt,
978
0
                        result.data()), 0);
979
0
            ret = Constantine_detail::SaveField(result);
980
3.67k
        } else if ( op.modulo->ToTrimmedString() == "21888242871839275222246405745257275088696311157297823662689037894645226208583" ) {
981
0
            std::optional<std::array<uint8_t, 32>> bn0_bytes, bn1_bytes;
982
0
            std::array<uint8_t, 32> result;
983
0
            CF_CHECK_NE(bn0_bytes = Constantine_detail::LoadField<32>(op.bn0), std::nullopt);
984
0
            CF_CHECK_NE(bn1_bytes = Constantine_detail::LoadField<32>(op.bn1), std::nullopt);
985
0
            CF_CHECK_EQ(
986
0
                    cryptofuzz_constantine_bignumcalc_fp(
987
0
                        0,
988
0
                        calcop,
989
0
                        bn0_bytes->data(), 32,
990
0
                        bn1_bytes->data(), 32,
991
0
                        alt,
992
0
                        result.data()), 0);
993
0
            ret = Constantine_detail::SaveField(result);
994
3.67k
        } else if ( op.modulo->ToTrimmedString() == "52435875175126190479447740508185965837690552500527637822603658699938581184513" ) {
995
2.10k
            std::optional<std::array<uint8_t, 32>> bn0_bytes, bn1_bytes;
996
2.10k
            std::array<uint8_t, 32> result;
997
2.10k
            CF_CHECK_NE(bn0_bytes = Constantine_detail::LoadField<32>(op.bn0), std::nullopt);
998
2.02k
            CF_CHECK_NE(bn1_bytes = Constantine_detail::LoadField<32>(op.bn1), std::nullopt);
999
1.96k
            CF_CHECK_EQ(
1000
1.96k
                    cryptofuzz_constantine_bignumcalc_fr(
1001
1.96k
                        1,
1002
1.96k
                        calcop,
1003
1.96k
                        bn0_bytes->data(), 32,
1004
1.96k
                        bn1_bytes->data(), 32,
1005
1.96k
                        alt,
1006
1.96k
                        result.data()), 0);
1007
1.25k
            ret = Constantine_detail::SaveField(result);
1008
1.56k
        } else if ( op.modulo->ToTrimmedString() == "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787" ) {
1009
1.56k
            std::optional<std::array<uint8_t, 48>> bn0_bytes, bn1_bytes;
1010
1.56k
            std::array<uint8_t, 48> result;
1011
1.56k
            CF_CHECK_NE(bn0_bytes = Constantine_detail::LoadField<48>(op.bn0), std::nullopt);
1012
1.48k
            CF_CHECK_NE(bn1_bytes = Constantine_detail::LoadField<48>(op.bn1), std::nullopt);
1013
1.43k
            CF_CHECK_EQ(
1014
1.43k
                    cryptofuzz_constantine_bignumcalc_fp(
1015
1.43k
                        1,
1016
1.43k
                        calcop,
1017
1.43k
                        bn0_bytes->data(), 48,
1018
1.43k
                        bn1_bytes->data(), 48,
1019
1.43k
                        alt,
1020
1.43k
                        result.data()), 0);
1021
1.43k
            ret = Constantine_detail::SaveField(result);
1022
1.43k
        }
1023
1024
3.67k
end:
1025
3.67k
        return ret;
1026
3.67k
    }
1027
}
1028
1029
2.72k
std::optional<component::Fp2> Constantine::OpBignumCalc_Fp2(operation::BignumCalc_Fp2& op) {
1030
2.72k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
1031
2.72k
    std::optional<component::Fp2> ret = std::nullopt;
1032
1033
2.72k
    uint8_t calcop;
1034
2.72k
    bool alt = false;
1035
1036
2.72k
    switch ( op.calcOp.Get() ) {
1037
85
        case    CF_CALCOP("Add(A,B)"):
1038
85
            calcop = 0;
1039
85
            break;
1040
80
        case    CF_CALCOP("Sub(A,B)"):
1041
80
            calcop = 1;
1042
80
            break;
1043
82
        case    CF_CALCOP("Mul(A,B)"):
1044
82
            calcop = 2;
1045
82
            break;
1046
84
        case    CF_CALCOP("InvMod(A,B)"):
1047
84
            calcop = 3;
1048
84
            break;
1049
50
        case    CF_CALCOP("Sqr(A)"):
1050
50
            calcop = 4;
1051
50
            break;
1052
2
        case    CF_CALCOP("IsEq(A,B)"):
1053
2
            calcop = 5;
1054
2
            break;
1055
58
        case    CF_CALCOP("Sqrt(A)"):
1056
58
            calcop = 6;
1057
58
            break;
1058
42
        case    CF_CALCOP("Not(A)"):
1059
42
            calcop = 7;
1060
42
            break;
1061
3
        case    CF_CALCOP("IsOne(A)"):
1062
3
            calcop = 8;
1063
3
            break;
1064
2
        case    CF_CALCOP("IsZero(A)"):
1065
2
            calcop = 9;
1066
2
            break;
1067
2
        case    CF_CALCOP("Exp(A,B)"):
1068
2
            calcop = 10;
1069
2
            break;
1070
2.23k
        default:
1071
2.23k
            return ret;
1072
2.72k
    }
1073
1074
490
    try {
1075
490
        alt = ds.Get<bool>();
1076
490
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
1077
317
    }
1078
1079
#if 0
1080
    std::optional<std::array<uint8_t, 32 * 2>> bn0_bytes, bn1_bytes;
1081
    std::array<uint8_t, 32 * 2> result;
1082
1083
    CF_CHECK_NE(bn0_bytes = Constantine_detail::LoadG1(op.bn0), std::nullopt);
1084
    CF_CHECK_NE(bn1_bytes = Constantine_detail::LoadG1(op.bn1), std::nullopt);
1085
1086
    CF_CHECK_EQ(
1087
            cryptofuzz_constantine_bignumcalc_fp2(
1088
                0,
1089
                calcop,
1090
                bn0_bytes->data(), bn0_bytes->size(),
1091
                bn1_bytes->data(), bn1_bytes->size(),
1092
                alt,
1093
                result.data()), 0);
1094
1095
    ret = Constantine_detail::SaveG1(result);
1096
#else
1097
490
    std::optional<std::array<uint8_t, 48 * 2>> bn0_bytes, bn1_bytes;
1098
490
    std::array<uint8_t, 48 * 2> result;
1099
1100
490
    CF_CHECK_NE(bn0_bytes = Constantine_detail::LoadG1<48>(op.bn0), std::nullopt);
1101
378
    CF_CHECK_NE(bn1_bytes = Constantine_detail::LoadG1<48>(op.bn1), std::nullopt);
1102
1103
328
    CF_CHECK_EQ(
1104
328
            cryptofuzz_constantine_bignumcalc_fp2(
1105
328
                1,
1106
328
                calcop,
1107
328
                bn0_bytes->data(), bn0_bytes->size(),
1108
328
                bn1_bytes->data(), bn1_bytes->size(),
1109
328
                alt,
1110
328
                result.data()), 0);
1111
1112
326
    ret = Constantine_detail::SaveG1<48>(result);
1113
326
#endif
1114
1115
490
end:
1116
490
    return ret;
1117
326
}
1118
1119
1.45k
std::optional<component::Fp12> Constantine::OpBignumCalc_Fp12(operation::BignumCalc_Fp12& op) {
1120
1.45k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
1121
1.45k
    std::optional<component::Fp12> ret = std::nullopt;
1122
1123
1.45k
    uint8_t calcop;
1124
1.45k
    bool alt = false;
1125
1126
1.45k
    switch ( op.calcOp.Get() ) {
1127
81
        case    CF_CALCOP("Add(A,B)"):
1128
81
            calcop = 0;
1129
81
            break;
1130
98
        case    CF_CALCOP("Sub(A,B)"):
1131
98
            calcop = 1;
1132
98
            break;
1133
194
        case    CF_CALCOP("Mul(A,B)"):
1134
194
            calcop = 2;
1135
194
            break;
1136
96
        case    CF_CALCOP("InvMod(A,B)"):
1137
96
            calcop = 3;
1138
96
            break;
1139
73
        case    CF_CALCOP("Sqr(A)"):
1140
73
            calcop = 4;
1141
73
            break;
1142
35
        case    CF_CALCOP("IsEq(A,B)"):
1143
35
            calcop = 5;
1144
35
            break;
1145
3
        case    CF_CALCOP("Sqrt(A)"):
1146
3
            calcop = 6;
1147
3
            break;
1148
7
        case    CF_CALCOP("Not(A)"):
1149
7
            calcop = 7;
1150
7
            break;
1151
30
        case    CF_CALCOP("IsOne(A)"):
1152
30
            calcop = 8;
1153
30
            break;
1154
2
        case    CF_CALCOP("IsZero(A)"):
1155
2
            calcop = 9;
1156
2
            break;
1157
7
        case    CF_CALCOP("Exp(A,B)"):
1158
7
            calcop = 10;
1159
7
            break;
1160
827
        default:
1161
827
            return ret;
1162
1.45k
    }
1163
1164
626
    try {
1165
626
        alt = ds.Get<bool>();
1166
626
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
1167
463
    }
1168
1169
#if 0
1170
    std::optional<std::array<uint8_t, 32 * 12>> bn0_bytes, bn1_bytes;
1171
    std::array<uint8_t, 32 * 12> result;
1172
1173
    CF_CHECK_NE(bn0_bytes = Constantine_detail::LoadFp12(op.bn0), std::nullopt);
1174
    CF_CHECK_NE(bn1_bytes = Constantine_detail::LoadFp12(op.bn1), std::nullopt);
1175
1176
    CF_CHECK_EQ(
1177
            cryptofuzz_constantine_bignumcalc_fp12(
1178
                0,
1179
                calcop,
1180
                bn0_bytes->data(), bn0_bytes->size(),
1181
                bn1_bytes->data(), bn1_bytes->size(),
1182
                alt,
1183
                result.data()), 0);
1184
1185
    ret = Constantine_detail::SaveFp12(result);
1186
#else
1187
626
    std::optional<std::array<uint8_t, 48 * 12>> bn0_bytes, bn1_bytes;
1188
626
    std::array<uint8_t, 48 * 12> result;
1189
1190
626
    CF_CHECK_NE(bn0_bytes = Constantine_detail::LoadFp12<48>(op.bn0), std::nullopt);
1191
528
    CF_CHECK_NE(bn1_bytes = Constantine_detail::LoadFp12<48>(op.bn1), std::nullopt);
1192
1193
454
    CF_CHECK_EQ(
1194
454
            cryptofuzz_constantine_bignumcalc_fp12(
1195
454
                1,
1196
454
                calcop,
1197
454
                bn0_bytes->data(), bn0_bytes->size(),
1198
454
                bn1_bytes->data(), bn1_bytes->size(),
1199
454
                alt,
1200
454
                result.data()), 0);
1201
1202
448
    ret = Constantine_detail::SaveFp12<48>(result);
1203
448
#endif
1204
1205
626
end:
1206
626
    return ret;
1207
448
}
1208
1209
12.8k
bool Constantine::SupportsModularBignumCalc(void) const {
1210
12.8k
    return true;
1211
12.8k
}
1212
1213
24.2k
std::optional<component::Bignum> Constantine::OpBignumCalc(operation::BignumCalc& op) {
1214
24.2k
    if ( op.modulo != std::nullopt ) {
1215
12.8k
        return Constantine_detail::OpBignumCalc_Mod(op);
1216
12.8k
    }
1217
1218
11.3k
    std::optional<component::Bignum> ret = std::nullopt;
1219
11.3k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
1220
1221
11.3k
    if ( op.calcOp.Is(CF_CALCOP("ExpMod(A,B,C)")) ) {
1222
        /* Don't run with even modulus.
1223
         *
1224
         * https://github.com/guidovranken/nimbus-audit/issues/5
1225
         */
1226
451
        const auto s = op.bn2.ToTrimmedString();
1227
451
        if ( (s[s.size()-1] - '0') % 2 == 0 ) {
1228
262
            return ret;
1229
262
        }
1230
1231
189
        std::vector<uint8_t> result;
1232
189
        std::vector<uint8_t> input;
1233
189
        uint64_t gas = 0, loops = 0;
1234
1235
189
        const auto b = Constantine_detail::Pad(ds, *op.bn0.ToBin());
1236
189
        const auto bl = util::DecToBin(std::to_string(b.size()), 32);
1237
189
        const auto e = Constantine_detail::Pad(ds, *op.bn1.ToBin());
1238
189
        const auto el = util::DecToBin(std::to_string(e.size()), 32);
1239
189
        const auto m = Constantine_detail::Pad(ds, *op.bn2.ToBin());
1240
189
        const auto ml = util::DecToBin(std::to_string(m.size()), 32);
1241
189
        input.insert(input.end(), bl->begin(), bl->end());
1242
189
        input.insert(input.end(), el->begin(), el->end());
1243
189
        input.insert(input.end(), ml->begin(), ml->end());
1244
189
        input.insert(input.end(), b.begin(), b.end());
1245
189
        input.insert(input.end(), e.begin(), e.end());
1246
189
        input.insert(input.end(), m.begin(), m.end());
1247
1248
189
        result.resize(m.size());
1249
189
        memset(result.data(), 0, result.size());
1250
1251
        //gas = static_cast<uint64_t>(
1252
        //        Geth_ModExp_RequiredGas(Constantine_detail::toGoSlice(input)));
1253
1254
        /* Enable to test for slow repeated modexp calls */
1255
        //loops = 30000000 / gas;
1256
1257
189
        CF_CHECK_EQ(
1258
189
                cryptofuzz_constantine_bignumcalc_modexp(
1259
189
                    loops,
1260
189
                    input.data(), input.size(),
1261
189
                    m.size(),
1262
189
                    result.data()), 1);
1263
1264
189
        ret = util::BinToDec(result.data(), result.size());
1265
10.8k
    } else {
1266
10.8k
        uint8_t calcop;
1267
10.8k
        switch ( op.calcOp.Get() ) {
1268
11
            case    CF_CALCOP("Add(A,B)"):
1269
11
                calcop = 0;
1270
11
                break;
1271
7
            case    CF_CALCOP("Sub(A,B)"):
1272
7
                calcop = 1;
1273
7
                break;
1274
13
            case    CF_CALCOP("Mul(A,B)"):
1275
13
                calcop = 2;
1276
13
                break;
1277
443
            case    CF_CALCOP("InvMod(A,B)"):
1278
443
                calcop = 3;
1279
443
                break;
1280
47
            case    CF_CALCOP("Sqr(A)"):
1281
47
                calcop = 4;
1282
47
                break;
1283
27
            case    CF_CALCOP("IsEq(A,B)"):
1284
27
                calcop = 5;
1285
27
                break;
1286
2
            case    CF_CALCOP("IsGt(A,B)"):
1287
2
                calcop = 6;
1288
2
                break;
1289
4
            case    CF_CALCOP("IsGte(A,B)"):
1290
4
                calcop = 7;
1291
4
                break;
1292
6
            case    CF_CALCOP("IsLt(A,B)"):
1293
6
                calcop = 8;
1294
6
                break;
1295
7
            case    CF_CALCOP("IsLte(A,B)"):
1296
7
                calcop = 9;
1297
7
                break;
1298
2
            case    CF_CALCOP("IsZero(A)"):
1299
2
                calcop = 10;
1300
2
                break;
1301
2
            case    CF_CALCOP("IsOne(A)"):
1302
2
                calcop = 11;
1303
2
                break;
1304
2
            case    CF_CALCOP("IsOdd(A)"):
1305
2
                calcop = 12;
1306
2
                break;
1307
3
            case    CF_CALCOP("IsEven(A)"):
1308
3
                calcop = 13;
1309
3
                break;
1310
3
            case    CF_CALCOP("Zero()"):
1311
3
                calcop = 14;
1312
3
                break;
1313
2
            case    CF_CALCOP("One()"):
1314
2
                calcop = 15;
1315
2
                break;
1316
2
            case    CF_CALCOP("LSB(A)"):
1317
2
                calcop = 16;
1318
2
                break;
1319
10.3k
            default:
1320
10.3k
                return ret;
1321
10.8k
        }
1322
1323
583
        auto a_bytes = util::DecToBin(op.bn0.ToTrimmedString(), 4096);
1324
583
        if ( a_bytes == std::nullopt ) {
1325
0
            return ret;
1326
0
        }
1327
583
        auto b_bytes = util::DecToBin(op.bn1.ToTrimmedString(), 4096);
1328
583
        if ( b_bytes == std::nullopt ) {
1329
0
            return ret;
1330
0
        }
1331
583
        auto c_bytes = util::DecToBin(op.bn2.ToTrimmedString(), 4096);
1332
583
        if ( c_bytes == std::nullopt ) {
1333
0
            return ret;
1334
0
        }
1335
1336
583
        std::array<uint8_t, 4096> result;
1337
583
        memset(result.data(), 0, result.size());
1338
1339
583
        bool alt = false;
1340
1341
583
        try {
1342
583
            alt = ds.Get<bool>();
1343
583
        } catch ( fuzzing::datasource::Datasource::OutOfData ) {
1344
355
        }
1345
1346
583
        CF_CHECK_EQ(
1347
583
                cryptofuzz_constantine_bignumcalc(
1348
583
                    calcop,
1349
583
                    a_bytes->data(), a_bytes->size(),
1350
583
                    b_bytes->data(), b_bytes->size(),
1351
583
                    c_bytes->data(), c_bytes->size(),
1352
583
                    alt ? 1 : 0,
1353
583
                    result.data()), 1);
1354
1355
296
        if ( op.calcOp.Is(CF_CALCOP("InvMod(A,B)")) ) {
1356
            /* The result of Constantine's invmod and invmod_vartime
1357
             * is undefined is the inverse doesn't exist.
1358
             *
1359
             * Check if the return value is in fact the inverse, return 0
1360
             * otherwise.
1361
             */
1362
221
            const boost::multiprecision::cpp_int A(op.bn0.ToTrimmedString());
1363
221
            const boost::multiprecision::cpp_int B(op.bn1.ToTrimmedString());
1364
221
            const boost::multiprecision::cpp_int Inv(util::BinToDec(result.data(), result.size()));
1365
221
            const boost::multiprecision::cpp_int R = (A * Inv) % B;
1366
1367
221
            if ( R == 1 ) {
1368
165
                ret = util::BinToDec(result.data(), result.size());
1369
165
            } else {
1370
56
                ret = component::Bignum{std::string("0")};
1371
56
            }
1372
221
        } else {
1373
75
            ret = util::BinToDec(result.data(), result.size());
1374
75
        }
1375
296
    }
1376
1377
772
end:
1378
772
    return ret;
1379
11.3k
}
1380
1381
} /* namespace module */
1382
} /* namespace cryptofuzz */