@@ -166,6 +166,240 @@ proc main() =
166166 # Check equality when converting back to natural domain
167167 9 'u64 == cast [uint64 ](r_bytes)
168168
169+ test " Addition mod 2^31 - 2^27 + 1" :
170+ block :
171+ var x, y, z: Fp [BabyBear ]
172+
173+ x.fromUint (80 'u32 )
174+ y.fromUint (10 'u32 )
175+ z.fromUint (90 'u32 )
176+
177+ x += y
178+
179+ var x_bytes: array [4 , byte ]
180+ x_bytes.marshal (x, cpuEndian )
181+ let new_x = cast [uint32 ](x_bytes)
182+
183+ check:
184+ # Check equality in the Montgomery domain
185+ bool (z == x)
186+ # Check equality when converting back to natural domain
187+ new_x == 90 'u32
188+
189+ block :
190+ var x, y, z: Fp [BabyBear ]
191+
192+ x.fromUint (0x 78000000 'u32 ) # p-1
193+ y.fromUint (1 'u32 )
194+ z.fromUint (0 'u32 )
195+
196+ x += y
197+
198+ var x_bytes: array [4 , byte ]
199+ x_bytes.marshal (x, cpuEndian )
200+ let new_x = cast [uint32 ](x_bytes)
201+
202+ check:
203+ # Check equality in the Montgomery domain
204+ bool (z == x)
205+ # Check equality when converting back to natural domain
206+ new_x == 0 'u32
207+
208+ test " Substraction mod 2^31 - 2^27 + 1" :
209+ block :
210+ var x, y, z: Fp [BabyBear ]
211+
212+ x.fromUint (80 'u32 )
213+ y.fromUint (10 'u32 )
214+ z.fromUint (70 'u32 )
215+
216+ x -= y
217+
218+ var x_bytes: array [4 , byte ]
219+ x_bytes.marshal (x, cpuEndian )
220+ let new_x = cast [uint32 ](x_bytes)
221+
222+ check:
223+ # Check equality in the Montgomery domain
224+ bool (z == x)
225+ # Check equality when converting back to natural domain
226+ new_x == 70 'u32
227+
228+ block :
229+ var x, y, z: Fp [BabyBear ]
230+
231+ x.fromUint (0 'u32 )
232+ y.fromUint (1 'u32 )
233+ z.fromUint (0x 78000000 'u32 ) # p-1
234+
235+ x -= y
236+
237+ var x_bytes: array [4 , byte ]
238+ x_bytes.marshal (x, cpuEndian )
239+ let new_x = cast [uint32 ](x_bytes)
240+
241+ check:
242+ # Check equality in the Montgomery domain
243+ bool (z == x)
244+ # Check equality when converting back to natural domain
245+ new_x == 0x 78000000 'u32
246+
247+ test " Multiplication mod 2^31 - 2^27 + 1" :
248+ block :
249+ var x, y, z, r: Fp [BabyBear ]
250+
251+ x.fromUint (10 'u32 )
252+ y.fromUint (10 'u32 )
253+ z.fromUint (100 'u32 )
254+
255+ r.prod (x, y)
256+
257+ var r_bytes: array [4 , byte ]
258+ r_bytes.marshal (r, cpuEndian )
259+ let new_r = cast [uint32 ](r_bytes)
260+
261+ check:
262+ # Check equality in the Montgomery domain
263+ bool (z == r)
264+ # Check equality when converting back to natural domain
265+ new_r == 100 'u32
266+
267+ block :
268+ var x, y, z, r: Fp [BabyBear ]
269+
270+ x.fromUint (0x 10000 'u32 )
271+ y.fromUint (0x 10000 'u32 )
272+ z.fromUint (uint32 ((0x 10000 'u64 * 0x 10000 'u64 ) mod 0x 78000001 'u64 ))
273+
274+ r.prod (x, y)
275+
276+ var r_bytes: array [4 , byte ]
277+ r_bytes.marshal (r, cpuEndian )
278+ let new_r = cast [uint32 ](r_bytes)
279+
280+ check:
281+ # Check equality in the Montgomery domain
282+ bool (z == r)
283+ # Check equality when converting back to natural domain
284+ new_r == uint32 ((0x 10000 'u64 * 0x 10000 'u64 ) mod 0x 78000001 'u64 )
285+
286+ test " Addition mod 2^31 - 2^24 + 1" :
287+ block :
288+ var x, y, z: Fp [KoalaBear ]
289+
290+ x.fromUint (50 'u32 )
291+ y.fromUint (20 'u32 )
292+ z.fromUint (70 'u32 )
293+
294+ x += y
295+
296+ var x_bytes: array [4 , byte ]
297+ x_bytes.marshal (x, cpuEndian )
298+ let new_x = cast [uint32 ](x_bytes)
299+
300+ check:
301+ # Check equality in the Montgomery domain
302+ bool (z == x)
303+ # Check equality when converting back to natural domain
304+ new_x == 70 'u32
305+
306+ block :
307+ var x, y, z: Fp [KoalaBear ]
308+
309+ x.fromUint (0x 7f000000 'u32 ) # p-1
310+ y.fromUint (1 'u32 )
311+ z.fromUint (0 'u32 )
312+
313+ x += y
314+
315+ var x_bytes: array [4 , byte ]
316+ x_bytes.marshal (x, cpuEndian )
317+ let new_x = cast [uint32 ](x_bytes)
318+
319+ check:
320+ # Check equality in the Montgomery domain
321+ bool (z == x)
322+ # Check equality when converting back to natural domain
323+ new_x == 0 'u32
324+
325+ test " Substraction mod 2^31 - 2^24 + 1" :
326+ block :
327+ var x, y, z: Fp [KoalaBear ]
328+
329+ x.fromUint (70 'u32 )
330+ y.fromUint (20 'u32 )
331+ z.fromUint (50 'u32 )
332+
333+ x -= y
334+
335+ var x_bytes: array [4 , byte ]
336+ x_bytes.marshal (x, cpuEndian )
337+ let new_x = cast [uint32 ](x_bytes)
338+
339+ check:
340+ # Check equality in the Montgomery domain
341+ bool (z == x)
342+ # Check equality when converting back to natural domain
343+ new_x == 50 'u32
344+
345+ block :
346+ var x, y, z: Fp [KoalaBear ]
347+
348+ x.fromUint (0 'u32 )
349+ y.fromUint (1 'u32 )
350+ z.fromUint (0x 7f000000 'u32 ) # p-1
351+
352+ x -= y
353+
354+ var x_bytes: array [4 , byte ]
355+ x_bytes.marshal (x, cpuEndian )
356+ let new_x = cast [uint32 ](x_bytes)
357+
358+ check:
359+ # Check equality in the Montgomery domain
360+ bool (z == x)
361+ # Check equality when converting back to natural domain
362+ new_x == 0x 7f000000 'u32
363+
364+ test " Multiplication mod 2^31 - 2^24 + 1" :
365+ block :
366+ var x, y, z, r: Fp [KoalaBear ]
367+
368+ x.fromUint (12 'u32 )
369+ y.fromUint (12 'u32 )
370+ z.fromUint (144 'u32 )
371+
372+ r.prod (x, y)
373+
374+ var r_bytes: array [4 , byte ]
375+ r_bytes.marshal (r, cpuEndian )
376+ let new_r = cast [uint32 ](r_bytes)
377+
378+ check:
379+ # Check equality in the Montgomery domain
380+ bool (z == r)
381+ # Check equality when converting back to natural domain
382+ new_r == 144 'u32
383+
384+ block :
385+ var x, y, z, r: Fp [KoalaBear ]
386+
387+ x.fromUint (0x 10000 'u32 )
388+ y.fromUint (0x 20000 'u32 )
389+ z.fromUint (uint32 ((0x 10000 'u64 * 0x 20000 'u64 ) mod 0x 7f000001 'u64 ))
390+
391+ r.prod (x, y)
392+
393+ var r_bytes: array [4 , byte ]
394+ r_bytes.marshal (r, cpuEndian )
395+ let new_r = cast [uint32 ](r_bytes)
396+
397+ check:
398+ # Check equality in the Montgomery domain
399+ bool (z == r)
400+ # Check equality when converting back to natural domain
401+ new_r == uint32 ((0x 10000 'u64 * 0x 20000 'u64 ) mod 0x 7f000001 'u64 )
402+
169403 test " Addition mod 2^61 - 1" :
170404 block :
171405 var x, y, z: Fp [Mersenne61 ]
@@ -302,7 +536,6 @@ proc main() =
302536 # Check equality when converting back to natural domain
303537 new_r == 2 'u64
304538
305-
306539main ()
307540
308541proc largeField () =
0 commit comments