-
Notifications
You must be signed in to change notification settings - Fork 25
/
curve_checks.c
122 lines (111 loc) · 3.51 KB
/
curve_checks.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Mina elliptic cruve unit tests
//
// Imported from https://github.com/MinaProtocol/c-reference-signer/blob/master/curve_checks.c
// Do not edit this file
#include <string.h>
#include "curve_checks.h"
#ifdef LEDGER_BUILD
#define CHECK_FAIL return false;
#else
#define CHECK_FAIL fprintf(stderr, "\n!! FAILED %s() at %s:%d !!\n\n", \
__FUNCTION__, __FILE__, __LINE__); \
return false;
#endif
bool curve_checks(void)
{
Affine a3;
Affine a4;
union {
// Fit in stackspace!
Affine a5;
Scalar s2;
} u;
for (size_t i = 0; i < EPOCHS; i++) {
// Test1: On curve after scaling
if (!affine_is_on_curve(&A[i][0])) {
CHECK_FAIL;
}
if (!affine_is_on_curve(&A[i][1])) {
CHECK_FAIL;
}
if (!affine_is_on_curve(&A[i][2])) {
CHECK_FAIL;
}
// Test2: Addition is commutative
// A0 + A1 == A1 + A0
affine_add(&a3, &A[i][0], &A[i][1]); // a3 = A0 + A1
affine_add(&a4, &A[i][1], &A[i][0]); // a4 = A1 + A0
if (!affine_eq(&a3, &a4)) {
CHECK_FAIL;
}
if (!affine_is_on_curve(&a3)) {
CHECK_FAIL;
}
// Test target check: a3 == T0
if (memcmp(&a3, &T[i][0], sizeof(a3)) != 0) {
CHECK_FAIL;
}
// Test3: Scaling commutes with adding scalars
// G*(S0 + S1) == G*S0 + G*S1
scalar_add(u.s2, S[i][0], S[i][1]);
generate_pubkey(&a3, u.s2); // a3 = G*(S0 + S1)
affine_add(&a4, &A[i][0], &A[i][1]); // a4 = G*S0 + G*S1
if (!affine_eq(&a3, &a4)) {
CHECK_FAIL;
}
if (!affine_is_on_curve(&a3)) {
CHECK_FAIL;
}
// Test target check: a3 == T1
if (memcmp(&a3, &T[i][1], sizeof(a3)) != 0) {
CHECK_FAIL;
}
// Test4: Scaling commutes with multiplying scalars
// G*(S0*S1) == S0*(G*S1)
scalar_mul(u.s2, S[i][0], S[i][1]);
generate_pubkey(&a3, u.s2); // a3 = G*(S0*S1)
affine_scalar_mul(&a4, S[i][0], &A[i][1]); // a4 = S0*(G*S1)
if (!affine_eq(&a3, &a4)) {
CHECK_FAIL;
}
if (!affine_is_on_curve(&a3)) {
CHECK_FAIL;
}
// Test target check: a3 == T2
if (memcmp(&a3, &T[i][2], sizeof(a3)) != 0) {
CHECK_FAIL;
}
// Test5: Scaling commutes with negation
// G*(-S0) == -(G*S0)
scalar_negate(u.s2, S[i][0]);
generate_pubkey(&a3, u.s2); // a3 = G*(-S0)
affine_negate(&a4, &A[i][0]); // a4 = -(G*S0)
if (!affine_eq(&a3, &a4)) {
CHECK_FAIL;
}
if (!affine_is_on_curve(&a3)) {
CHECK_FAIL;
}
// Test target check: a3 == T3
if (memcmp(&a3, &T[i][3], sizeof(a3)) != 0) {
CHECK_FAIL;
}
// Test6: Addition is associative
// (A0 + A1) + A2 == A0 + (A1 + A2)
affine_add(&a3, &A[i][0], &A[i][1]);
affine_add(&a4, &a3, &A[i][2]); // a4 = (A0 + A1) + A2
affine_add(&a3, &A[i][1], &A[i][2]);
affine_add(&u.a5, &A[i][0], &a3); // a5 = A0 + (A1 + A2)
if (!affine_eq(&a4, &u.a5)) {
CHECK_FAIL;
}
if (!affine_is_on_curve(&a4)) {
CHECK_FAIL;
}
// Test target check: a4 == T4
if (memcmp(&a4, &T[i][4], sizeof(a4)) != 0) {
CHECK_FAIL;
}
}
return true;
}