FK20 CUDA
fptest_mulconst.cu
Go to the documentation of this file.
1 // bls12_381: Arithmetic for BLS12-381
2 // Copyright 2022-2023 Dag Arne Osvik
3 // Copyright 2022-2023 Luan Cardoso dos Santos
4 
5 #include "fp.cuh"
6 #include "fptest.cuh"
7 
8 #define ITER 100
9 
21 __global__ void FpTestMulConst(testval_t *testval) {
22 
23  printf("=== RUN %s\n", __func__);
24 
25  bool pass = true;
26  size_t count = 0;
27 
28  // 2*4 == 8
29 
30  for (int i=0; pass && i<TESTVALS; i++) {
31  fp_t x2x4, x8;
32 
33  fp_cpy(x2x4, testval[i]);
34  fp_cpy(x8, testval[i]);
35 
36  for (int j=0; pass && j<ITER; j++) {
37  fp_t x1;
38  fp_cpy(x1, x2x4);
39 
40  fp_x2(x2x4, x2x4);
41  fp_x4(x2x4, x2x4);
42 
43  fp_x8(x8, x8);
44 
45  if (fp_neq(x2x4, x8)) {
46  pass = false;
47 
48  printf("%d: FAILED: inconsistent result\n", j);
49  fp_print("1 : ", x1);
50  fp_print("2*4 : ", x2x4);
51  fp_print("8 : ", x8);
52  }
53  ++count;
54  }
55  }
56 
57  // 2*2*2*2*2*2 == 4*4*4 == 8*8
58 
59  for (int i=0; pass && i<TESTVALS; i++) {
60  fp_t x2, x4, x8;
61 
62  fp_cpy(x2, testval[i]);
63  fp_cpy(x4, testval[i]);
64  fp_cpy(x8, testval[i]);
65 
66  for (int j=0; pass && j<ITER; j++) {
67  fp_t x1;
68  fp_cpy(x1, x2);
69 
70  fp_x2(x2, x2);
71  fp_x2(x2, x2);
72  fp_x2(x2, x2);
73  fp_x2(x2, x2);
74  fp_x2(x2, x2);
75  fp_x2(x2, x2);
76 
77  fp_x4(x4, x4);
78  fp_x4(x4, x4);
79  fp_x4(x4, x4);
80 
81  fp_x8(x8, x8);
82  fp_x8(x8, x8);
83 
84  if (fp_neq(x2, x4) || fp_neq(x2, x8)) {
85  pass = false;
86 
87  printf("%d: FAILED: inconsistent result\n", j);
88  fp_print("1 : ", x1);
89  fp_print("2^6 : ", x2);
90  fp_print("4^3 : ", x4);
91  fp_print("8^2 : ", x8);
92  }
93  ++count;
94  }
95  }
96 
97  // 3*4 == 12
98 
99  for (int i=0; pass && i<TESTVALS; i++) {
100  fp_t x3x4, x12;
101 
102  fp_cpy(x3x4, testval[i]);
103  fp_cpy(x12, testval[i]);
104 
105  for (int j=0; pass && j<ITER; j++) {
106  fp_t x1;
107  fp_cpy(x1, x3x4);
108 
109  fp_x3(x3x4, x3x4);
110  fp_x4(x3x4, x3x4);
111 
112  fp_x12(x12, x12);
113 
114  if (fp_neq(x3x4, x12)) {
115  pass = false;
116 
117  printf("%d: FAILED: inconsistent result\n", j);
118  fp_print("1 : ", x1);
119  fp_print("3*4 : ", x3x4);
120  fp_print("12 : ", x12);
121  }
122  ++count;
123  }
124  }
125 
126  // 12+8 == 4(3+2)
127 
128  for (int i=0; pass && i<TESTVALS; i++) {
129  fp_t x1, x2, x3, x8, x12, l, r;
130 
131  fp_cpy(l, testval[i]);
132  fp_cpy(r, testval[i]);
133 
134  for (int j=0; pass && j<ITER; j++) {
135 
136  fp_cpy(x1, l);
137 
138  fp_x2(x2, l);
139  fp_x3(x3, l);
140  fp_x8(x8, l);
141  fp_x12(x12, l);
142 
143  fp_add(l, x12, x8);
144 
145  fp_add(r, x3, x2);
146  fp_x4(r, r);
147 
148  if (fp_neq(l, r)) {
149  pass = false;
150 
151  printf("%d: FAILED: inconsistent result\n", i);
152  fp_print("1 : ", x1);
153  fp_print("12+8 : ", l);
154  fp_print("4(3+2) : ", r);
155  }
156  ++count;
157  }
158  }
159 
160  // 3*3*3*2*4*8 == 12*12*12
161 
162  for (int i=0; pass && i<TESTVALS; i++) {
163  fp_t x1, l, r;
164 
165  fp_cpy(l, testval[i]);
166  fp_cpy(r, testval[i]);
167 
168  for (int j=0; pass && j<ITER; j++) {
169 
170  fp_cpy(x1, l);
171 
172  fp_x3(l, l);
173  fp_x3(l, l);
174  fp_x3(l, l);
175  fp_x2(l, l);
176  fp_x4(l, l);
177  fp_x8(l, l);
178 
179  fp_x12(r, r);
180  fp_x12(r, r);
181  fp_x12(r, r);
182 
183  if (fp_neq(l, r)) {
184  pass = false;
185 
186  printf("%d: FAILED: inconsistent result\n", i);
187  fp_print("1 : ", x1);
188  fp_print("3*3*3*2*4*8 : ", l);
189  fp_print("12*12*12 : ", r);
190  }
191  ++count;
192  }
193  }
194 
195  printf("%ld tests\n", count);
196 
197  PRINTPASS(pass);
198 }
199 
200 // vim: ts=4 et sw=4 si
__device__ void fp_print(const char *s, const fp_t &x)
Prints the canonical representation of x to STDOUT.
Definition: fp.cu:39
__device__ bool fp_neq(const fp_t &x, const fp_t &y)
Compares two fp_t residues.
Definition: fp_neq.cu:14
__device__ void fp_add(fp_t &z, const fp_t &x, const fp_t &y)
Computes the sum of two residues x and y modulo p and stores it in z. Device only function.
Definition: fp_add.cu:17
__device__ void fp_x8(fp_t &z, const fp_t &x)
Multiplies x by 8 and stores the result into z.
Definition: fp_x8.cu:15
__device__ void fp_x2(fp_t &z, const fp_t &x)
Multiplies x by 2 and stores the result into z.
Definition: fp_x2.cu:15
__device__ void fp_x12(fp_t &z, const fp_t &x)
Multiplies the residue mod p x by 12 and stores the result into z.
Definition: fp_x12.cu:15
__device__ void fp_x4(fp_t &z, const fp_t &x)
Multiplies x by 4 and stores the result into z.
Definition: fp_x4.cu:15
uint64_t fp_t[6]
Residue modulo p. Any 384-bit representative of each residue is allowed, and stored as a 6-element li...
Definition: fp.cuh:14
__device__ __host__ void fp_cpy(fp_t &z, const fp_t &x)
Copy from x into z.
Definition: fp_cpy.cu:14
__device__ void fp_x3(fp_t &z, const fp_t &x)
Multiplies x by 3 and stores the result into z.
Definition: fp_x3.cu:15
__managed__ testval_t testval[TESTVALS]
Definition: fptest.cu:8
#define TESTVALS
Definition: fptest.cuh:13
__global__ void FpTestMulConst(testval_t *testval)
Test self consistency in multiplication by constant:
#define ITER
#define PRINTPASS(pass)
Definition: test.h:25