Coverage Report

Created: 2023-12-08 07:00

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