authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2022-06-29 15:11:33+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-29 15:11:33+02:00
log234ccb4a5088cd6fa06144d7ba1aceab0596f1cc
tree935448b28b2b694f8066c59e410efae0db737af1
parentea13437ac575329f1198f8422b856ebfcadff4c8
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std.crypto.ecc: add support for the secp256k1 curve (#11880)

std.crypto.ecc: add support for the secp256k1 curve Usage of the secp256k1 elliptic curve recently grew exponentially, since this is the curve used by Bitcoin and other popular blockchains such as Ethereum. With this, Zig has support for all the widely deployed elliptic curves today.

8 files changed, 4933 insertions(+), 0 deletions(-)

lib/std/crypto.zig+2
...@@ -64,6 +64,7 @@ pub const ecc = struct {...@@ -64,6 +64,7 @@ pub const ecc = struct {
64 pub const P256 = @import("crypto/pcurves/p256.zig").P256;64 pub const P256 = @import("crypto/pcurves/p256.zig").P256;
65 pub const P384 = @import("crypto/pcurves/p384.zig").P384;65 pub const P384 = @import("crypto/pcurves/p384.zig").P384;
66 pub const Ristretto255 = @import("crypto/25519/ristretto255.zig").Ristretto255;66 pub const Ristretto255 = @import("crypto/25519/ristretto255.zig").Ristretto255;
67 pub const Secp256k1 = @import("crypto/pcurves/secp256k1.zig").Secp256k1;
67};68};
6869
69/// Hash functions.70/// Hash functions.
...@@ -205,6 +206,7 @@ test {...@@ -205,6 +206,7 @@ test {
205 _ = ecc.P256;206 _ = ecc.P256;
206 _ = ecc.P384;207 _ = ecc.P384;
207 _ = ecc.Ristretto255;208 _ = ecc.Ristretto255;
209 _ = ecc.Secp256k1;
208210
209 _ = hash.blake2;211 _ = hash.blake2;
210 _ = hash.Blake3;212 _ = hash.Blake3;
lib/std/crypto/pcurves/common.zig+11
...@@ -295,6 +295,17 @@ pub fn Field(comptime params: FieldParams) type {...@@ -295,6 +295,17 @@ pub fn Field(comptime params: FieldParams) type {
295 const x63 = x32.sqn(31).mul(x31);295 const x63 = x32.sqn(31).mul(x31);
296 const x126 = x63.sqn(63).mul(x63);296 const x126 = x63.sqn(63).mul(x63);
297 return x126.sqn(126).mul(x126).sqn(3).mul(t111).sqn(33).mul(x32).sqn(64).mul(x2).sqn(30);297 return x126.sqn(126).mul(x126).sqn(3).mul(t111).sqn(33).mul(x32).sqn(64).mul(x2).sqn(30);
298 } else if (field_order == 115792089237316195423570985008687907853269984665640564039457584007908834671663) {
299 const t11 = x2.mul(x2.sq());
300 const t1111 = t11.mul(t11.sqn(2));
301 const t11111 = x2.mul(t1111.sq());
302 const t1111111 = t11.mul(t11111.sqn(2));
303 const x11 = t1111111.sqn(4).mul(t1111);
304 const x22 = x11.sqn(11).mul(x11);
305 const x27 = x22.sqn(5).mul(t11111);
306 const x54 = x27.sqn(27).mul(x27);
307 const x108 = x54.sqn(54).mul(x54);
308 return x108.sqn(108).mul(x108).sqn(7).mul(t1111111).sqn(23).mul(x22).sqn(6).mul(t11).sqn(2);
298 } else {309 } else {
299 return x2.pow(std.meta.Int(.unsigned, field_bits), (field_order + 1) / 4);310 return x2.pow(std.meta.Int(.unsigned, field_bits), (field_order + 1) / 4);
300 }311 }
lib/std/crypto/pcurves/secp256k1.zig created+556
...@@ -0,0 +1,556 @@
1const std = @import("std");
2const crypto = std.crypto;
3const math = std.math;
4const mem = std.mem;
5const meta = std.meta;
6
7const EncodingError = crypto.errors.EncodingError;
8const IdentityElementError = crypto.errors.IdentityElementError;
9const NonCanonicalError = crypto.errors.NonCanonicalError;
10const NotSquareError = crypto.errors.NotSquareError;
11
12/// Group operations over secp256k1.
13pub const Secp256k1 = struct {
14 /// The underlying prime field.
15 pub const Fe = @import("secp256k1/field.zig").Fe;
16 /// Field arithmetic mod the order of the main subgroup.
17 pub const scalar = @import("secp256k1/scalar.zig");
18
19 x: Fe,
20 y: Fe,
21 z: Fe = Fe.one,
22
23 is_base: bool = false,
24
25 /// The secp256k1 base point.
26 pub const basePoint = Secp256k1{
27 .x = Fe.fromInt(55066263022277343669578718895168534326250603453777594175500187360389116729240) catch unreachable,
28 .y = Fe.fromInt(32670510020758816978083085130507043184471273380659243275938904335757337482424) catch unreachable,
29 .z = Fe.one,
30 .is_base = true,
31 };
32
33 /// The secp256k1 neutral element.
34 pub const identityElement = Secp256k1{ .x = Fe.zero, .y = Fe.one, .z = Fe.zero };
35
36 pub const B = Fe.fromInt(7) catch unreachable;
37
38 pub const Endormorphism = struct {
39 const lambda: u256 = 37718080363155996902926221483475020450927657555482586988616620542887997980018;
40 const beta: u256 = 55594575648329892869085402983802832744385952214688224221778511981742606582254;
41
42 const lambda_s = s: {
43 var buf: [32]u8 = undefined;
44 mem.writeIntLittle(u256, &buf, Endormorphism.lambda);
45 break :s buf;
46 };
47
48 pub const SplitScalar = struct {
49 r1: [32]u8,
50 r2: [32]u8,
51 };
52
53 /// Compute r1 and r2 so that k = r1 + r2*lambda (mod L).
54 pub fn splitScalar(s: [32]u8, endian: std.builtin.Endian) SplitScalar {
55 const b1_neg_s = comptime s: {
56 var buf: [32]u8 = undefined;
57 mem.writeIntLittle(u256, &buf, 303414439467246543595250775667605759171);
58 break :s buf;
59 };
60 const b2_neg_s = comptime s: {
61 var buf: [32]u8 = undefined;
62 mem.writeIntLittle(u256, &buf, scalar.field_order - 64502973549206556628585045361533709077);
63 break :s buf;
64 };
65 const k = mem.readInt(u256, &s, endian);
66
67 const t1 = math.mulWide(u256, k, 21949224512762693861512883645436906316123769664773102907882521278123970637873);
68 const t2 = math.mulWide(u256, k, 103246583619904461035481197785446227098457807945486720222659797044629401272177);
69
70 const c1 = @truncate(u128, t1 >> 384) + @truncate(u1, t1 >> 383);
71 const c2 = @truncate(u128, t2 >> 384) + @truncate(u1, t2 >> 383);
72
73 var buf: [32]u8 = undefined;
74
75 mem.writeIntLittle(u256, &buf, c1);
76 const c1x = scalar.mul(buf, b1_neg_s, .Little) catch unreachable;
77
78 mem.writeIntLittle(u256, &buf, c2);
79 const c2x = scalar.mul(buf, b2_neg_s, .Little) catch unreachable;
80
81 const r2 = scalar.add(c1x, c2x, .Little) catch unreachable;
82
83 var r1 = scalar.mul(r2, lambda_s, .Little) catch unreachable;
84 r1 = scalar.sub(s, r1, .Little) catch unreachable;
85
86 return SplitScalar{ .r1 = r1, .r2 = r2 };
87 }
88 };
89
90 /// Reject the neutral element.
91 pub fn rejectIdentity(p: Secp256k1) IdentityElementError!void {
92 if (p.x.isZero()) {
93 return error.IdentityElement;
94 }
95 }
96
97 /// Create a point from affine coordinates after checking that they match the curve equation.
98 pub fn fromAffineCoordinates(p: AffineCoordinates) EncodingError!Secp256k1 {
99 const x = p.x;
100 const y = p.y;
101 const x3B = x.sq().mul(x).add(B);
102 const yy = y.sq();
103 const on_curve = @boolToInt(x3B.equivalent(yy));
104 const is_identity = @boolToInt(x.equivalent(AffineCoordinates.identityElement.x)) & @boolToInt(y.equivalent(AffineCoordinates.identityElement.y));
105 if ((on_curve | is_identity) == 0) {
106 return error.InvalidEncoding;
107 }
108 var ret = Secp256k1{ .x = x, .y = y, .z = Fe.one };
109 ret.z.cMov(Secp256k1.identityElement.z, is_identity);
110 return ret;
111 }
112
113 /// Create a point from serialized affine coordinates.
114 pub fn fromSerializedAffineCoordinates(xs: [32]u8, ys: [32]u8, endian: std.builtin.Endian) (NonCanonicalError || EncodingError)!Secp256k1 {
115 const x = try Fe.fromBytes(xs, endian);
116 const y = try Fe.fromBytes(ys, endian);
117 return fromAffineCoordinates(.{ .x = x, .y = y });
118 }
119
120 /// Recover the Y coordinate from the X coordinate.
121 pub fn recoverY(x: Fe, is_odd: bool) NotSquareError!Fe {
122 const x3B = x.sq().mul(x).add(B);
123 var y = try x3B.sqrt();
124 const yn = y.neg();
125 y.cMov(yn, @boolToInt(is_odd) ^ @boolToInt(y.isOdd()));
126 return y;
127 }
128
129 /// Deserialize a SEC1-encoded point.
130 pub fn fromSec1(s: []const u8) (EncodingError || NotSquareError || NonCanonicalError)!Secp256k1 {
131 if (s.len < 1) return error.InvalidEncoding;
132 const encoding_type = s[0];
133 const encoded = s[1..];
134 switch (encoding_type) {
135 0 => {
136 if (encoded.len != 0) return error.InvalidEncoding;
137 return Secp256k1.identityElement;
138 },
139 2, 3 => {
140 if (encoded.len != 32) return error.InvalidEncoding;
141 const x = try Fe.fromBytes(encoded[0..32].*, .Big);
142 const y_is_odd = (encoding_type == 3);
143 const y = try recoverY(x, y_is_odd);
144 return Secp256k1{ .x = x, .y = y };
145 },
146 4 => {
147 if (encoded.len != 64) return error.InvalidEncoding;
148 const x = try Fe.fromBytes(encoded[0..32].*, .Big);
149 const y = try Fe.fromBytes(encoded[32..64].*, .Big);
150 return Secp256k1.fromAffineCoordinates(.{ .x = x, .y = y });
151 },
152 else => return error.InvalidEncoding,
153 }
154 }
155
156 /// Serialize a point using the compressed SEC-1 format.
157 pub fn toCompressedSec1(p: Secp256k1) [33]u8 {
158 var out: [33]u8 = undefined;
159 const xy = p.affineCoordinates();
160 out[0] = if (xy.y.isOdd()) 3 else 2;
161 mem.copy(u8, out[1..], &xy.x.toBytes(.Big));
162 return out;
163 }
164
165 /// Serialize a point using the uncompressed SEC-1 format.
166 pub fn toUncompressedSec1(p: Secp256k1) [65]u8 {
167 var out: [65]u8 = undefined;
168 out[0] = 4;
169 const xy = p.affineCoordinates();
170 mem.copy(u8, out[1..33], &xy.x.toBytes(.Big));
171 mem.copy(u8, out[33..65], &xy.y.toBytes(.Big));
172 return out;
173 }
174
175 /// Return a random point.
176 pub fn random() Secp256k1 {
177 const n = scalar.random(.Little);
178 return basePoint.mul(n, .Little) catch unreachable;
179 }
180
181 /// Flip the sign of the X coordinate.
182 pub fn neg(p: Secp256k1) Secp256k1 {
183 return .{ .x = p.x, .y = p.y.neg(), .z = p.z };
184 }
185
186 /// Double a secp256k1 point.
187 // Algorithm 9 from https://eprint.iacr.org/2015/1060.pdf
188 pub fn dbl(p: Secp256k1) Secp256k1 {
189 var t0 = p.y.sq();
190 var Z3 = t0.dbl();
191 Z3 = Z3.dbl();
192 Z3 = Z3.dbl();
193 var t1 = p.y.mul(p.z);
194 var t2 = p.z.sq();
195 // b3 = (2^2)^2 + 2^2 + 1
196 const t2_4 = t2.dbl().dbl();
197 t2 = t2_4.dbl().dbl().add(t2_4).add(t2);
198 var X3 = t2.mul(Z3);
199 var Y3 = t0.add(t2);
200 Z3 = t1.mul(Z3);
201 t1 = t2.dbl();
202 t2 = t1.add(t2);
203 t0 = t0.sub(t2);
204 Y3 = t0.mul(Y3);
205 Y3 = X3.add(Y3);
206 t1 = p.x.mul(p.y);
207 X3 = t0.mul(t1);
208 X3 = X3.dbl();
209 return .{
210 .x = X3,
211 .y = Y3,
212 .z = Z3,
213 };
214 }
215
216 /// Add secp256k1 points, the second being specified using affine coordinates.
217 // Algorithm 8 from https://eprint.iacr.org/2015/1060.pdf
218 pub fn addMixed(p: Secp256k1, q: AffineCoordinates) Secp256k1 {
219 var t0 = p.x.mul(q.x);
220 var t1 = p.y.mul(q.y);
221 var t3 = q.x.add(q.y);
222 var t4 = p.x.add(p.y1);
223 t3 = t3.mul(t4);
224 t4 = t0.add(t1);
225 t3 = t3.sub(t4);
226 t4 = q.y.mul(p.z);
227 t4 = t4.add(p.y);
228 var Y3 = q.x.mul(p.z);
229 Y3 = Y3.add(p.x);
230 var X3 = t0.dbl();
231 t0 = X3.add(t0);
232 // b3 = (2^2)^2 + 2^2 + 1
233 const t2_4 = p.z.dbl().dbl();
234 var t2 = t2_4.dbl().dbl().add(t2_4).add(p.z);
235 var Z3 = t1.add(t2);
236 t1 = t1.sub(t2);
237 const Y3_4 = Y3.dbl().dbl();
238 Y3 = Y3_4.dbl().dbl().add(Y3_4).add(Y3);
239 X3 = t4.mul(Y3);
240 t2 = t3.mul(t1);
241 X3 = t2.sub(X3);
242 Y3 = Y3.mul(t0);
243 t1 = t1.mul(Z3);
244 Y3 = t1.add(Y3);
245 t0 = t0.mul(t3);
246 Z3 = Z3.mul(t4);
247 Z3 = Z3.add(t0);
248
249 var ret = Secp256k1{
250 .x = X3,
251 .y = Y3,
252 .z = Z3,
253 };
254 ret.cMov(p, @boolToInt(q.x.isZero()));
255 return ret;
256 }
257
258 /// Add secp256k1 points.
259 // Algorithm 7 from https://eprint.iacr.org/2015/1060.pdf
260 pub fn add(p: Secp256k1, q: Secp256k1) Secp256k1 {
261 var t0 = p.x.mul(q.x);
262 var t1 = p.y.mul(q.y);
263 var t2 = p.z.mul(q.z);
264 var t3 = p.x.add(p.y);
265 var t4 = q.x.add(q.y);
266 t3 = t3.mul(t4);
267 t4 = t0.add(t1);
268 t3 = t3.sub(t4);
269 t4 = p.y.add(p.z);
270 var X3 = q.y.add(q.z);
271 t4 = t4.mul(X3);
272 X3 = t1.add(t2);
273 t4 = t4.sub(X3);
274 X3 = p.x.add(p.z);
275 var Y3 = q.x.add(q.z);
276 X3 = X3.mul(Y3);
277 Y3 = t0.add(t2);
278 Y3 = X3.sub(Y3);
279 X3 = t0.dbl();
280 t0 = X3.add(t0);
281 // b3 = (2^2)^2 + 2^2 + 1
282 const t2_4 = t2.dbl().dbl();
283 t2 = t2_4.dbl().dbl().add(t2_4).add(t2);
284 var Z3 = t1.add(t2);
285 t1 = t1.sub(t2);
286 const Y3_4 = Y3.dbl().dbl();
287 Y3 = Y3_4.dbl().dbl().add(Y3_4).add(Y3);
288 X3 = t4.mul(Y3);
289 t2 = t3.mul(t1);
290 X3 = t2.sub(X3);
291 Y3 = Y3.mul(t0);
292 t1 = t1.mul(Z3);
293 Y3 = t1.add(Y3);
294 t0 = t0.mul(t3);
295 Z3 = Z3.mul(t4);
296 Z3 = Z3.add(t0);
297
298 return .{
299 .x = X3,
300 .y = Y3,
301 .z = Z3,
302 };
303 }
304
305 /// Subtract secp256k1 points.
306 pub fn sub(p: Secp256k1, q: Secp256k1) Secp256k1 {
307 return p.add(q.neg());
308 }
309
310 /// Subtract secp256k1 points, the second being specified using affine coordinates.
311 pub fn subMixed(p: Secp256k1, q: AffineCoordinates) Secp256k1 {
312 return p.addMixed(q.neg());
313 }
314
315 /// Return affine coordinates.
316 pub fn affineCoordinates(p: Secp256k1) AffineCoordinates {
317 const zinv = p.z.invert();
318 var ret = AffineCoordinates{
319 .x = p.x.mul(zinv),
320 .y = p.y.mul(zinv),
321 };
322 ret.cMov(AffineCoordinates.identityElement, @boolToInt(p.x.isZero()));
323 return ret;
324 }
325
326 /// Return true if both coordinate sets represent the same point.
327 pub fn equivalent(a: Secp256k1, b: Secp256k1) bool {
328 if (a.sub(b).rejectIdentity()) {
329 return false;
330 } else |_| {
331 return true;
332 }
333 }
334
335 fn cMov(p: *Secp256k1, a: Secp256k1, c: u1) void {
336 p.x.cMov(a.x, c);
337 p.y.cMov(a.y, c);
338 p.z.cMov(a.z, c);
339 }
340
341 fn pcSelect(comptime n: usize, pc: *const [n]Secp256k1, b: u8) Secp256k1 {
342 var t = Secp256k1.identityElement;
343 comptime var i: u8 = 1;
344 inline while (i < pc.len) : (i += 1) {
345 t.cMov(pc[i], @truncate(u1, (@as(usize, b ^ i) -% 1) >> 8));
346 }
347 return t;
348 }
349
350 fn slide(s: [32]u8) [2 * 32 + 1]i8 {
351 var e: [2 * 32 + 1]i8 = undefined;
352 for (s) |x, i| {
353 e[i * 2 + 0] = @as(i8, @truncate(u4, x));
354 e[i * 2 + 1] = @as(i8, @truncate(u4, x >> 4));
355 }
356 // Now, e[0..63] is between 0 and 15, e[63] is between 0 and 7
357 var carry: i8 = 0;
358 for (e[0..64]) |*x| {
359 x.* += carry;
360 carry = (x.* + 8) >> 4;
361 x.* -= carry * 16;
362 std.debug.assert(x.* >= -8 and x.* <= 8);
363 }
364 e[64] = carry;
365 // Now, e[*] is between -8 and 8, including e[64]
366 std.debug.assert(carry >= -8 and carry <= 8);
367 return e;
368 }
369
370 fn pcMul(pc: *const [9]Secp256k1, s: [32]u8, comptime vartime: bool) IdentityElementError!Secp256k1 {
371 std.debug.assert(vartime);
372 const e = slide(s);
373 var q = Secp256k1.identityElement;
374 var pos = e.len - 1;
375 while (true) : (pos -= 1) {
376 const slot = e[pos];
377 if (slot > 0) {
378 q = q.add(pc[@intCast(usize, slot)]);
379 } else if (slot < 0) {
380 q = q.sub(pc[@intCast(usize, -slot)]);
381 }
382 if (pos == 0) break;
383 q = q.dbl().dbl().dbl().dbl();
384 }
385 try q.rejectIdentity();
386 return q;
387 }
388
389 fn pcMul16(pc: *const [16]Secp256k1, s: [32]u8, comptime vartime: bool) IdentityElementError!Secp256k1 {
390 var q = Secp256k1.identityElement;
391 var pos: usize = 252;
392 while (true) : (pos -= 4) {
393 const slot = @truncate(u4, (s[pos >> 3] >> @truncate(u3, pos)));
394 if (vartime) {
395 if (slot != 0) {
396 q = q.add(pc[slot]);
397 }
398 } else {
399 q = q.add(pcSelect(16, pc, slot));
400 }
401 if (pos == 0) break;
402 q = q.dbl().dbl().dbl().dbl();
403 }
404 try q.rejectIdentity();
405 return q;
406 }
407
408 fn precompute(p: Secp256k1, comptime count: usize) [1 + count]Secp256k1 {
409 var pc: [1 + count]Secp256k1 = undefined;
410 pc[0] = Secp256k1.identityElement;
411 pc[1] = p;
412 var i: usize = 2;
413 while (i <= count) : (i += 1) {
414 pc[i] = if (i % 2 == 0) pc[i / 2].dbl() else pc[i - 1].add(p);
415 }
416 return pc;
417 }
418
419 const basePointPc = pc: {
420 @setEvalBranchQuota(50000);
421 break :pc precompute(Secp256k1.basePoint, 15);
422 };
423
424 /// Multiply an elliptic curve point by a scalar.
425 /// Return error.IdentityElement if the result is the identity element.
426 pub fn mul(p: Secp256k1, s_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 {
427 const s = if (endian == .Little) s_ else Fe.orderSwap(s_);
428 if (p.is_base) {
429 return pcMul16(&basePointPc, s, false);
430 }
431 try p.rejectIdentity();
432 const pc = precompute(p, 15);
433 return pcMul16(&pc, s, false);
434 }
435
436 /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME*
437 /// This can be used for signature verification.
438 pub fn mulPublic(p: Secp256k1, s_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 {
439 const s = if (endian == .Little) s_ else Fe.orderSwap(s_);
440 const zero = comptime scalar.Scalar.zero.toBytes(.Little);
441 if (mem.eql(u8, &zero, &s)) {
442 return error.IdentityElement;
443 }
444 const pc = precompute(p, 8);
445 var lambda_p = try pcMul(&pc, Endormorphism.lambda_s, true);
446 var split_scalar = Endormorphism.splitScalar(s, .Little);
447 var px = p;
448
449 // If a key is negative, flip the sign to keep it half-sized,
450 // and flip the sign of the Y point coordinate to compensate.
451 if (split_scalar.r1[split_scalar.r1.len / 2] != 0) {
452 split_scalar.r1 = scalar.neg(split_scalar.r1, .Little) catch zero;
453 px = px.neg();
454 }
455 if (split_scalar.r2[split_scalar.r2.len / 2] != 0) {
456 split_scalar.r2 = scalar.neg(split_scalar.r2, .Little) catch zero;
457 lambda_p = lambda_p.neg();
458 }
459 return mulDoubleBasePublicEndo(px, split_scalar.r1, lambda_p, split_scalar.r2);
460 }
461
462 // Half-size double-base public multiplication when using the curve endomorphism.
463 // Scalars must be in little-endian.
464 // The second point is unlikely to be the generator, so don't even try to use the comptime table for it.
465 fn mulDoubleBasePublicEndo(p1: Secp256k1, s1: [32]u8, p2: Secp256k1, s2: [32]u8) IdentityElementError!Secp256k1 {
466 var pc1_array: [9]Secp256k1 = undefined;
467 const pc1 = if (p1.is_base) basePointPc[0..9] else pc: {
468 pc1_array = precompute(p1, 8);
469 break :pc &pc1_array;
470 };
471 const pc2 = precompute(p2, 8);
472 std.debug.assert(s1[s1.len / 2] == 0);
473 std.debug.assert(s2[s2.len / 2] == 0);
474 const e1 = slide(s1);
475 const e2 = slide(s2);
476 var q = Secp256k1.identityElement;
477 var pos: usize = 2 * 32 / 2; // second half is all zero
478 while (true) : (pos -= 1) {
479 const slot1 = e1[pos];
480 if (slot1 > 0) {
481 q = q.add(pc1[@intCast(usize, slot1)]);
482 } else if (slot1 < 0) {
483 q = q.sub(pc1[@intCast(usize, -slot1)]);
484 }
485 const slot2 = e2[pos];
486 if (slot2 > 0) {
487 q = q.add(pc2[@intCast(usize, slot2)]);
488 } else if (slot2 < 0) {
489 q = q.sub(pc2[@intCast(usize, -slot2)]);
490 }
491 if (pos == 0) break;
492 q = q.dbl().dbl().dbl().dbl();
493 }
494 try q.rejectIdentity();
495 return q;
496 }
497
498 /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME*
499 /// This can be used for signature verification.
500 pub fn mulDoubleBasePublic(p1: Secp256k1, s1_: [32]u8, p2: Secp256k1, s2_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 {
501 const s1 = if (endian == .Little) s1_ else Fe.orderSwap(s1_);
502 const s2 = if (endian == .Little) s2_ else Fe.orderSwap(s2_);
503 try p1.rejectIdentity();
504 var pc1_array: [9]Secp256k1 = undefined;
505 const pc1 = if (p1.is_base) basePointPc[0..9] else pc: {
506 pc1_array = precompute(p1, 8);
507 break :pc &pc1_array;
508 };
509 try p2.rejectIdentity();
510 var pc2_array: [9]Secp256k1 = undefined;
511 const pc2 = if (p2.is_base) basePointPc[0..9] else pc: {
512 pc2_array = precompute(p2, 8);
513 break :pc &pc2_array;
514 };
515 const e1 = slide(s1);
516 const e2 = slide(s2);
517 var q = Secp256k1.identityElement;
518 var pos: usize = 2 * 32;
519 while (true) : (pos -= 1) {
520 const slot1 = e1[pos];
521 if (slot1 > 0) {
522 q = q.add(pc1[@intCast(usize, slot1)]);
523 } else if (slot1 < 0) {
524 q = q.sub(pc1[@intCast(usize, -slot1)]);
525 }
526 const slot2 = e2[pos];
527 if (slot2 > 0) {
528 q = q.add(pc2[@intCast(usize, slot2)]);
529 } else if (slot2 < 0) {
530 q = q.sub(pc2[@intCast(usize, -slot2)]);
531 }
532 if (pos == 0) break;
533 q = q.dbl().dbl().dbl().dbl();
534 }
535 try q.rejectIdentity();
536 return q;
537 }
538};
539
540/// A point in affine coordinates.
541pub const AffineCoordinates = struct {
542 x: Secp256k1.Fe,
543 y: Secp256k1.Fe,
544
545 /// Identity element in affine coordinates.
546 pub const identityElement = AffineCoordinates{ .x = Secp256k1.identityElement.x, .y = Secp256k1.identityElement.y };
547
548 fn cMov(p: *AffineCoordinates, a: AffineCoordinates, c: u1) void {
549 p.x.cMov(a.x, c);
550 p.y.cMov(a.y, c);
551 }
552};
553
554test "secp256k1" {
555 _ = @import("tests/secp256k1.zig");
556}
lib/std/crypto/pcurves/secp256k1/field.zig created+12
...@@ -0,0 +1,12 @@
1const std = @import("std");
2const common = @import("../common.zig");
3
4const Field = common.Field;
5
6pub const Fe = Field(.{
7 .fiat = @import("secp256k1_64.zig"),
8 .field_order = 115792089237316195423570985008687907853269984665640564039457584007908834671663,
9 .field_bits = 256,
10 .saturated_bits = 256,
11 .encoded_length = 32,
12});
lib/std/crypto/pcurves/secp256k1/scalar.zig created+227
...@@ -0,0 +1,227 @@
1const std = @import("std");
2const common = @import("../common.zig");
3const crypto = std.crypto;
4const debug = std.debug;
5const math = std.math;
6const mem = std.mem;
7
8const Field = common.Field;
9
10const NonCanonicalError = std.crypto.errors.NonCanonicalError;
11const NotSquareError = std.crypto.errors.NotSquareError;
12
13/// Number of bytes required to encode a scalar.
14pub const encoded_length = 32;
15
16/// A compressed scalar, in canonical form.
17pub const CompressedScalar = [encoded_length]u8;
18
19const Fe = Field(.{
20 .fiat = @import("secp256k1_scalar_64.zig"),
21 .field_order = 115792089237316195423570985008687907852837564279074904382605163141518161494337,
22 .field_bits = 256,
23 .saturated_bits = 256,
24 .encoded_length = encoded_length,
25});
26
27/// The scalar field order.
28pub const field_order = Fe.field_order;
29
30/// Reject a scalar whose encoding is not canonical.
31pub fn rejectNonCanonical(s: CompressedScalar, endian: std.builtin.Endian) NonCanonicalError!void {
32 return Fe.rejectNonCanonical(s, endian);
33}
34
35/// Reduce a 48-bytes scalar to the field size.
36pub fn reduce48(s: [48]u8, endian: std.builtin.Endian) CompressedScalar {
37 return Scalar.fromBytes48(s, endian).toBytes(endian);
38}
39
40/// Reduce a 64-bytes scalar to the field size.
41pub fn reduce64(s: [64]u8, endian: std.builtin.Endian) CompressedScalar {
42 return ScalarDouble.fromBytes64(s, endian).toBytes(endian);
43}
44
45/// Return a*b (mod L)
46pub fn mul(a: CompressedScalar, b: CompressedScalar, endian: std.builtin.Endian) NonCanonicalError!CompressedScalar {
47 return (try Scalar.fromBytes(a, endian)).mul(try Scalar.fromBytes(b, endian)).toBytes(endian);
48}
49
50/// Return a*b+c (mod L)
51pub fn mulAdd(a: CompressedScalar, b: CompressedScalar, c: CompressedScalar, endian: std.builtin.Endian) NonCanonicalError!CompressedScalar {
52 return (try Scalar.fromBytes(a, endian)).mul(try Scalar.fromBytes(b, endian)).add(try Scalar.fromBytes(c, endian)).toBytes(endian);
53}
54
55/// Return a+b (mod L)
56pub fn add(a: CompressedScalar, b: CompressedScalar, endian: std.builtin.Endian) NonCanonicalError!CompressedScalar {
57 return (try Scalar.fromBytes(a, endian)).add(try Scalar.fromBytes(b, endian)).toBytes(endian);
58}
59
60/// Return -s (mod L)
61pub fn neg(s: CompressedScalar, endian: std.builtin.Endian) NonCanonicalError!CompressedScalar {
62 return (try Scalar.fromBytes(s, endian)).neg().toBytes(endian);
63}
64
65/// Return (a-b) (mod L)
66pub fn sub(a: CompressedScalar, b: CompressedScalar, endian: std.builtin.Endian) NonCanonicalError!CompressedScalar {
67 return (try Scalar.fromBytes(a, endian)).sub(try Scalar.fromBytes(b, endian)).toBytes(endian);
68}
69
70/// Return a random scalar
71pub fn random(endian: std.builtin.Endian) CompressedScalar {
72 return Scalar.random().toBytes(endian);
73}
74
75/// A scalar in unpacked representation.
76pub const Scalar = struct {
77 fe: Fe,
78
79 /// Zero.
80 pub const zero = Scalar{ .fe = Fe.zero };
81
82 /// One.
83 pub const one = Scalar{ .fe = Fe.one };
84
85 /// Unpack a serialized representation of a scalar.
86 pub fn fromBytes(s: CompressedScalar, endian: std.builtin.Endian) NonCanonicalError!Scalar {
87 return Scalar{ .fe = try Fe.fromBytes(s, endian) };
88 }
89
90 /// Reduce a 384 bit input to the field size.
91 pub fn fromBytes48(s: [48]u8, endian: std.builtin.Endian) Scalar {
92 const t = ScalarDouble.fromBytes(384, s, endian);
93 return t.reduce(384);
94 }
95
96 /// Reduce a 512 bit input to the field size.
97 pub fn fromBytes64(s: [64]u8, endian: std.builtin.Endian) Scalar {
98 const t = ScalarDouble.fromBytes(512, s, endian);
99 return t.reduce(512);
100 }
101
102 /// Pack a scalar into bytes.
103 pub fn toBytes(n: Scalar, endian: std.builtin.Endian) CompressedScalar {
104 return n.fe.toBytes(endian);
105 }
106
107 /// Return true if the scalar is zero..
108 pub fn isZero(n: Scalar) bool {
109 return n.fe.isZero();
110 }
111
112 /// Return true if a and b are equivalent.
113 pub fn equivalent(a: Scalar, b: Scalar) bool {
114 return a.fe.equivalent(b.fe);
115 }
116
117 /// Compute x+y (mod L)
118 pub fn add(x: Scalar, y: Scalar) Scalar {
119 return Scalar{ .fe = x.fe.add(y.fe) };
120 }
121
122 /// Compute x-y (mod L)
123 pub fn sub(x: Scalar, y: Scalar) Scalar {
124 return Scalar{ .fe = x.fe.sub(y.fe) };
125 }
126
127 /// Compute 2n (mod L)
128 pub fn dbl(n: Scalar) Scalar {
129 return Scalar{ .fe = n.fe.dbl() };
130 }
131
132 /// Compute x*y (mod L)
133 pub fn mul(x: Scalar, y: Scalar) Scalar {
134 return Scalar{ .fe = x.fe.mul(y.fe) };
135 }
136
137 /// Compute x^2 (mod L)
138 pub fn sq(n: Scalar) Scalar {
139 return Scalar{ .fe = n.fe.sq() };
140 }
141
142 /// Compute x^n (mod L)
143 pub fn pow(a: Scalar, comptime T: type, comptime n: T) Scalar {
144 return Scalar{ .fe = a.fe.pow(n) };
145 }
146
147 /// Compute -x (mod L)
148 pub fn neg(n: Scalar) Scalar {
149 return Scalar{ .fe = n.fe.neg() };
150 }
151
152 /// Compute x^-1 (mod L)
153 pub fn invert(n: Scalar) Scalar {
154 return Scalar{ .fe = n.fe.invert() };
155 }
156
157 /// Return true if n is a quadratic residue mod L.
158 pub fn isSquare(n: Scalar) Scalar {
159 return n.fe.isSquare();
160 }
161
162 /// Return the square root of L, or NotSquare if there isn't any solutions.
163 pub fn sqrt(n: Scalar) NotSquareError!Scalar {
164 return Scalar{ .fe = try n.fe.sqrt() };
165 }
166
167 /// Return a random scalar < L.
168 pub fn random() Scalar {
169 var s: [48]u8 = undefined;
170 while (true) {
171 crypto.random.bytes(&s);
172 const n = Scalar.fromBytes48(s, .Little);
173 if (!n.isZero()) {
174 return n;
175 }
176 }
177 }
178};
179
180const ScalarDouble = struct {
181 x1: Fe,
182 x2: Fe,
183 x3: Fe,
184
185 fn fromBytes(comptime bits: usize, s_: [bits / 8]u8, endian: std.builtin.Endian) ScalarDouble {
186 debug.assert(bits > 0 and bits <= 512 and bits >= Fe.saturated_bits and bits <= Fe.saturated_bits * 3);
187
188 var s = s_;
189 if (endian == .Big) {
190 for (s_) |x, i| s[s.len - 1 - i] = x;
191 }
192 var t = ScalarDouble{ .x1 = undefined, .x2 = Fe.zero, .x3 = Fe.zero };
193 {
194 var b = [_]u8{0} ** encoded_length;
195 const len = math.min(s.len, 24);
196 mem.copy(u8, b[0..len], s[0..len]);
197 t.x1 = Fe.fromBytes(b, .Little) catch unreachable;
198 }
199 if (s_.len >= 24) {
200 var b = [_]u8{0} ** encoded_length;
201 const len = math.min(s.len - 24, 24);
202 mem.copy(u8, b[0..len], s[24..][0..len]);
203 t.x2 = Fe.fromBytes(b, .Little) catch unreachable;
204 }
205 if (s_.len >= 48) {
206 var b = [_]u8{0} ** encoded_length;
207 const len = s.len - 48;
208 mem.copy(u8, b[0..len], s[48..][0..len]);
209 t.x3 = Fe.fromBytes(b, .Little) catch unreachable;
210 }
211 return t;
212 }
213
214 fn reduce(expanded: ScalarDouble, comptime bits: usize) Scalar {
215 debug.assert(bits > 0 and bits <= Fe.saturated_bits * 3 and bits <= 512);
216 var fe = expanded.x1;
217 if (bits >= 192) {
218 const st1 = Fe.fromInt(1 << 192) catch unreachable;
219 fe = fe.add(expanded.x2.mul(st1));
220 if (bits >= 384) {
221 const st2 = st1.sq();
222 fe = fe.add(expanded.x3.mul(st2));
223 }
224 }
225 return Scalar{ .fe = fe };
226 }
227};
lib/std/crypto/pcurves/secp256k1/secp256k1_64.zig created+1964
...@@ -0,0 +1,1964 @@
1// Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --lang Zig --internal-static --public-function-case camelCase --private-function-case camelCase --public-type-case UpperCamelCase --private-type-case UpperCamelCase --no-prefix-fiat --package-name secp256k1 '' 64 '2^256 - 2^32 - 977' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp
2// curve description (via package name): secp256k1
3// machine_wordsize = 64 (from "64")
4// requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp
5// m = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f (from "2^256 - 2^32 - 977")
6//
7// NOTE: In addition to the bounds specified above each function, all
8// functions synthesized for this Montgomery arithmetic require the
9// input to be strictly less than the prime modulus (m), and also
10// require the input to be in the unique saturated representation.
11// All functions also ensure that these two properties are true of
12// return values.
13//
14// Computed values:
15// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192)
16// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248)
17// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in
18// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256
19
20const std = @import("std");
21const mode = @import("builtin").mode; // Checked arithmetic is disabled in non-debug modes to avoid side channels
22
23// The type MontgomeryDomainFieldElement is a field element in the Montgomery domain.
24// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
25pub const MontgomeryDomainFieldElement = [4]u64;
26
27// The type NonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain.
28// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
29pub const NonMontgomeryDomainFieldElement = [4]u64;
30
31/// The function addcarryxU64 is an addition with carry.
32///
33/// Postconditions:
34/// out1 = (arg1 + arg2 + arg3) mod 2^64
35/// out2 = ⌊(arg1 + arg2 + arg3) / 2^64⌋
36///
37/// Input Bounds:
38/// arg1: [0x0 ~> 0x1]
39/// arg2: [0x0 ~> 0xffffffffffffffff]
40/// arg3: [0x0 ~> 0xffffffffffffffff]
41/// Output Bounds:
42/// out1: [0x0 ~> 0xffffffffffffffff]
43/// out2: [0x0 ~> 0x1]
44inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
45 @setRuntimeSafety(mode == .Debug);
46
47 var t: u64 = undefined;
48 const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49 const carry2 = @addWithOverflow(u64, t, arg1, out1);
50 out2.* = @boolToInt(carry1) | @boolToInt(carry2);
51}
52
53/// The function subborrowxU64 is a subtraction with borrow.
54///
55/// Postconditions:
56/// out1 = (-arg1 + arg2 + -arg3) mod 2^64
57/// out2 = -⌊(-arg1 + arg2 + -arg3) / 2^64⌋
58///
59/// Input Bounds:
60/// arg1: [0x0 ~> 0x1]
61/// arg2: [0x0 ~> 0xffffffffffffffff]
62/// arg3: [0x0 ~> 0xffffffffffffffff]
63/// Output Bounds:
64/// out1: [0x0 ~> 0xffffffffffffffff]
65/// out2: [0x0 ~> 0x1]
66inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
67 @setRuntimeSafety(mode == .Debug);
68
69 var t: u64 = undefined;
70 const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71 const carry2 = @subWithOverflow(u64, t, arg1, out1);
72 out2.* = @boolToInt(carry1) | @boolToInt(carry2);
73}
74
75/// The function mulxU64 is a multiplication, returning the full double-width result.
76///
77/// Postconditions:
78/// out1 = (arg1 * arg2) mod 2^64
79/// out2 = ⌊arg1 * arg2 / 2^64⌋
80///
81/// Input Bounds:
82/// arg1: [0x0 ~> 0xffffffffffffffff]
83/// arg2: [0x0 ~> 0xffffffffffffffff]
84/// Output Bounds:
85/// out1: [0x0 ~> 0xffffffffffffffff]
86/// out2: [0x0 ~> 0xffffffffffffffff]
87inline fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void {
88 @setRuntimeSafety(mode == .Debug);
89
90 const x = @as(u128, arg1) * @as(u128, arg2);
91 out1.* = @truncate(u64, x);
92 out2.* = @truncate(u64, x >> 64);
93}
94
95/// The function cmovznzU64 is a single-word conditional move.
96///
97/// Postconditions:
98/// out1 = (if arg1 = 0 then arg2 else arg3)
99///
100/// Input Bounds:
101/// arg1: [0x0 ~> 0x1]
102/// arg2: [0x0 ~> 0xffffffffffffffff]
103/// arg3: [0x0 ~> 0xffffffffffffffff]
104/// Output Bounds:
105/// out1: [0x0 ~> 0xffffffffffffffff]
106inline fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void {
107 @setRuntimeSafety(mode == .Debug);
108
109 const mask = 0 -% @as(u64, arg1);
110 out1.* = (mask & arg3) | ((~mask) & arg2);
111}
112
113/// The function mul multiplies two field elements in the Montgomery domain.
114///
115/// Preconditions:
116/// 0 ≤ eval arg1 < m
117/// 0 ≤ eval arg2 < m
118/// Postconditions:
119/// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m
120/// 0 ≤ eval out1 < m
121///
122pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void {
123 @setRuntimeSafety(mode == .Debug);
124
125 const x1 = (arg1[1]);
126 const x2 = (arg1[2]);
127 const x3 = (arg1[3]);
128 const x4 = (arg1[0]);
129 var x5: u64 = undefined;
130 var x6: u64 = undefined;
131 mulxU64(&x5, &x6, x4, (arg2[3]));
132 var x7: u64 = undefined;
133 var x8: u64 = undefined;
134 mulxU64(&x7, &x8, x4, (arg2[2]));
135 var x9: u64 = undefined;
136 var x10: u64 = undefined;
137 mulxU64(&x9, &x10, x4, (arg2[1]));
138 var x11: u64 = undefined;
139 var x12: u64 = undefined;
140 mulxU64(&x11, &x12, x4, (arg2[0]));
141 var x13: u64 = undefined;
142 var x14: u1 = undefined;
143 addcarryxU64(&x13, &x14, 0x0, x12, x9);
144 var x15: u64 = undefined;
145 var x16: u1 = undefined;
146 addcarryxU64(&x15, &x16, x14, x10, x7);
147 var x17: u64 = undefined;
148 var x18: u1 = undefined;
149 addcarryxU64(&x17, &x18, x16, x8, x5);
150 const x19 = (@as(u64, x18) + x6);
151 var x20: u64 = undefined;
152 var x21: u64 = undefined;
153 mulxU64(&x20, &x21, x11, 0xd838091dd2253531);
154 var x22: u64 = undefined;
155 var x23: u64 = undefined;
156 mulxU64(&x22, &x23, x20, 0xffffffffffffffff);
157 var x24: u64 = undefined;
158 var x25: u64 = undefined;
159 mulxU64(&x24, &x25, x20, 0xffffffffffffffff);
160 var x26: u64 = undefined;
161 var x27: u64 = undefined;
162 mulxU64(&x26, &x27, x20, 0xffffffffffffffff);
163 var x28: u64 = undefined;
164 var x29: u64 = undefined;
165 mulxU64(&x28, &x29, x20, 0xfffffffefffffc2f);
166 var x30: u64 = undefined;
167 var x31: u1 = undefined;
168 addcarryxU64(&x30, &x31, 0x0, x29, x26);
169 var x32: u64 = undefined;
170 var x33: u1 = undefined;
171 addcarryxU64(&x32, &x33, x31, x27, x24);
172 var x34: u64 = undefined;
173 var x35: u1 = undefined;
174 addcarryxU64(&x34, &x35, x33, x25, x22);
175 const x36 = (@as(u64, x35) + x23);
176 var x37: u64 = undefined;
177 var x38: u1 = undefined;
178 addcarryxU64(&x37, &x38, 0x0, x11, x28);
179 var x39: u64 = undefined;
180 var x40: u1 = undefined;
181 addcarryxU64(&x39, &x40, x38, x13, x30);
182 var x41: u64 = undefined;
183 var x42: u1 = undefined;
184 addcarryxU64(&x41, &x42, x40, x15, x32);
185 var x43: u64 = undefined;
186 var x44: u1 = undefined;
187 addcarryxU64(&x43, &x44, x42, x17, x34);
188 var x45: u64 = undefined;
189 var x46: u1 = undefined;
190 addcarryxU64(&x45, &x46, x44, x19, x36);
191 var x47: u64 = undefined;
192 var x48: u64 = undefined;
193 mulxU64(&x47, &x48, x1, (arg2[3]));
194 var x49: u64 = undefined;
195 var x50: u64 = undefined;
196 mulxU64(&x49, &x50, x1, (arg2[2]));
197 var x51: u64 = undefined;
198 var x52: u64 = undefined;
199 mulxU64(&x51, &x52, x1, (arg2[1]));
200 var x53: u64 = undefined;
201 var x54: u64 = undefined;
202 mulxU64(&x53, &x54, x1, (arg2[0]));
203 var x55: u64 = undefined;
204 var x56: u1 = undefined;
205 addcarryxU64(&x55, &x56, 0x0, x54, x51);
206 var x57: u64 = undefined;
207 var x58: u1 = undefined;
208 addcarryxU64(&x57, &x58, x56, x52, x49);
209 var x59: u64 = undefined;
210 var x60: u1 = undefined;
211 addcarryxU64(&x59, &x60, x58, x50, x47);
212 const x61 = (@as(u64, x60) + x48);
213 var x62: u64 = undefined;
214 var x63: u1 = undefined;
215 addcarryxU64(&x62, &x63, 0x0, x39, x53);
216 var x64: u64 = undefined;
217 var x65: u1 = undefined;
218 addcarryxU64(&x64, &x65, x63, x41, x55);
219 var x66: u64 = undefined;
220 var x67: u1 = undefined;
221 addcarryxU64(&x66, &x67, x65, x43, x57);
222 var x68: u64 = undefined;
223 var x69: u1 = undefined;
224 addcarryxU64(&x68, &x69, x67, x45, x59);
225 var x70: u64 = undefined;
226 var x71: u1 = undefined;
227 addcarryxU64(&x70, &x71, x69, @as(u64, x46), x61);
228 var x72: u64 = undefined;
229 var x73: u64 = undefined;
230 mulxU64(&x72, &x73, x62, 0xd838091dd2253531);
231 var x74: u64 = undefined;
232 var x75: u64 = undefined;
233 mulxU64(&x74, &x75, x72, 0xffffffffffffffff);
234 var x76: u64 = undefined;
235 var x77: u64 = undefined;
236 mulxU64(&x76, &x77, x72, 0xffffffffffffffff);
237 var x78: u64 = undefined;
238 var x79: u64 = undefined;
239 mulxU64(&x78, &x79, x72, 0xffffffffffffffff);
240 var x80: u64 = undefined;
241 var x81: u64 = undefined;
242 mulxU64(&x80, &x81, x72, 0xfffffffefffffc2f);
243 var x82: u64 = undefined;
244 var x83: u1 = undefined;
245 addcarryxU64(&x82, &x83, 0x0, x81, x78);
246 var x84: u64 = undefined;
247 var x85: u1 = undefined;
248 addcarryxU64(&x84, &x85, x83, x79, x76);
249 var x86: u64 = undefined;
250 var x87: u1 = undefined;
251 addcarryxU64(&x86, &x87, x85, x77, x74);
252 const x88 = (@as(u64, x87) + x75);
253 var x89: u64 = undefined;
254 var x90: u1 = undefined;
255 addcarryxU64(&x89, &x90, 0x0, x62, x80);
256 var x91: u64 = undefined;
257 var x92: u1 = undefined;
258 addcarryxU64(&x91, &x92, x90, x64, x82);
259 var x93: u64 = undefined;
260 var x94: u1 = undefined;
261 addcarryxU64(&x93, &x94, x92, x66, x84);
262 var x95: u64 = undefined;
263 var x96: u1 = undefined;
264 addcarryxU64(&x95, &x96, x94, x68, x86);
265 var x97: u64 = undefined;
266 var x98: u1 = undefined;
267 addcarryxU64(&x97, &x98, x96, x70, x88);
268 const x99 = (@as(u64, x98) + @as(u64, x71));
269 var x100: u64 = undefined;
270 var x101: u64 = undefined;
271 mulxU64(&x100, &x101, x2, (arg2[3]));
272 var x102: u64 = undefined;
273 var x103: u64 = undefined;
274 mulxU64(&x102, &x103, x2, (arg2[2]));
275 var x104: u64 = undefined;
276 var x105: u64 = undefined;
277 mulxU64(&x104, &x105, x2, (arg2[1]));
278 var x106: u64 = undefined;
279 var x107: u64 = undefined;
280 mulxU64(&x106, &x107, x2, (arg2[0]));
281 var x108: u64 = undefined;
282 var x109: u1 = undefined;
283 addcarryxU64(&x108, &x109, 0x0, x107, x104);
284 var x110: u64 = undefined;
285 var x111: u1 = undefined;
286 addcarryxU64(&x110, &x111, x109, x105, x102);
287 var x112: u64 = undefined;
288 var x113: u1 = undefined;
289 addcarryxU64(&x112, &x113, x111, x103, x100);
290 const x114 = (@as(u64, x113) + x101);
291 var x115: u64 = undefined;
292 var x116: u1 = undefined;
293 addcarryxU64(&x115, &x116, 0x0, x91, x106);
294 var x117: u64 = undefined;
295 var x118: u1 = undefined;
296 addcarryxU64(&x117, &x118, x116, x93, x108);
297 var x119: u64 = undefined;
298 var x120: u1 = undefined;
299 addcarryxU64(&x119, &x120, x118, x95, x110);
300 var x121: u64 = undefined;
301 var x122: u1 = undefined;
302 addcarryxU64(&x121, &x122, x120, x97, x112);
303 var x123: u64 = undefined;
304 var x124: u1 = undefined;
305 addcarryxU64(&x123, &x124, x122, x99, x114);
306 var x125: u64 = undefined;
307 var x126: u64 = undefined;
308 mulxU64(&x125, &x126, x115, 0xd838091dd2253531);
309 var x127: u64 = undefined;
310 var x128: u64 = undefined;
311 mulxU64(&x127, &x128, x125, 0xffffffffffffffff);
312 var x129: u64 = undefined;
313 var x130: u64 = undefined;
314 mulxU64(&x129, &x130, x125, 0xffffffffffffffff);
315 var x131: u64 = undefined;
316 var x132: u64 = undefined;
317 mulxU64(&x131, &x132, x125, 0xffffffffffffffff);
318 var x133: u64 = undefined;
319 var x134: u64 = undefined;
320 mulxU64(&x133, &x134, x125, 0xfffffffefffffc2f);
321 var x135: u64 = undefined;
322 var x136: u1 = undefined;
323 addcarryxU64(&x135, &x136, 0x0, x134, x131);
324 var x137: u64 = undefined;
325 var x138: u1 = undefined;
326 addcarryxU64(&x137, &x138, x136, x132, x129);
327 var x139: u64 = undefined;
328 var x140: u1 = undefined;
329 addcarryxU64(&x139, &x140, x138, x130, x127);
330 const x141 = (@as(u64, x140) + x128);
331 var x142: u64 = undefined;
332 var x143: u1 = undefined;
333 addcarryxU64(&x142, &x143, 0x0, x115, x133);
334 var x144: u64 = undefined;
335 var x145: u1 = undefined;
336 addcarryxU64(&x144, &x145, x143, x117, x135);
337 var x146: u64 = undefined;
338 var x147: u1 = undefined;
339 addcarryxU64(&x146, &x147, x145, x119, x137);
340 var x148: u64 = undefined;
341 var x149: u1 = undefined;
342 addcarryxU64(&x148, &x149, x147, x121, x139);
343 var x150: u64 = undefined;
344 var x151: u1 = undefined;
345 addcarryxU64(&x150, &x151, x149, x123, x141);
346 const x152 = (@as(u64, x151) + @as(u64, x124));
347 var x153: u64 = undefined;
348 var x154: u64 = undefined;
349 mulxU64(&x153, &x154, x3, (arg2[3]));
350 var x155: u64 = undefined;
351 var x156: u64 = undefined;
352 mulxU64(&x155, &x156, x3, (arg2[2]));
353 var x157: u64 = undefined;
354 var x158: u64 = undefined;
355 mulxU64(&x157, &x158, x3, (arg2[1]));
356 var x159: u64 = undefined;
357 var x160: u64 = undefined;
358 mulxU64(&x159, &x160, x3, (arg2[0]));
359 var x161: u64 = undefined;
360 var x162: u1 = undefined;
361 addcarryxU64(&x161, &x162, 0x0, x160, x157);
362 var x163: u64 = undefined;
363 var x164: u1 = undefined;
364 addcarryxU64(&x163, &x164, x162, x158, x155);
365 var x165: u64 = undefined;
366 var x166: u1 = undefined;
367 addcarryxU64(&x165, &x166, x164, x156, x153);
368 const x167 = (@as(u64, x166) + x154);
369 var x168: u64 = undefined;
370 var x169: u1 = undefined;
371 addcarryxU64(&x168, &x169, 0x0, x144, x159);
372 var x170: u64 = undefined;
373 var x171: u1 = undefined;
374 addcarryxU64(&x170, &x171, x169, x146, x161);
375 var x172: u64 = undefined;
376 var x173: u1 = undefined;
377 addcarryxU64(&x172, &x173, x171, x148, x163);
378 var x174: u64 = undefined;
379 var x175: u1 = undefined;
380 addcarryxU64(&x174, &x175, x173, x150, x165);
381 var x176: u64 = undefined;
382 var x177: u1 = undefined;
383 addcarryxU64(&x176, &x177, x175, x152, x167);
384 var x178: u64 = undefined;
385 var x179: u64 = undefined;
386 mulxU64(&x178, &x179, x168, 0xd838091dd2253531);
387 var x180: u64 = undefined;
388 var x181: u64 = undefined;
389 mulxU64(&x180, &x181, x178, 0xffffffffffffffff);
390 var x182: u64 = undefined;
391 var x183: u64 = undefined;
392 mulxU64(&x182, &x183, x178, 0xffffffffffffffff);
393 var x184: u64 = undefined;
394 var x185: u64 = undefined;
395 mulxU64(&x184, &x185, x178, 0xffffffffffffffff);
396 var x186: u64 = undefined;
397 var x187: u64 = undefined;
398 mulxU64(&x186, &x187, x178, 0xfffffffefffffc2f);
399 var x188: u64 = undefined;
400 var x189: u1 = undefined;
401 addcarryxU64(&x188, &x189, 0x0, x187, x184);
402 var x190: u64 = undefined;
403 var x191: u1 = undefined;
404 addcarryxU64(&x190, &x191, x189, x185, x182);
405 var x192: u64 = undefined;
406 var x193: u1 = undefined;
407 addcarryxU64(&x192, &x193, x191, x183, x180);
408 const x194 = (@as(u64, x193) + x181);
409 var x195: u64 = undefined;
410 var x196: u1 = undefined;
411 addcarryxU64(&x195, &x196, 0x0, x168, x186);
412 var x197: u64 = undefined;
413 var x198: u1 = undefined;
414 addcarryxU64(&x197, &x198, x196, x170, x188);
415 var x199: u64 = undefined;
416 var x200: u1 = undefined;
417 addcarryxU64(&x199, &x200, x198, x172, x190);
418 var x201: u64 = undefined;
419 var x202: u1 = undefined;
420 addcarryxU64(&x201, &x202, x200, x174, x192);
421 var x203: u64 = undefined;
422 var x204: u1 = undefined;
423 addcarryxU64(&x203, &x204, x202, x176, x194);
424 const x205 = (@as(u64, x204) + @as(u64, x177));
425 var x206: u64 = undefined;
426 var x207: u1 = undefined;
427 subborrowxU64(&x206, &x207, 0x0, x197, 0xfffffffefffffc2f);
428 var x208: u64 = undefined;
429 var x209: u1 = undefined;
430 subborrowxU64(&x208, &x209, x207, x199, 0xffffffffffffffff);
431 var x210: u64 = undefined;
432 var x211: u1 = undefined;
433 subborrowxU64(&x210, &x211, x209, x201, 0xffffffffffffffff);
434 var x212: u64 = undefined;
435 var x213: u1 = undefined;
436 subborrowxU64(&x212, &x213, x211, x203, 0xffffffffffffffff);
437 var x214: u64 = undefined;
438 var x215: u1 = undefined;
439 subborrowxU64(&x214, &x215, x213, x205, 0x0);
440 var x216: u64 = undefined;
441 cmovznzU64(&x216, x215, x206, x197);
442 var x217: u64 = undefined;
443 cmovznzU64(&x217, x215, x208, x199);
444 var x218: u64 = undefined;
445 cmovznzU64(&x218, x215, x210, x201);
446 var x219: u64 = undefined;
447 cmovznzU64(&x219, x215, x212, x203);
448 out1[0] = x216;
449 out1[1] = x217;
450 out1[2] = x218;
451 out1[3] = x219;
452}
453
454/// The function square squares a field element in the Montgomery domain.
455///
456/// Preconditions:
457/// 0 ≤ eval arg1 < m
458/// Postconditions:
459/// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m
460/// 0 ≤ eval out1 < m
461///
462pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void {
463 @setRuntimeSafety(mode == .Debug);
464
465 const x1 = (arg1[1]);
466 const x2 = (arg1[2]);
467 const x3 = (arg1[3]);
468 const x4 = (arg1[0]);
469 var x5: u64 = undefined;
470 var x6: u64 = undefined;
471 mulxU64(&x5, &x6, x4, (arg1[3]));
472 var x7: u64 = undefined;
473 var x8: u64 = undefined;
474 mulxU64(&x7, &x8, x4, (arg1[2]));
475 var x9: u64 = undefined;
476 var x10: u64 = undefined;
477 mulxU64(&x9, &x10, x4, (arg1[1]));
478 var x11: u64 = undefined;
479 var x12: u64 = undefined;
480 mulxU64(&x11, &x12, x4, (arg1[0]));
481 var x13: u64 = undefined;
482 var x14: u1 = undefined;
483 addcarryxU64(&x13, &x14, 0x0, x12, x9);
484 var x15: u64 = undefined;
485 var x16: u1 = undefined;
486 addcarryxU64(&x15, &x16, x14, x10, x7);
487 var x17: u64 = undefined;
488 var x18: u1 = undefined;
489 addcarryxU64(&x17, &x18, x16, x8, x5);
490 const x19 = (@as(u64, x18) + x6);
491 var x20: u64 = undefined;
492 var x21: u64 = undefined;
493 mulxU64(&x20, &x21, x11, 0xd838091dd2253531);
494 var x22: u64 = undefined;
495 var x23: u64 = undefined;
496 mulxU64(&x22, &x23, x20, 0xffffffffffffffff);
497 var x24: u64 = undefined;
498 var x25: u64 = undefined;
499 mulxU64(&x24, &x25, x20, 0xffffffffffffffff);
500 var x26: u64 = undefined;
501 var x27: u64 = undefined;
502 mulxU64(&x26, &x27, x20, 0xffffffffffffffff);
503 var x28: u64 = undefined;
504 var x29: u64 = undefined;
505 mulxU64(&x28, &x29, x20, 0xfffffffefffffc2f);
506 var x30: u64 = undefined;
507 var x31: u1 = undefined;
508 addcarryxU64(&x30, &x31, 0x0, x29, x26);
509 var x32: u64 = undefined;
510 var x33: u1 = undefined;
511 addcarryxU64(&x32, &x33, x31, x27, x24);
512 var x34: u64 = undefined;
513 var x35: u1 = undefined;
514 addcarryxU64(&x34, &x35, x33, x25, x22);
515 const x36 = (@as(u64, x35) + x23);
516 var x37: u64 = undefined;
517 var x38: u1 = undefined;
518 addcarryxU64(&x37, &x38, 0x0, x11, x28);
519 var x39: u64 = undefined;
520 var x40: u1 = undefined;
521 addcarryxU64(&x39, &x40, x38, x13, x30);
522 var x41: u64 = undefined;
523 var x42: u1 = undefined;
524 addcarryxU64(&x41, &x42, x40, x15, x32);
525 var x43: u64 = undefined;
526 var x44: u1 = undefined;
527 addcarryxU64(&x43, &x44, x42, x17, x34);
528 var x45: u64 = undefined;
529 var x46: u1 = undefined;
530 addcarryxU64(&x45, &x46, x44, x19, x36);
531 var x47: u64 = undefined;
532 var x48: u64 = undefined;
533 mulxU64(&x47, &x48, x1, (arg1[3]));
534 var x49: u64 = undefined;
535 var x50: u64 = undefined;
536 mulxU64(&x49, &x50, x1, (arg1[2]));
537 var x51: u64 = undefined;
538 var x52: u64 = undefined;
539 mulxU64(&x51, &x52, x1, (arg1[1]));
540 var x53: u64 = undefined;
541 var x54: u64 = undefined;
542 mulxU64(&x53, &x54, x1, (arg1[0]));
543 var x55: u64 = undefined;
544 var x56: u1 = undefined;
545 addcarryxU64(&x55, &x56, 0x0, x54, x51);
546 var x57: u64 = undefined;
547 var x58: u1 = undefined;
548 addcarryxU64(&x57, &x58, x56, x52, x49);
549 var x59: u64 = undefined;
550 var x60: u1 = undefined;
551 addcarryxU64(&x59, &x60, x58, x50, x47);
552 const x61 = (@as(u64, x60) + x48);
553 var x62: u64 = undefined;
554 var x63: u1 = undefined;
555 addcarryxU64(&x62, &x63, 0x0, x39, x53);
556 var x64: u64 = undefined;
557 var x65: u1 = undefined;
558 addcarryxU64(&x64, &x65, x63, x41, x55);
559 var x66: u64 = undefined;
560 var x67: u1 = undefined;
561 addcarryxU64(&x66, &x67, x65, x43, x57);
562 var x68: u64 = undefined;
563 var x69: u1 = undefined;
564 addcarryxU64(&x68, &x69, x67, x45, x59);
565 var x70: u64 = undefined;
566 var x71: u1 = undefined;
567 addcarryxU64(&x70, &x71, x69, @as(u64, x46), x61);
568 var x72: u64 = undefined;
569 var x73: u64 = undefined;
570 mulxU64(&x72, &x73, x62, 0xd838091dd2253531);
571 var x74: u64 = undefined;
572 var x75: u64 = undefined;
573 mulxU64(&x74, &x75, x72, 0xffffffffffffffff);
574 var x76: u64 = undefined;
575 var x77: u64 = undefined;
576 mulxU64(&x76, &x77, x72, 0xffffffffffffffff);
577 var x78: u64 = undefined;
578 var x79: u64 = undefined;
579 mulxU64(&x78, &x79, x72, 0xffffffffffffffff);
580 var x80: u64 = undefined;
581 var x81: u64 = undefined;
582 mulxU64(&x80, &x81, x72, 0xfffffffefffffc2f);
583 var x82: u64 = undefined;
584 var x83: u1 = undefined;
585 addcarryxU64(&x82, &x83, 0x0, x81, x78);
586 var x84: u64 = undefined;
587 var x85: u1 = undefined;
588 addcarryxU64(&x84, &x85, x83, x79, x76);
589 var x86: u64 = undefined;
590 var x87: u1 = undefined;
591 addcarryxU64(&x86, &x87, x85, x77, x74);
592 const x88 = (@as(u64, x87) + x75);
593 var x89: u64 = undefined;
594 var x90: u1 = undefined;
595 addcarryxU64(&x89, &x90, 0x0, x62, x80);
596 var x91: u64 = undefined;
597 var x92: u1 = undefined;
598 addcarryxU64(&x91, &x92, x90, x64, x82);
599 var x93: u64 = undefined;
600 var x94: u1 = undefined;
601 addcarryxU64(&x93, &x94, x92, x66, x84);
602 var x95: u64 = undefined;
603 var x96: u1 = undefined;
604 addcarryxU64(&x95, &x96, x94, x68, x86);
605 var x97: u64 = undefined;
606 var x98: u1 = undefined;
607 addcarryxU64(&x97, &x98, x96, x70, x88);
608 const x99 = (@as(u64, x98) + @as(u64, x71));
609 var x100: u64 = undefined;
610 var x101: u64 = undefined;
611 mulxU64(&x100, &x101, x2, (arg1[3]));
612 var x102: u64 = undefined;
613 var x103: u64 = undefined;
614 mulxU64(&x102, &x103, x2, (arg1[2]));
615 var x104: u64 = undefined;
616 var x105: u64 = undefined;
617 mulxU64(&x104, &x105, x2, (arg1[1]));
618 var x106: u64 = undefined;
619 var x107: u64 = undefined;
620 mulxU64(&x106, &x107, x2, (arg1[0]));
621 var x108: u64 = undefined;
622 var x109: u1 = undefined;
623 addcarryxU64(&x108, &x109, 0x0, x107, x104);
624 var x110: u64 = undefined;
625 var x111: u1 = undefined;
626 addcarryxU64(&x110, &x111, x109, x105, x102);
627 var x112: u64 = undefined;
628 var x113: u1 = undefined;
629 addcarryxU64(&x112, &x113, x111, x103, x100);
630 const x114 = (@as(u64, x113) + x101);
631 var x115: u64 = undefined;
632 var x116: u1 = undefined;
633 addcarryxU64(&x115, &x116, 0x0, x91, x106);
634 var x117: u64 = undefined;
635 var x118: u1 = undefined;
636 addcarryxU64(&x117, &x118, x116, x93, x108);
637 var x119: u64 = undefined;
638 var x120: u1 = undefined;
639 addcarryxU64(&x119, &x120, x118, x95, x110);
640 var x121: u64 = undefined;
641 var x122: u1 = undefined;
642 addcarryxU64(&x121, &x122, x120, x97, x112);
643 var x123: u64 = undefined;
644 var x124: u1 = undefined;
645 addcarryxU64(&x123, &x124, x122, x99, x114);
646 var x125: u64 = undefined;
647 var x126: u64 = undefined;
648 mulxU64(&x125, &x126, x115, 0xd838091dd2253531);
649 var x127: u64 = undefined;
650 var x128: u64 = undefined;
651 mulxU64(&x127, &x128, x125, 0xffffffffffffffff);
652 var x129: u64 = undefined;
653 var x130: u64 = undefined;
654 mulxU64(&x129, &x130, x125, 0xffffffffffffffff);
655 var x131: u64 = undefined;
656 var x132: u64 = undefined;
657 mulxU64(&x131, &x132, x125, 0xffffffffffffffff);
658 var x133: u64 = undefined;
659 var x134: u64 = undefined;
660 mulxU64(&x133, &x134, x125, 0xfffffffefffffc2f);
661 var x135: u64 = undefined;
662 var x136: u1 = undefined;
663 addcarryxU64(&x135, &x136, 0x0, x134, x131);
664 var x137: u64 = undefined;
665 var x138: u1 = undefined;
666 addcarryxU64(&x137, &x138, x136, x132, x129);
667 var x139: u64 = undefined;
668 var x140: u1 = undefined;
669 addcarryxU64(&x139, &x140, x138, x130, x127);
670 const x141 = (@as(u64, x140) + x128);
671 var x142: u64 = undefined;
672 var x143: u1 = undefined;
673 addcarryxU64(&x142, &x143, 0x0, x115, x133);
674 var x144: u64 = undefined;
675 var x145: u1 = undefined;
676 addcarryxU64(&x144, &x145, x143, x117, x135);
677 var x146: u64 = undefined;
678 var x147: u1 = undefined;
679 addcarryxU64(&x146, &x147, x145, x119, x137);
680 var x148: u64 = undefined;
681 var x149: u1 = undefined;
682 addcarryxU64(&x148, &x149, x147, x121, x139);
683 var x150: u64 = undefined;
684 var x151: u1 = undefined;
685 addcarryxU64(&x150, &x151, x149, x123, x141);
686 const x152 = (@as(u64, x151) + @as(u64, x124));
687 var x153: u64 = undefined;
688 var x154: u64 = undefined;
689 mulxU64(&x153, &x154, x3, (arg1[3]));
690 var x155: u64 = undefined;
691 var x156: u64 = undefined;
692 mulxU64(&x155, &x156, x3, (arg1[2]));
693 var x157: u64 = undefined;
694 var x158: u64 = undefined;
695 mulxU64(&x157, &x158, x3, (arg1[1]));
696 var x159: u64 = undefined;
697 var x160: u64 = undefined;
698 mulxU64(&x159, &x160, x3, (arg1[0]));
699 var x161: u64 = undefined;
700 var x162: u1 = undefined;
701 addcarryxU64(&x161, &x162, 0x0, x160, x157);
702 var x163: u64 = undefined;
703 var x164: u1 = undefined;
704 addcarryxU64(&x163, &x164, x162, x158, x155);
705 var x165: u64 = undefined;
706 var x166: u1 = undefined;
707 addcarryxU64(&x165, &x166, x164, x156, x153);
708 const x167 = (@as(u64, x166) + x154);
709 var x168: u64 = undefined;
710 var x169: u1 = undefined;
711 addcarryxU64(&x168, &x169, 0x0, x144, x159);
712 var x170: u64 = undefined;
713 var x171: u1 = undefined;
714 addcarryxU64(&x170, &x171, x169, x146, x161);
715 var x172: u64 = undefined;
716 var x173: u1 = undefined;
717 addcarryxU64(&x172, &x173, x171, x148, x163);
718 var x174: u64 = undefined;
719 var x175: u1 = undefined;
720 addcarryxU64(&x174, &x175, x173, x150, x165);
721 var x176: u64 = undefined;
722 var x177: u1 = undefined;
723 addcarryxU64(&x176, &x177, x175, x152, x167);
724 var x178: u64 = undefined;
725 var x179: u64 = undefined;
726 mulxU64(&x178, &x179, x168, 0xd838091dd2253531);
727 var x180: u64 = undefined;
728 var x181: u64 = undefined;
729 mulxU64(&x180, &x181, x178, 0xffffffffffffffff);
730 var x182: u64 = undefined;
731 var x183: u64 = undefined;
732 mulxU64(&x182, &x183, x178, 0xffffffffffffffff);
733 var x184: u64 = undefined;
734 var x185: u64 = undefined;
735 mulxU64(&x184, &x185, x178, 0xffffffffffffffff);
736 var x186: u64 = undefined;
737 var x187: u64 = undefined;
738 mulxU64(&x186, &x187, x178, 0xfffffffefffffc2f);
739 var x188: u64 = undefined;
740 var x189: u1 = undefined;
741 addcarryxU64(&x188, &x189, 0x0, x187, x184);
742 var x190: u64 = undefined;
743 var x191: u1 = undefined;
744 addcarryxU64(&x190, &x191, x189, x185, x182);
745 var x192: u64 = undefined;
746 var x193: u1 = undefined;
747 addcarryxU64(&x192, &x193, x191, x183, x180);
748 const x194 = (@as(u64, x193) + x181);
749 var x195: u64 = undefined;
750 var x196: u1 = undefined;
751 addcarryxU64(&x195, &x196, 0x0, x168, x186);
752 var x197: u64 = undefined;
753 var x198: u1 = undefined;
754 addcarryxU64(&x197, &x198, x196, x170, x188);
755 var x199: u64 = undefined;
756 var x200: u1 = undefined;
757 addcarryxU64(&x199, &x200, x198, x172, x190);
758 var x201: u64 = undefined;
759 var x202: u1 = undefined;
760 addcarryxU64(&x201, &x202, x200, x174, x192);
761 var x203: u64 = undefined;
762 var x204: u1 = undefined;
763 addcarryxU64(&x203, &x204, x202, x176, x194);
764 const x205 = (@as(u64, x204) + @as(u64, x177));
765 var x206: u64 = undefined;
766 var x207: u1 = undefined;
767 subborrowxU64(&x206, &x207, 0x0, x197, 0xfffffffefffffc2f);
768 var x208: u64 = undefined;
769 var x209: u1 = undefined;
770 subborrowxU64(&x208, &x209, x207, x199, 0xffffffffffffffff);
771 var x210: u64 = undefined;
772 var x211: u1 = undefined;
773 subborrowxU64(&x210, &x211, x209, x201, 0xffffffffffffffff);
774 var x212: u64 = undefined;
775 var x213: u1 = undefined;
776 subborrowxU64(&x212, &x213, x211, x203, 0xffffffffffffffff);
777 var x214: u64 = undefined;
778 var x215: u1 = undefined;
779 subborrowxU64(&x214, &x215, x213, x205, 0x0);
780 var x216: u64 = undefined;
781 cmovznzU64(&x216, x215, x206, x197);
782 var x217: u64 = undefined;
783 cmovznzU64(&x217, x215, x208, x199);
784 var x218: u64 = undefined;
785 cmovznzU64(&x218, x215, x210, x201);
786 var x219: u64 = undefined;
787 cmovznzU64(&x219, x215, x212, x203);
788 out1[0] = x216;
789 out1[1] = x217;
790 out1[2] = x218;
791 out1[3] = x219;
792}
793
794/// The function add adds two field elements in the Montgomery domain.
795///
796/// Preconditions:
797/// 0 ≤ eval arg1 < m
798/// 0 ≤ eval arg2 < m
799/// Postconditions:
800/// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m
801/// 0 ≤ eval out1 < m
802///
803pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void {
804 @setRuntimeSafety(mode == .Debug);
805
806 var x1: u64 = undefined;
807 var x2: u1 = undefined;
808 addcarryxU64(&x1, &x2, 0x0, (arg1[0]), (arg2[0]));
809 var x3: u64 = undefined;
810 var x4: u1 = undefined;
811 addcarryxU64(&x3, &x4, x2, (arg1[1]), (arg2[1]));
812 var x5: u64 = undefined;
813 var x6: u1 = undefined;
814 addcarryxU64(&x5, &x6, x4, (arg1[2]), (arg2[2]));
815 var x7: u64 = undefined;
816 var x8: u1 = undefined;
817 addcarryxU64(&x7, &x8, x6, (arg1[3]), (arg2[3]));
818 var x9: u64 = undefined;
819 var x10: u1 = undefined;
820 subborrowxU64(&x9, &x10, 0x0, x1, 0xfffffffefffffc2f);
821 var x11: u64 = undefined;
822 var x12: u1 = undefined;
823 subborrowxU64(&x11, &x12, x10, x3, 0xffffffffffffffff);
824 var x13: u64 = undefined;
825 var x14: u1 = undefined;
826 subborrowxU64(&x13, &x14, x12, x5, 0xffffffffffffffff);
827 var x15: u64 = undefined;
828 var x16: u1 = undefined;
829 subborrowxU64(&x15, &x16, x14, x7, 0xffffffffffffffff);
830 var x17: u64 = undefined;
831 var x18: u1 = undefined;
832 subborrowxU64(&x17, &x18, x16, @as(u64, x8), 0x0);
833 var x19: u64 = undefined;
834 cmovznzU64(&x19, x18, x9, x1);
835 var x20: u64 = undefined;
836 cmovznzU64(&x20, x18, x11, x3);
837 var x21: u64 = undefined;
838 cmovznzU64(&x21, x18, x13, x5);
839 var x22: u64 = undefined;
840 cmovznzU64(&x22, x18, x15, x7);
841 out1[0] = x19;
842 out1[1] = x20;
843 out1[2] = x21;
844 out1[3] = x22;
845}
846
847/// The function sub subtracts two field elements in the Montgomery domain.
848///
849/// Preconditions:
850/// 0 ≤ eval arg1 < m
851/// 0 ≤ eval arg2 < m
852/// Postconditions:
853/// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m
854/// 0 ≤ eval out1 < m
855///
856pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void {
857 @setRuntimeSafety(mode == .Debug);
858
859 var x1: u64 = undefined;
860 var x2: u1 = undefined;
861 subborrowxU64(&x1, &x2, 0x0, (arg1[0]), (arg2[0]));
862 var x3: u64 = undefined;
863 var x4: u1 = undefined;
864 subborrowxU64(&x3, &x4, x2, (arg1[1]), (arg2[1]));
865 var x5: u64 = undefined;
866 var x6: u1 = undefined;
867 subborrowxU64(&x5, &x6, x4, (arg1[2]), (arg2[2]));
868 var x7: u64 = undefined;
869 var x8: u1 = undefined;
870 subborrowxU64(&x7, &x8, x6, (arg1[3]), (arg2[3]));
871 var x9: u64 = undefined;
872 cmovznzU64(&x9, x8, 0x0, 0xffffffffffffffff);
873 var x10: u64 = undefined;
874 var x11: u1 = undefined;
875 addcarryxU64(&x10, &x11, 0x0, x1, (x9 & 0xfffffffefffffc2f));
876 var x12: u64 = undefined;
877 var x13: u1 = undefined;
878 addcarryxU64(&x12, &x13, x11, x3, x9);
879 var x14: u64 = undefined;
880 var x15: u1 = undefined;
881 addcarryxU64(&x14, &x15, x13, x5, x9);
882 var x16: u64 = undefined;
883 var x17: u1 = undefined;
884 addcarryxU64(&x16, &x17, x15, x7, x9);
885 out1[0] = x10;
886 out1[1] = x12;
887 out1[2] = x14;
888 out1[3] = x16;
889}
890
891/// The function opp negates a field element in the Montgomery domain.
892///
893/// Preconditions:
894/// 0 ≤ eval arg1 < m
895/// Postconditions:
896/// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m
897/// 0 ≤ eval out1 < m
898///
899pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void {
900 @setRuntimeSafety(mode == .Debug);
901
902 var x1: u64 = undefined;
903 var x2: u1 = undefined;
904 subborrowxU64(&x1, &x2, 0x0, 0x0, (arg1[0]));
905 var x3: u64 = undefined;
906 var x4: u1 = undefined;
907 subborrowxU64(&x3, &x4, x2, 0x0, (arg1[1]));
908 var x5: u64 = undefined;
909 var x6: u1 = undefined;
910 subborrowxU64(&x5, &x6, x4, 0x0, (arg1[2]));
911 var x7: u64 = undefined;
912 var x8: u1 = undefined;
913 subborrowxU64(&x7, &x8, x6, 0x0, (arg1[3]));
914 var x9: u64 = undefined;
915 cmovznzU64(&x9, x8, 0x0, 0xffffffffffffffff);
916 var x10: u64 = undefined;
917 var x11: u1 = undefined;
918 addcarryxU64(&x10, &x11, 0x0, x1, (x9 & 0xfffffffefffffc2f));
919 var x12: u64 = undefined;
920 var x13: u1 = undefined;
921 addcarryxU64(&x12, &x13, x11, x3, x9);
922 var x14: u64 = undefined;
923 var x15: u1 = undefined;
924 addcarryxU64(&x14, &x15, x13, x5, x9);
925 var x16: u64 = undefined;
926 var x17: u1 = undefined;
927 addcarryxU64(&x16, &x17, x15, x7, x9);
928 out1[0] = x10;
929 out1[1] = x12;
930 out1[2] = x14;
931 out1[3] = x16;
932}
933
934/// The function fromMontgomery translates a field element out of the Montgomery domain.
935///
936/// Preconditions:
937/// 0 ≤ eval arg1 < m
938/// Postconditions:
939/// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m
940/// 0 ≤ eval out1 < m
941///
942pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void {
943 @setRuntimeSafety(mode == .Debug);
944
945 const x1 = (arg1[0]);
946 var x2: u64 = undefined;
947 var x3: u64 = undefined;
948 mulxU64(&x2, &x3, x1, 0xd838091dd2253531);
949 var x4: u64 = undefined;
950 var x5: u64 = undefined;
951 mulxU64(&x4, &x5, x2, 0xffffffffffffffff);
952 var x6: u64 = undefined;
953 var x7: u64 = undefined;
954 mulxU64(&x6, &x7, x2, 0xffffffffffffffff);
955 var x8: u64 = undefined;
956 var x9: u64 = undefined;
957 mulxU64(&x8, &x9, x2, 0xffffffffffffffff);
958 var x10: u64 = undefined;
959 var x11: u64 = undefined;
960 mulxU64(&x10, &x11, x2, 0xfffffffefffffc2f);
961 var x12: u64 = undefined;
962 var x13: u1 = undefined;
963 addcarryxU64(&x12, &x13, 0x0, x11, x8);
964 var x14: u64 = undefined;
965 var x15: u1 = undefined;
966 addcarryxU64(&x14, &x15, x13, x9, x6);
967 var x16: u64 = undefined;
968 var x17: u1 = undefined;
969 addcarryxU64(&x16, &x17, x15, x7, x4);
970 var x18: u64 = undefined;
971 var x19: u1 = undefined;
972 addcarryxU64(&x18, &x19, 0x0, x1, x10);
973 var x20: u64 = undefined;
974 var x21: u1 = undefined;
975 addcarryxU64(&x20, &x21, x19, 0x0, x12);
976 var x22: u64 = undefined;
977 var x23: u1 = undefined;
978 addcarryxU64(&x22, &x23, x21, 0x0, x14);
979 var x24: u64 = undefined;
980 var x25: u1 = undefined;
981 addcarryxU64(&x24, &x25, x23, 0x0, x16);
982 var x26: u64 = undefined;
983 var x27: u1 = undefined;
984 addcarryxU64(&x26, &x27, x25, 0x0, (@as(u64, x17) + x5));
985 var x28: u64 = undefined;
986 var x29: u1 = undefined;
987 addcarryxU64(&x28, &x29, 0x0, x20, (arg1[1]));
988 var x30: u64 = undefined;
989 var x31: u1 = undefined;
990 addcarryxU64(&x30, &x31, x29, x22, 0x0);
991 var x32: u64 = undefined;
992 var x33: u1 = undefined;
993 addcarryxU64(&x32, &x33, x31, x24, 0x0);
994 var x34: u64 = undefined;
995 var x35: u1 = undefined;
996 addcarryxU64(&x34, &x35, x33, x26, 0x0);
997 var x36: u64 = undefined;
998 var x37: u64 = undefined;
999 mulxU64(&x36, &x37, x28, 0xd838091dd2253531);
1000 var x38: u64 = undefined;
1001 var x39: u64 = undefined;
1002 mulxU64(&x38, &x39, x36, 0xffffffffffffffff);
1003 var x40: u64 = undefined;
1004 var x41: u64 = undefined;
1005 mulxU64(&x40, &x41, x36, 0xffffffffffffffff);
1006 var x42: u64 = undefined;
1007 var x43: u64 = undefined;
1008 mulxU64(&x42, &x43, x36, 0xffffffffffffffff);
1009 var x44: u64 = undefined;
1010 var x45: u64 = undefined;
1011 mulxU64(&x44, &x45, x36, 0xfffffffefffffc2f);
1012 var x46: u64 = undefined;
1013 var x47: u1 = undefined;
1014 addcarryxU64(&x46, &x47, 0x0, x45, x42);
1015 var x48: u64 = undefined;
1016 var x49: u1 = undefined;
1017 addcarryxU64(&x48, &x49, x47, x43, x40);
1018 var x50: u64 = undefined;
1019 var x51: u1 = undefined;
1020 addcarryxU64(&x50, &x51, x49, x41, x38);
1021 var x52: u64 = undefined;
1022 var x53: u1 = undefined;
1023 addcarryxU64(&x52, &x53, 0x0, x28, x44);
1024 var x54: u64 = undefined;
1025 var x55: u1 = undefined;
1026 addcarryxU64(&x54, &x55, x53, x30, x46);
1027 var x56: u64 = undefined;
1028 var x57: u1 = undefined;
1029 addcarryxU64(&x56, &x57, x55, x32, x48);
1030 var x58: u64 = undefined;
1031 var x59: u1 = undefined;
1032 addcarryxU64(&x58, &x59, x57, x34, x50);
1033 var x60: u64 = undefined;
1034 var x61: u1 = undefined;
1035 addcarryxU64(&x60, &x61, x59, (@as(u64, x35) + @as(u64, x27)), (@as(u64, x51) + x39));
1036 var x62: u64 = undefined;
1037 var x63: u1 = undefined;
1038 addcarryxU64(&x62, &x63, 0x0, x54, (arg1[2]));
1039 var x64: u64 = undefined;
1040 var x65: u1 = undefined;
1041 addcarryxU64(&x64, &x65, x63, x56, 0x0);
1042 var x66: u64 = undefined;
1043 var x67: u1 = undefined;
1044 addcarryxU64(&x66, &x67, x65, x58, 0x0);
1045 var x68: u64 = undefined;
1046 var x69: u1 = undefined;
1047 addcarryxU64(&x68, &x69, x67, x60, 0x0);
1048 var x70: u64 = undefined;
1049 var x71: u64 = undefined;
1050 mulxU64(&x70, &x71, x62, 0xd838091dd2253531);
1051 var x72: u64 = undefined;
1052 var x73: u64 = undefined;
1053 mulxU64(&x72, &x73, x70, 0xffffffffffffffff);
1054 var x74: u64 = undefined;
1055 var x75: u64 = undefined;
1056 mulxU64(&x74, &x75, x70, 0xffffffffffffffff);
1057 var x76: u64 = undefined;
1058 var x77: u64 = undefined;
1059 mulxU64(&x76, &x77, x70, 0xffffffffffffffff);
1060 var x78: u64 = undefined;
1061 var x79: u64 = undefined;
1062 mulxU64(&x78, &x79, x70, 0xfffffffefffffc2f);
1063 var x80: u64 = undefined;
1064 var x81: u1 = undefined;
1065 addcarryxU64(&x80, &x81, 0x0, x79, x76);
1066 var x82: u64 = undefined;
1067 var x83: u1 = undefined;
1068 addcarryxU64(&x82, &x83, x81, x77, x74);
1069 var x84: u64 = undefined;
1070 var x85: u1 = undefined;
1071 addcarryxU64(&x84, &x85, x83, x75, x72);
1072 var x86: u64 = undefined;
1073 var x87: u1 = undefined;
1074 addcarryxU64(&x86, &x87, 0x0, x62, x78);
1075 var x88: u64 = undefined;
1076 var x89: u1 = undefined;
1077 addcarryxU64(&x88, &x89, x87, x64, x80);
1078 var x90: u64 = undefined;
1079 var x91: u1 = undefined;
1080 addcarryxU64(&x90, &x91, x89, x66, x82);
1081 var x92: u64 = undefined;
1082 var x93: u1 = undefined;
1083 addcarryxU64(&x92, &x93, x91, x68, x84);
1084 var x94: u64 = undefined;
1085 var x95: u1 = undefined;
1086 addcarryxU64(&x94, &x95, x93, (@as(u64, x69) + @as(u64, x61)), (@as(u64, x85) + x73));
1087 var x96: u64 = undefined;
1088 var x97: u1 = undefined;
1089 addcarryxU64(&x96, &x97, 0x0, x88, (arg1[3]));
1090 var x98: u64 = undefined;
1091 var x99: u1 = undefined;
1092 addcarryxU64(&x98, &x99, x97, x90, 0x0);
1093 var x100: u64 = undefined;
1094 var x101: u1 = undefined;
1095 addcarryxU64(&x100, &x101, x99, x92, 0x0);
1096 var x102: u64 = undefined;
1097 var x103: u1 = undefined;
1098 addcarryxU64(&x102, &x103, x101, x94, 0x0);
1099 var x104: u64 = undefined;
1100 var x105: u64 = undefined;
1101 mulxU64(&x104, &x105, x96, 0xd838091dd2253531);
1102 var x106: u64 = undefined;
1103 var x107: u64 = undefined;
1104 mulxU64(&x106, &x107, x104, 0xffffffffffffffff);
1105 var x108: u64 = undefined;
1106 var x109: u64 = undefined;
1107 mulxU64(&x108, &x109, x104, 0xffffffffffffffff);
1108 var x110: u64 = undefined;
1109 var x111: u64 = undefined;
1110 mulxU64(&x110, &x111, x104, 0xffffffffffffffff);
1111 var x112: u64 = undefined;
1112 var x113: u64 = undefined;
1113 mulxU64(&x112, &x113, x104, 0xfffffffefffffc2f);
1114 var x114: u64 = undefined;
1115 var x115: u1 = undefined;
1116 addcarryxU64(&x114, &x115, 0x0, x113, x110);
1117 var x116: u64 = undefined;
1118 var x117: u1 = undefined;
1119 addcarryxU64(&x116, &x117, x115, x111, x108);
1120 var x118: u64 = undefined;
1121 var x119: u1 = undefined;
1122 addcarryxU64(&x118, &x119, x117, x109, x106);
1123 var x120: u64 = undefined;
1124 var x121: u1 = undefined;
1125 addcarryxU64(&x120, &x121, 0x0, x96, x112);
1126 var x122: u64 = undefined;
1127 var x123: u1 = undefined;
1128 addcarryxU64(&x122, &x123, x121, x98, x114);
1129 var x124: u64 = undefined;
1130 var x125: u1 = undefined;
1131 addcarryxU64(&x124, &x125, x123, x100, x116);
1132 var x126: u64 = undefined;
1133 var x127: u1 = undefined;
1134 addcarryxU64(&x126, &x127, x125, x102, x118);
1135 var x128: u64 = undefined;
1136 var x129: u1 = undefined;
1137 addcarryxU64(&x128, &x129, x127, (@as(u64, x103) + @as(u64, x95)), (@as(u64, x119) + x107));
1138 var x130: u64 = undefined;
1139 var x131: u1 = undefined;
1140 subborrowxU64(&x130, &x131, 0x0, x122, 0xfffffffefffffc2f);
1141 var x132: u64 = undefined;
1142 var x133: u1 = undefined;
1143 subborrowxU64(&x132, &x133, x131, x124, 0xffffffffffffffff);
1144 var x134: u64 = undefined;
1145 var x135: u1 = undefined;
1146 subborrowxU64(&x134, &x135, x133, x126, 0xffffffffffffffff);
1147 var x136: u64 = undefined;
1148 var x137: u1 = undefined;
1149 subborrowxU64(&x136, &x137, x135, x128, 0xffffffffffffffff);
1150 var x138: u64 = undefined;
1151 var x139: u1 = undefined;
1152 subborrowxU64(&x138, &x139, x137, @as(u64, x129), 0x0);
1153 var x140: u64 = undefined;
1154 cmovznzU64(&x140, x139, x130, x122);
1155 var x141: u64 = undefined;
1156 cmovznzU64(&x141, x139, x132, x124);
1157 var x142: u64 = undefined;
1158 cmovznzU64(&x142, x139, x134, x126);
1159 var x143: u64 = undefined;
1160 cmovznzU64(&x143, x139, x136, x128);
1161 out1[0] = x140;
1162 out1[1] = x141;
1163 out1[2] = x142;
1164 out1[3] = x143;
1165}
1166
1167/// The function toMontgomery translates a field element into the Montgomery domain.
1168///
1169/// Preconditions:
1170/// 0 ≤ eval arg1 < m
1171/// Postconditions:
1172/// eval (from_montgomery out1) mod m = eval arg1 mod m
1173/// 0 ≤ eval out1 < m
1174///
1175pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void {
1176 @setRuntimeSafety(mode == .Debug);
1177
1178 const x1 = (arg1[1]);
1179 const x2 = (arg1[2]);
1180 const x3 = (arg1[3]);
1181 const x4 = (arg1[0]);
1182 var x5: u64 = undefined;
1183 var x6: u64 = undefined;
1184 mulxU64(&x5, &x6, x4, 0x7a2000e90a1);
1185 var x7: u64 = undefined;
1186 var x8: u1 = undefined;
1187 addcarryxU64(&x7, &x8, 0x0, x6, x4);
1188 var x9: u64 = undefined;
1189 var x10: u64 = undefined;
1190 mulxU64(&x9, &x10, x5, 0xd838091dd2253531);
1191 var x11: u64 = undefined;
1192 var x12: u64 = undefined;
1193 mulxU64(&x11, &x12, x9, 0xffffffffffffffff);
1194 var x13: u64 = undefined;
1195 var x14: u64 = undefined;
1196 mulxU64(&x13, &x14, x9, 0xffffffffffffffff);
1197 var x15: u64 = undefined;
1198 var x16: u64 = undefined;
1199 mulxU64(&x15, &x16, x9, 0xffffffffffffffff);
1200 var x17: u64 = undefined;
1201 var x18: u64 = undefined;
1202 mulxU64(&x17, &x18, x9, 0xfffffffefffffc2f);
1203 var x19: u64 = undefined;
1204 var x20: u1 = undefined;
1205 addcarryxU64(&x19, &x20, 0x0, x18, x15);
1206 var x21: u64 = undefined;
1207 var x22: u1 = undefined;
1208 addcarryxU64(&x21, &x22, x20, x16, x13);
1209 var x23: u64 = undefined;
1210 var x24: u1 = undefined;
1211 addcarryxU64(&x23, &x24, x22, x14, x11);
1212 var x25: u64 = undefined;
1213 var x26: u1 = undefined;
1214 addcarryxU64(&x25, &x26, 0x0, x5, x17);
1215 var x27: u64 = undefined;
1216 var x28: u1 = undefined;
1217 addcarryxU64(&x27, &x28, x26, x7, x19);
1218 var x29: u64 = undefined;
1219 var x30: u1 = undefined;
1220 addcarryxU64(&x29, &x30, x28, @as(u64, x8), x21);
1221 var x31: u64 = undefined;
1222 var x32: u1 = undefined;
1223 addcarryxU64(&x31, &x32, x30, 0x0, x23);
1224 var x33: u64 = undefined;
1225 var x34: u1 = undefined;
1226 addcarryxU64(&x33, &x34, x32, 0x0, (@as(u64, x24) + x12));
1227 var x35: u64 = undefined;
1228 var x36: u64 = undefined;
1229 mulxU64(&x35, &x36, x1, 0x7a2000e90a1);
1230 var x37: u64 = undefined;
1231 var x38: u1 = undefined;
1232 addcarryxU64(&x37, &x38, 0x0, x36, x1);
1233 var x39: u64 = undefined;
1234 var x40: u1 = undefined;
1235 addcarryxU64(&x39, &x40, 0x0, x27, x35);
1236 var x41: u64 = undefined;
1237 var x42: u1 = undefined;
1238 addcarryxU64(&x41, &x42, x40, x29, x37);
1239 var x43: u64 = undefined;
1240 var x44: u1 = undefined;
1241 addcarryxU64(&x43, &x44, x42, x31, @as(u64, x38));
1242 var x45: u64 = undefined;
1243 var x46: u1 = undefined;
1244 addcarryxU64(&x45, &x46, x44, x33, 0x0);
1245 var x47: u64 = undefined;
1246 var x48: u64 = undefined;
1247 mulxU64(&x47, &x48, x39, 0xd838091dd2253531);
1248 var x49: u64 = undefined;
1249 var x50: u64 = undefined;
1250 mulxU64(&x49, &x50, x47, 0xffffffffffffffff);
1251 var x51: u64 = undefined;
1252 var x52: u64 = undefined;
1253 mulxU64(&x51, &x52, x47, 0xffffffffffffffff);
1254 var x53: u64 = undefined;
1255 var x54: u64 = undefined;
1256 mulxU64(&x53, &x54, x47, 0xffffffffffffffff);
1257 var x55: u64 = undefined;
1258 var x56: u64 = undefined;
1259 mulxU64(&x55, &x56, x47, 0xfffffffefffffc2f);
1260 var x57: u64 = undefined;
1261 var x58: u1 = undefined;
1262 addcarryxU64(&x57, &x58, 0x0, x56, x53);
1263 var x59: u64 = undefined;
1264 var x60: u1 = undefined;
1265 addcarryxU64(&x59, &x60, x58, x54, x51);
1266 var x61: u64 = undefined;
1267 var x62: u1 = undefined;
1268 addcarryxU64(&x61, &x62, x60, x52, x49);
1269 var x63: u64 = undefined;
1270 var x64: u1 = undefined;
1271 addcarryxU64(&x63, &x64, 0x0, x39, x55);
1272 var x65: u64 = undefined;
1273 var x66: u1 = undefined;
1274 addcarryxU64(&x65, &x66, x64, x41, x57);
1275 var x67: u64 = undefined;
1276 var x68: u1 = undefined;
1277 addcarryxU64(&x67, &x68, x66, x43, x59);
1278 var x69: u64 = undefined;
1279 var x70: u1 = undefined;
1280 addcarryxU64(&x69, &x70, x68, x45, x61);
1281 var x71: u64 = undefined;
1282 var x72: u1 = undefined;
1283 addcarryxU64(&x71, &x72, x70, (@as(u64, x46) + @as(u64, x34)), (@as(u64, x62) + x50));
1284 var x73: u64 = undefined;
1285 var x74: u64 = undefined;
1286 mulxU64(&x73, &x74, x2, 0x7a2000e90a1);
1287 var x75: u64 = undefined;
1288 var x76: u1 = undefined;
1289 addcarryxU64(&x75, &x76, 0x0, x74, x2);
1290 var x77: u64 = undefined;
1291 var x78: u1 = undefined;
1292 addcarryxU64(&x77, &x78, 0x0, x65, x73);
1293 var x79: u64 = undefined;
1294 var x80: u1 = undefined;
1295 addcarryxU64(&x79, &x80, x78, x67, x75);
1296 var x81: u64 = undefined;
1297 var x82: u1 = undefined;
1298 addcarryxU64(&x81, &x82, x80, x69, @as(u64, x76));
1299 var x83: u64 = undefined;
1300 var x84: u1 = undefined;
1301 addcarryxU64(&x83, &x84, x82, x71, 0x0);
1302 var x85: u64 = undefined;
1303 var x86: u64 = undefined;
1304 mulxU64(&x85, &x86, x77, 0xd838091dd2253531);
1305 var x87: u64 = undefined;
1306 var x88: u64 = undefined;
1307 mulxU64(&x87, &x88, x85, 0xffffffffffffffff);
1308 var x89: u64 = undefined;
1309 var x90: u64 = undefined;
1310 mulxU64(&x89, &x90, x85, 0xffffffffffffffff);
1311 var x91: u64 = undefined;
1312 var x92: u64 = undefined;
1313 mulxU64(&x91, &x92, x85, 0xffffffffffffffff);
1314 var x93: u64 = undefined;
1315 var x94: u64 = undefined;
1316 mulxU64(&x93, &x94, x85, 0xfffffffefffffc2f);
1317 var x95: u64 = undefined;
1318 var x96: u1 = undefined;
1319 addcarryxU64(&x95, &x96, 0x0, x94, x91);
1320 var x97: u64 = undefined;
1321 var x98: u1 = undefined;
1322 addcarryxU64(&x97, &x98, x96, x92, x89);
1323 var x99: u64 = undefined;
1324 var x100: u1 = undefined;
1325 addcarryxU64(&x99, &x100, x98, x90, x87);
1326 var x101: u64 = undefined;
1327 var x102: u1 = undefined;
1328 addcarryxU64(&x101, &x102, 0x0, x77, x93);
1329 var x103: u64 = undefined;
1330 var x104: u1 = undefined;
1331 addcarryxU64(&x103, &x104, x102, x79, x95);
1332 var x105: u64 = undefined;
1333 var x106: u1 = undefined;
1334 addcarryxU64(&x105, &x106, x104, x81, x97);
1335 var x107: u64 = undefined;
1336 var x108: u1 = undefined;
1337 addcarryxU64(&x107, &x108, x106, x83, x99);
1338 var x109: u64 = undefined;
1339 var x110: u1 = undefined;
1340 addcarryxU64(&x109, &x110, x108, (@as(u64, x84) + @as(u64, x72)), (@as(u64, x100) + x88));
1341 var x111: u64 = undefined;
1342 var x112: u64 = undefined;
1343 mulxU64(&x111, &x112, x3, 0x7a2000e90a1);
1344 var x113: u64 = undefined;
1345 var x114: u1 = undefined;
1346 addcarryxU64(&x113, &x114, 0x0, x112, x3);
1347 var x115: u64 = undefined;
1348 var x116: u1 = undefined;
1349 addcarryxU64(&x115, &x116, 0x0, x103, x111);
1350 var x117: u64 = undefined;
1351 var x118: u1 = undefined;
1352 addcarryxU64(&x117, &x118, x116, x105, x113);
1353 var x119: u64 = undefined;
1354 var x120: u1 = undefined;
1355 addcarryxU64(&x119, &x120, x118, x107, @as(u64, x114));
1356 var x121: u64 = undefined;
1357 var x122: u1 = undefined;
1358 addcarryxU64(&x121, &x122, x120, x109, 0x0);
1359 var x123: u64 = undefined;
1360 var x124: u64 = undefined;
1361 mulxU64(&x123, &x124, x115, 0xd838091dd2253531);
1362 var x125: u64 = undefined;
1363 var x126: u64 = undefined;
1364 mulxU64(&x125, &x126, x123, 0xffffffffffffffff);
1365 var x127: u64 = undefined;
1366 var x128: u64 = undefined;
1367 mulxU64(&x127, &x128, x123, 0xffffffffffffffff);
1368 var x129: u64 = undefined;
1369 var x130: u64 = undefined;
1370 mulxU64(&x129, &x130, x123, 0xffffffffffffffff);
1371 var x131: u64 = undefined;
1372 var x132: u64 = undefined;
1373 mulxU64(&x131, &x132, x123, 0xfffffffefffffc2f);
1374 var x133: u64 = undefined;
1375 var x134: u1 = undefined;
1376 addcarryxU64(&x133, &x134, 0x0, x132, x129);
1377 var x135: u64 = undefined;
1378 var x136: u1 = undefined;
1379 addcarryxU64(&x135, &x136, x134, x130, x127);
1380 var x137: u64 = undefined;
1381 var x138: u1 = undefined;
1382 addcarryxU64(&x137, &x138, x136, x128, x125);
1383 var x139: u64 = undefined;
1384 var x140: u1 = undefined;
1385 addcarryxU64(&x139, &x140, 0x0, x115, x131);
1386 var x141: u64 = undefined;
1387 var x142: u1 = undefined;
1388 addcarryxU64(&x141, &x142, x140, x117, x133);
1389 var x143: u64 = undefined;
1390 var x144: u1 = undefined;
1391 addcarryxU64(&x143, &x144, x142, x119, x135);
1392 var x145: u64 = undefined;
1393 var x146: u1 = undefined;
1394 addcarryxU64(&x145, &x146, x144, x121, x137);
1395 var x147: u64 = undefined;
1396 var x148: u1 = undefined;
1397 addcarryxU64(&x147, &x148, x146, (@as(u64, x122) + @as(u64, x110)), (@as(u64, x138) + x126));
1398 var x149: u64 = undefined;
1399 var x150: u1 = undefined;
1400 subborrowxU64(&x149, &x150, 0x0, x141, 0xfffffffefffffc2f);
1401 var x151: u64 = undefined;
1402 var x152: u1 = undefined;
1403 subborrowxU64(&x151, &x152, x150, x143, 0xffffffffffffffff);
1404 var x153: u64 = undefined;
1405 var x154: u1 = undefined;
1406 subborrowxU64(&x153, &x154, x152, x145, 0xffffffffffffffff);
1407 var x155: u64 = undefined;
1408 var x156: u1 = undefined;
1409 subborrowxU64(&x155, &x156, x154, x147, 0xffffffffffffffff);
1410 var x157: u64 = undefined;
1411 var x158: u1 = undefined;
1412 subborrowxU64(&x157, &x158, x156, @as(u64, x148), 0x0);
1413 var x159: u64 = undefined;
1414 cmovznzU64(&x159, x158, x149, x141);
1415 var x160: u64 = undefined;
1416 cmovznzU64(&x160, x158, x151, x143);
1417 var x161: u64 = undefined;
1418 cmovznzU64(&x161, x158, x153, x145);
1419 var x162: u64 = undefined;
1420 cmovznzU64(&x162, x158, x155, x147);
1421 out1[0] = x159;
1422 out1[1] = x160;
1423 out1[2] = x161;
1424 out1[3] = x162;
1425}
1426
1427/// The function nonzero outputs a single non-zero word if the input is non-zero and zero otherwise.
1428///
1429/// Preconditions:
1430/// 0 ≤ eval arg1 < m
1431/// Postconditions:
1432/// out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0
1433///
1434/// Input Bounds:
1435/// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1436/// Output Bounds:
1437/// out1: [0x0 ~> 0xffffffffffffffff]
1438pub fn nonzero(out1: *u64, arg1: [4]u64) void {
1439 @setRuntimeSafety(mode == .Debug);
1440
1441 const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3]))));
1442 out1.* = x1;
1443}
1444
1445/// The function selectznz is a multi-limb conditional select.
1446///
1447/// Postconditions:
1448/// out1 = (if arg1 = 0 then arg2 else arg3)
1449///
1450/// Input Bounds:
1451/// arg1: [0x0 ~> 0x1]
1452/// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1453/// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1454/// Output Bounds:
1455/// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1456pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void {
1457 @setRuntimeSafety(mode == .Debug);
1458
1459 var x1: u64 = undefined;
1460 cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0]));
1461 var x2: u64 = undefined;
1462 cmovznzU64(&x2, arg1, (arg2[1]), (arg3[1]));
1463 var x3: u64 = undefined;
1464 cmovznzU64(&x3, arg1, (arg2[2]), (arg3[2]));
1465 var x4: u64 = undefined;
1466 cmovznzU64(&x4, arg1, (arg2[3]), (arg3[3]));
1467 out1[0] = x1;
1468 out1[1] = x2;
1469 out1[2] = x3;
1470 out1[3] = x4;
1471}
1472
1473/// The function toBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order.
1474///
1475/// Preconditions:
1476/// 0 ≤ eval arg1 < m
1477/// Postconditions:
1478/// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31]
1479///
1480/// Input Bounds:
1481/// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1482/// Output Bounds:
1483/// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]]
1484pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void {
1485 @setRuntimeSafety(mode == .Debug);
1486
1487 const x1 = (arg1[3]);
1488 const x2 = (arg1[2]);
1489 const x3 = (arg1[1]);
1490 const x4 = (arg1[0]);
1491 const x5 = @truncate(u8, (x4 & 0xff));
1492 const x6 = (x4 >> 8);
1493 const x7 = @truncate(u8, (x6 & 0xff));
1494 const x8 = (x6 >> 8);
1495 const x9 = @truncate(u8, (x8 & 0xff));
1496 const x10 = (x8 >> 8);
1497 const x11 = @truncate(u8, (x10 & 0xff));
1498 const x12 = (x10 >> 8);
1499 const x13 = @truncate(u8, (x12 & 0xff));
1500 const x14 = (x12 >> 8);
1501 const x15 = @truncate(u8, (x14 & 0xff));
1502 const x16 = (x14 >> 8);
1503 const x17 = @truncate(u8, (x16 & 0xff));
1504 const x18 = @truncate(u8, (x16 >> 8));
1505 const x19 = @truncate(u8, (x3 & 0xff));
1506 const x20 = (x3 >> 8);
1507 const x21 = @truncate(u8, (x20 & 0xff));
1508 const x22 = (x20 >> 8);
1509 const x23 = @truncate(u8, (x22 & 0xff));
1510 const x24 = (x22 >> 8);
1511 const x25 = @truncate(u8, (x24 & 0xff));
1512 const x26 = (x24 >> 8);
1513 const x27 = @truncate(u8, (x26 & 0xff));
1514 const x28 = (x26 >> 8);
1515 const x29 = @truncate(u8, (x28 & 0xff));
1516 const x30 = (x28 >> 8);
1517 const x31 = @truncate(u8, (x30 & 0xff));
1518 const x32 = @truncate(u8, (x30 >> 8));
1519 const x33 = @truncate(u8, (x2 & 0xff));
1520 const x34 = (x2 >> 8);
1521 const x35 = @truncate(u8, (x34 & 0xff));
1522 const x36 = (x34 >> 8);
1523 const x37 = @truncate(u8, (x36 & 0xff));
1524 const x38 = (x36 >> 8);
1525 const x39 = @truncate(u8, (x38 & 0xff));
1526 const x40 = (x38 >> 8);
1527 const x41 = @truncate(u8, (x40 & 0xff));
1528 const x42 = (x40 >> 8);
1529 const x43 = @truncate(u8, (x42 & 0xff));
1530 const x44 = (x42 >> 8);
1531 const x45 = @truncate(u8, (x44 & 0xff));
1532 const x46 = @truncate(u8, (x44 >> 8));
1533 const x47 = @truncate(u8, (x1 & 0xff));
1534 const x48 = (x1 >> 8);
1535 const x49 = @truncate(u8, (x48 & 0xff));
1536 const x50 = (x48 >> 8);
1537 const x51 = @truncate(u8, (x50 & 0xff));
1538 const x52 = (x50 >> 8);
1539 const x53 = @truncate(u8, (x52 & 0xff));
1540 const x54 = (x52 >> 8);
1541 const x55 = @truncate(u8, (x54 & 0xff));
1542 const x56 = (x54 >> 8);
1543 const x57 = @truncate(u8, (x56 & 0xff));
1544 const x58 = (x56 >> 8);
1545 const x59 = @truncate(u8, (x58 & 0xff));
1546 const x60 = @truncate(u8, (x58 >> 8));
1547 out1[0] = x5;
1548 out1[1] = x7;
1549 out1[2] = x9;
1550 out1[3] = x11;
1551 out1[4] = x13;
1552 out1[5] = x15;
1553 out1[6] = x17;
1554 out1[7] = x18;
1555 out1[8] = x19;
1556 out1[9] = x21;
1557 out1[10] = x23;
1558 out1[11] = x25;
1559 out1[12] = x27;
1560 out1[13] = x29;
1561 out1[14] = x31;
1562 out1[15] = x32;
1563 out1[16] = x33;
1564 out1[17] = x35;
1565 out1[18] = x37;
1566 out1[19] = x39;
1567 out1[20] = x41;
1568 out1[21] = x43;
1569 out1[22] = x45;
1570 out1[23] = x46;
1571 out1[24] = x47;
1572 out1[25] = x49;
1573 out1[26] = x51;
1574 out1[27] = x53;
1575 out1[28] = x55;
1576 out1[29] = x57;
1577 out1[30] = x59;
1578 out1[31] = x60;
1579}
1580
1581/// The function fromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order.
1582///
1583/// Preconditions:
1584/// 0 ≤ bytes_eval arg1 < m
1585/// Postconditions:
1586/// eval out1 mod m = bytes_eval arg1 mod m
1587/// 0 ≤ eval out1 < m
1588///
1589/// Input Bounds:
1590/// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]]
1591/// Output Bounds:
1592/// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1593pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void {
1594 @setRuntimeSafety(mode == .Debug);
1595
1596 const x1 = (@as(u64, (arg1[31])) << 56);
1597 const x2 = (@as(u64, (arg1[30])) << 48);
1598 const x3 = (@as(u64, (arg1[29])) << 40);
1599 const x4 = (@as(u64, (arg1[28])) << 32);
1600 const x5 = (@as(u64, (arg1[27])) << 24);
1601 const x6 = (@as(u64, (arg1[26])) << 16);
1602 const x7 = (@as(u64, (arg1[25])) << 8);
1603 const x8 = (arg1[24]);
1604 const x9 = (@as(u64, (arg1[23])) << 56);
1605 const x10 = (@as(u64, (arg1[22])) << 48);
1606 const x11 = (@as(u64, (arg1[21])) << 40);
1607 const x12 = (@as(u64, (arg1[20])) << 32);
1608 const x13 = (@as(u64, (arg1[19])) << 24);
1609 const x14 = (@as(u64, (arg1[18])) << 16);
1610 const x15 = (@as(u64, (arg1[17])) << 8);
1611 const x16 = (arg1[16]);
1612 const x17 = (@as(u64, (arg1[15])) << 56);
1613 const x18 = (@as(u64, (arg1[14])) << 48);
1614 const x19 = (@as(u64, (arg1[13])) << 40);
1615 const x20 = (@as(u64, (arg1[12])) << 32);
1616 const x21 = (@as(u64, (arg1[11])) << 24);
1617 const x22 = (@as(u64, (arg1[10])) << 16);
1618 const x23 = (@as(u64, (arg1[9])) << 8);
1619 const x24 = (arg1[8]);
1620 const x25 = (@as(u64, (arg1[7])) << 56);
1621 const x26 = (@as(u64, (arg1[6])) << 48);
1622 const x27 = (@as(u64, (arg1[5])) << 40);
1623 const x28 = (@as(u64, (arg1[4])) << 32);
1624 const x29 = (@as(u64, (arg1[3])) << 24);
1625 const x30 = (@as(u64, (arg1[2])) << 16);
1626 const x31 = (@as(u64, (arg1[1])) << 8);
1627 const x32 = (arg1[0]);
1628 const x33 = (x31 + @as(u64, x32));
1629 const x34 = (x30 + x33);
1630 const x35 = (x29 + x34);
1631 const x36 = (x28 + x35);
1632 const x37 = (x27 + x36);
1633 const x38 = (x26 + x37);
1634 const x39 = (x25 + x38);
1635 const x40 = (x23 + @as(u64, x24));
1636 const x41 = (x22 + x40);
1637 const x42 = (x21 + x41);
1638 const x43 = (x20 + x42);
1639 const x44 = (x19 + x43);
1640 const x45 = (x18 + x44);
1641 const x46 = (x17 + x45);
1642 const x47 = (x15 + @as(u64, x16));
1643 const x48 = (x14 + x47);
1644 const x49 = (x13 + x48);
1645 const x50 = (x12 + x49);
1646 const x51 = (x11 + x50);
1647 const x52 = (x10 + x51);
1648 const x53 = (x9 + x52);
1649 const x54 = (x7 + @as(u64, x8));
1650 const x55 = (x6 + x54);
1651 const x56 = (x5 + x55);
1652 const x57 = (x4 + x56);
1653 const x58 = (x3 + x57);
1654 const x59 = (x2 + x58);
1655 const x60 = (x1 + x59);
1656 out1[0] = x39;
1657 out1[1] = x46;
1658 out1[2] = x53;
1659 out1[3] = x60;
1660}
1661
1662/// The function setOne returns the field element one in the Montgomery domain.
1663///
1664/// Postconditions:
1665/// eval (from_montgomery out1) mod m = 1 mod m
1666/// 0 ≤ eval out1 < m
1667///
1668pub fn setOne(out1: *MontgomeryDomainFieldElement) void {
1669 @setRuntimeSafety(mode == .Debug);
1670
1671 out1[0] = 0x1000003d1;
1672 out1[1] = 0x0;
1673 out1[2] = 0x0;
1674 out1[3] = 0x0;
1675}
1676
1677/// The function msat returns the saturated representation of the prime modulus.
1678///
1679/// Postconditions:
1680/// twos_complement_eval out1 = m
1681/// 0 ≤ eval out1 < m
1682///
1683/// Output Bounds:
1684/// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1685pub fn msat(out1: *[5]u64) void {
1686 @setRuntimeSafety(mode == .Debug);
1687
1688 out1[0] = 0xfffffffefffffc2f;
1689 out1[1] = 0xffffffffffffffff;
1690 out1[2] = 0xffffffffffffffff;
1691 out1[3] = 0xffffffffffffffff;
1692 out1[4] = 0x0;
1693}
1694
1695/// The function divstep computes a divstep.
1696///
1697/// Preconditions:
1698/// 0 ≤ eval arg4 < m
1699/// 0 ≤ eval arg5 < m
1700/// Postconditions:
1701/// out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1)
1702/// twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2)
1703/// twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋)
1704/// eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m)
1705/// eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m)
1706/// 0 ≤ eval out5 < m
1707/// 0 ≤ eval out5 < m
1708/// 0 ≤ eval out2 < m
1709/// 0 ≤ eval out3 < m
1710///
1711/// Input Bounds:
1712/// arg1: [0x0 ~> 0xffffffffffffffff]
1713/// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1714/// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1715/// arg4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1716/// arg5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1717/// Output Bounds:
1718/// out1: [0x0 ~> 0xffffffffffffffff]
1719/// out2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1720/// out3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1721/// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1722/// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1723pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void {
1724 @setRuntimeSafety(mode == .Debug);
1725
1726 var x1: u64 = undefined;
1727 var x2: u1 = undefined;
1728 addcarryxU64(&x1, &x2, 0x0, (~arg1), 0x1);
1729 const x3 = (@truncate(u1, (x1 >> 63)) & @truncate(u1, ((arg3[0]) & 0x1)));
1730 var x4: u64 = undefined;
1731 var x5: u1 = undefined;
1732 addcarryxU64(&x4, &x5, 0x0, (~arg1), 0x1);
1733 var x6: u64 = undefined;
1734 cmovznzU64(&x6, x3, arg1, x4);
1735 var x7: u64 = undefined;
1736 cmovznzU64(&x7, x3, (arg2[0]), (arg3[0]));
1737 var x8: u64 = undefined;
1738 cmovznzU64(&x8, x3, (arg2[1]), (arg3[1]));
1739 var x9: u64 = undefined;
1740 cmovznzU64(&x9, x3, (arg2[2]), (arg3[2]));
1741 var x10: u64 = undefined;
1742 cmovznzU64(&x10, x3, (arg2[3]), (arg3[3]));
1743 var x11: u64 = undefined;
1744 cmovznzU64(&x11, x3, (arg2[4]), (arg3[4]));
1745 var x12: u64 = undefined;
1746 var x13: u1 = undefined;
1747 addcarryxU64(&x12, &x13, 0x0, 0x1, (~(arg2[0])));
1748 var x14: u64 = undefined;
1749 var x15: u1 = undefined;
1750 addcarryxU64(&x14, &x15, x13, 0x0, (~(arg2[1])));
1751 var x16: u64 = undefined;
1752 var x17: u1 = undefined;
1753 addcarryxU64(&x16, &x17, x15, 0x0, (~(arg2[2])));
1754 var x18: u64 = undefined;
1755 var x19: u1 = undefined;
1756 addcarryxU64(&x18, &x19, x17, 0x0, (~(arg2[3])));
1757 var x20: u64 = undefined;
1758 var x21: u1 = undefined;
1759 addcarryxU64(&x20, &x21, x19, 0x0, (~(arg2[4])));
1760 var x22: u64 = undefined;
1761 cmovznzU64(&x22, x3, (arg3[0]), x12);
1762 var x23: u64 = undefined;
1763 cmovznzU64(&x23, x3, (arg3[1]), x14);
1764 var x24: u64 = undefined;
1765 cmovznzU64(&x24, x3, (arg3[2]), x16);
1766 var x25: u64 = undefined;
1767 cmovznzU64(&x25, x3, (arg3[3]), x18);
1768 var x26: u64 = undefined;
1769 cmovznzU64(&x26, x3, (arg3[4]), x20);
1770 var x27: u64 = undefined;
1771 cmovznzU64(&x27, x3, (arg4[0]), (arg5[0]));
1772 var x28: u64 = undefined;
1773 cmovznzU64(&x28, x3, (arg4[1]), (arg5[1]));
1774 var x29: u64 = undefined;
1775 cmovznzU64(&x29, x3, (arg4[2]), (arg5[2]));
1776 var x30: u64 = undefined;
1777 cmovznzU64(&x30, x3, (arg4[3]), (arg5[3]));
1778 var x31: u64 = undefined;
1779 var x32: u1 = undefined;
1780 addcarryxU64(&x31, &x32, 0x0, x27, x27);
1781 var x33: u64 = undefined;
1782 var x34: u1 = undefined;
1783 addcarryxU64(&x33, &x34, x32, x28, x28);
1784 var x35: u64 = undefined;
1785 var x36: u1 = undefined;
1786 addcarryxU64(&x35, &x36, x34, x29, x29);
1787 var x37: u64 = undefined;
1788 var x38: u1 = undefined;
1789 addcarryxU64(&x37, &x38, x36, x30, x30);
1790 var x39: u64 = undefined;
1791 var x40: u1 = undefined;
1792 subborrowxU64(&x39, &x40, 0x0, x31, 0xfffffffefffffc2f);
1793 var x41: u64 = undefined;
1794 var x42: u1 = undefined;
1795 subborrowxU64(&x41, &x42, x40, x33, 0xffffffffffffffff);
1796 var x43: u64 = undefined;
1797 var x44: u1 = undefined;
1798 subborrowxU64(&x43, &x44, x42, x35, 0xffffffffffffffff);
1799 var x45: u64 = undefined;
1800 var x46: u1 = undefined;
1801 subborrowxU64(&x45, &x46, x44, x37, 0xffffffffffffffff);
1802 var x47: u64 = undefined;
1803 var x48: u1 = undefined;
1804 subborrowxU64(&x47, &x48, x46, @as(u64, x38), 0x0);
1805 const x49 = (arg4[3]);
1806 const x50 = (arg4[2]);
1807 const x51 = (arg4[1]);
1808 const x52 = (arg4[0]);
1809 var x53: u64 = undefined;
1810 var x54: u1 = undefined;
1811 subborrowxU64(&x53, &x54, 0x0, 0x0, x52);
1812 var x55: u64 = undefined;
1813 var x56: u1 = undefined;
1814 subborrowxU64(&x55, &x56, x54, 0x0, x51);
1815 var x57: u64 = undefined;
1816 var x58: u1 = undefined;
1817 subborrowxU64(&x57, &x58, x56, 0x0, x50);
1818 var x59: u64 = undefined;
1819 var x60: u1 = undefined;
1820 subborrowxU64(&x59, &x60, x58, 0x0, x49);
1821 var x61: u64 = undefined;
1822 cmovznzU64(&x61, x60, 0x0, 0xffffffffffffffff);
1823 var x62: u64 = undefined;
1824 var x63: u1 = undefined;
1825 addcarryxU64(&x62, &x63, 0x0, x53, (x61 & 0xfffffffefffffc2f));
1826 var x64: u64 = undefined;
1827 var x65: u1 = undefined;
1828 addcarryxU64(&x64, &x65, x63, x55, x61);
1829 var x66: u64 = undefined;
1830 var x67: u1 = undefined;
1831 addcarryxU64(&x66, &x67, x65, x57, x61);
1832 var x68: u64 = undefined;
1833 var x69: u1 = undefined;
1834 addcarryxU64(&x68, &x69, x67, x59, x61);
1835 var x70: u64 = undefined;
1836 cmovznzU64(&x70, x3, (arg5[0]), x62);
1837 var x71: u64 = undefined;
1838 cmovznzU64(&x71, x3, (arg5[1]), x64);
1839 var x72: u64 = undefined;
1840 cmovznzU64(&x72, x3, (arg5[2]), x66);
1841 var x73: u64 = undefined;
1842 cmovznzU64(&x73, x3, (arg5[3]), x68);
1843 const x74 = @truncate(u1, (x22 & 0x1));
1844 var x75: u64 = undefined;
1845 cmovznzU64(&x75, x74, 0x0, x7);
1846 var x76: u64 = undefined;
1847 cmovznzU64(&x76, x74, 0x0, x8);
1848 var x77: u64 = undefined;
1849 cmovznzU64(&x77, x74, 0x0, x9);
1850 var x78: u64 = undefined;
1851 cmovznzU64(&x78, x74, 0x0, x10);
1852 var x79: u64 = undefined;
1853 cmovznzU64(&x79, x74, 0x0, x11);
1854 var x80: u64 = undefined;
1855 var x81: u1 = undefined;
1856 addcarryxU64(&x80, &x81, 0x0, x22, x75);
1857 var x82: u64 = undefined;
1858 var x83: u1 = undefined;
1859 addcarryxU64(&x82, &x83, x81, x23, x76);
1860 var x84: u64 = undefined;
1861 var x85: u1 = undefined;
1862 addcarryxU64(&x84, &x85, x83, x24, x77);
1863 var x86: u64 = undefined;
1864 var x87: u1 = undefined;
1865 addcarryxU64(&x86, &x87, x85, x25, x78);
1866 var x88: u64 = undefined;
1867 var x89: u1 = undefined;
1868 addcarryxU64(&x88, &x89, x87, x26, x79);
1869 var x90: u64 = undefined;
1870 cmovznzU64(&x90, x74, 0x0, x27);
1871 var x91: u64 = undefined;
1872 cmovznzU64(&x91, x74, 0x0, x28);
1873 var x92: u64 = undefined;
1874 cmovznzU64(&x92, x74, 0x0, x29);
1875 var x93: u64 = undefined;
1876 cmovznzU64(&x93, x74, 0x0, x30);
1877 var x94: u64 = undefined;
1878 var x95: u1 = undefined;
1879 addcarryxU64(&x94, &x95, 0x0, x70, x90);
1880 var x96: u64 = undefined;
1881 var x97: u1 = undefined;
1882 addcarryxU64(&x96, &x97, x95, x71, x91);
1883 var x98: u64 = undefined;
1884 var x99: u1 = undefined;
1885 addcarryxU64(&x98, &x99, x97, x72, x92);
1886 var x100: u64 = undefined;
1887 var x101: u1 = undefined;
1888 addcarryxU64(&x100, &x101, x99, x73, x93);
1889 var x102: u64 = undefined;
1890 var x103: u1 = undefined;
1891 subborrowxU64(&x102, &x103, 0x0, x94, 0xfffffffefffffc2f);
1892 var x104: u64 = undefined;
1893 var x105: u1 = undefined;
1894 subborrowxU64(&x104, &x105, x103, x96, 0xffffffffffffffff);
1895 var x106: u64 = undefined;
1896 var x107: u1 = undefined;
1897 subborrowxU64(&x106, &x107, x105, x98, 0xffffffffffffffff);
1898 var x108: u64 = undefined;
1899 var x109: u1 = undefined;
1900 subborrowxU64(&x108, &x109, x107, x100, 0xffffffffffffffff);
1901 var x110: u64 = undefined;
1902 var x111: u1 = undefined;
1903 subborrowxU64(&x110, &x111, x109, @as(u64, x101), 0x0);
1904 var x112: u64 = undefined;
1905 var x113: u1 = undefined;
1906 addcarryxU64(&x112, &x113, 0x0, x6, 0x1);
1907 const x114 = ((x80 >> 1) | ((x82 << 63) & 0xffffffffffffffff));
1908 const x115 = ((x82 >> 1) | ((x84 << 63) & 0xffffffffffffffff));
1909 const x116 = ((x84 >> 1) | ((x86 << 63) & 0xffffffffffffffff));
1910 const x117 = ((x86 >> 1) | ((x88 << 63) & 0xffffffffffffffff));
1911 const x118 = ((x88 & 0x8000000000000000) | (x88 >> 1));
1912 var x119: u64 = undefined;
1913 cmovznzU64(&x119, x48, x39, x31);
1914 var x120: u64 = undefined;
1915 cmovznzU64(&x120, x48, x41, x33);
1916 var x121: u64 = undefined;
1917 cmovznzU64(&x121, x48, x43, x35);
1918 var x122: u64 = undefined;
1919 cmovznzU64(&x122, x48, x45, x37);
1920 var x123: u64 = undefined;
1921 cmovznzU64(&x123, x111, x102, x94);
1922 var x124: u64 = undefined;
1923 cmovznzU64(&x124, x111, x104, x96);
1924 var x125: u64 = undefined;
1925 cmovznzU64(&x125, x111, x106, x98);
1926 var x126: u64 = undefined;
1927 cmovznzU64(&x126, x111, x108, x100);
1928 out1.* = x112;
1929 out2[0] = x7;
1930 out2[1] = x8;
1931 out2[2] = x9;
1932 out2[3] = x10;
1933 out2[4] = x11;
1934 out3[0] = x114;
1935 out3[1] = x115;
1936 out3[2] = x116;
1937 out3[3] = x117;
1938 out3[4] = x118;
1939 out4[0] = x119;
1940 out4[1] = x120;
1941 out4[2] = x121;
1942 out4[3] = x122;
1943 out5[0] = x123;
1944 out5[1] = x124;
1945 out5[2] = x125;
1946 out5[3] = x126;
1947}
1948
1949/// The function divstepPrecomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form).
1950///
1951/// Postconditions:
1952/// eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋)
1953/// 0 ≤ eval out1 < m
1954///
1955/// Output Bounds:
1956/// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1957pub fn divstepPrecomp(out1: *[4]u64) void {
1958 @setRuntimeSafety(mode == .Debug);
1959
1960 out1[0] = 0xf201a41831525e0a;
1961 out1[1] = 0x9953f9ddcd648d85;
1962 out1[2] = 0xe86029463db210a9;
1963 out1[3] = 0x24fb8a3104b03709;
1964}
lib/std/crypto/pcurves/secp256k1/secp256k1_scalar_64.zig created+2024
...@@ -0,0 +1,2024 @@
1// Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --lang Zig --internal-static --public-function-case camelCase --private-function-case camelCase --public-type-case UpperCamelCase --private-type-case UpperCamelCase --no-prefix-fiat --package-name secp256k1_scalar '' 64 '2^256 - 432420386565659656852420866394968145599' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp
2// curve description (via package name): secp256k1_scalar
3// machine_wordsize = 64 (from "64")
4// requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp
5// m = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 (from "2^256 - 432420386565659656852420866394968145599")
6//
7// NOTE: In addition to the bounds specified above each function, all
8// functions synthesized for this Montgomery arithmetic require the
9// input to be strictly less than the prime modulus (m), and also
10// require the input to be in the unique saturated representation.
11// All functions also ensure that these two properties are true of
12// return values.
13//
14// Computed values:
15// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192)
16// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248)
17// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in
18// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256
19
20const std = @import("std");
21const mode = @import("builtin").mode; // Checked arithmetic is disabled in non-debug modes to avoid side channels
22
23// The type MontgomeryDomainFieldElement is a field element in the Montgomery domain.
24// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
25pub const MontgomeryDomainFieldElement = [4]u64;
26
27// The type NonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain.
28// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
29pub const NonMontgomeryDomainFieldElement = [4]u64;
30
31/// The function addcarryxU64 is an addition with carry.
32///
33/// Postconditions:
34/// out1 = (arg1 + arg2 + arg3) mod 2^64
35/// out2 = ⌊(arg1 + arg2 + arg3) / 2^64⌋
36///
37/// Input Bounds:
38/// arg1: [0x0 ~> 0x1]
39/// arg2: [0x0 ~> 0xffffffffffffffff]
40/// arg3: [0x0 ~> 0xffffffffffffffff]
41/// Output Bounds:
42/// out1: [0x0 ~> 0xffffffffffffffff]
43/// out2: [0x0 ~> 0x1]
44inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
45 @setRuntimeSafety(mode == .Debug);
46
47 var t: u64 = undefined;
48 const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49 const carry2 = @addWithOverflow(u64, t, arg1, out1);
50 out2.* = @boolToInt(carry1) | @boolToInt(carry2);
51}
52
53/// The function subborrowxU64 is a subtraction with borrow.
54///
55/// Postconditions:
56/// out1 = (-arg1 + arg2 + -arg3) mod 2^64
57/// out2 = -⌊(-arg1 + arg2 + -arg3) / 2^64⌋
58///
59/// Input Bounds:
60/// arg1: [0x0 ~> 0x1]
61/// arg2: [0x0 ~> 0xffffffffffffffff]
62/// arg3: [0x0 ~> 0xffffffffffffffff]
63/// Output Bounds:
64/// out1: [0x0 ~> 0xffffffffffffffff]
65/// out2: [0x0 ~> 0x1]
66inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
67 @setRuntimeSafety(mode == .Debug);
68
69 var t: u64 = undefined;
70 const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71 const carry2 = @subWithOverflow(u64, t, arg1, out1);
72 out2.* = @boolToInt(carry1) | @boolToInt(carry2);
73}
74
75/// The function mulxU64 is a multiplication, returning the full double-width result.
76///
77/// Postconditions:
78/// out1 = (arg1 * arg2) mod 2^64
79/// out2 = ⌊arg1 * arg2 / 2^64⌋
80///
81/// Input Bounds:
82/// arg1: [0x0 ~> 0xffffffffffffffff]
83/// arg2: [0x0 ~> 0xffffffffffffffff]
84/// Output Bounds:
85/// out1: [0x0 ~> 0xffffffffffffffff]
86/// out2: [0x0 ~> 0xffffffffffffffff]
87inline fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void {
88 @setRuntimeSafety(mode == .Debug);
89
90 const x = @as(u128, arg1) * @as(u128, arg2);
91 out1.* = @truncate(u64, x);
92 out2.* = @truncate(u64, x >> 64);
93}
94
95/// The function cmovznzU64 is a single-word conditional move.
96///
97/// Postconditions:
98/// out1 = (if arg1 = 0 then arg2 else arg3)
99///
100/// Input Bounds:
101/// arg1: [0x0 ~> 0x1]
102/// arg2: [0x0 ~> 0xffffffffffffffff]
103/// arg3: [0x0 ~> 0xffffffffffffffff]
104/// Output Bounds:
105/// out1: [0x0 ~> 0xffffffffffffffff]
106inline fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void {
107 @setRuntimeSafety(mode == .Debug);
108
109 const mask = 0 -% @as(u64, arg1);
110 out1.* = (mask & arg3) | ((~mask) & arg2);
111}
112
113/// The function mul multiplies two field elements in the Montgomery domain.
114///
115/// Preconditions:
116/// 0 ≤ eval arg1 < m
117/// 0 ≤ eval arg2 < m
118/// Postconditions:
119/// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m
120/// 0 ≤ eval out1 < m
121///
122pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void {
123 @setRuntimeSafety(mode == .Debug);
124
125 const x1 = (arg1[1]);
126 const x2 = (arg1[2]);
127 const x3 = (arg1[3]);
128 const x4 = (arg1[0]);
129 var x5: u64 = undefined;
130 var x6: u64 = undefined;
131 mulxU64(&x5, &x6, x4, (arg2[3]));
132 var x7: u64 = undefined;
133 var x8: u64 = undefined;
134 mulxU64(&x7, &x8, x4, (arg2[2]));
135 var x9: u64 = undefined;
136 var x10: u64 = undefined;
137 mulxU64(&x9, &x10, x4, (arg2[1]));
138 var x11: u64 = undefined;
139 var x12: u64 = undefined;
140 mulxU64(&x11, &x12, x4, (arg2[0]));
141 var x13: u64 = undefined;
142 var x14: u1 = undefined;
143 addcarryxU64(&x13, &x14, 0x0, x12, x9);
144 var x15: u64 = undefined;
145 var x16: u1 = undefined;
146 addcarryxU64(&x15, &x16, x14, x10, x7);
147 var x17: u64 = undefined;
148 var x18: u1 = undefined;
149 addcarryxU64(&x17, &x18, x16, x8, x5);
150 const x19 = (@as(u64, x18) + x6);
151 var x20: u64 = undefined;
152 var x21: u64 = undefined;
153 mulxU64(&x20, &x21, x11, 0x4b0dff665588b13f);
154 var x22: u64 = undefined;
155 var x23: u64 = undefined;
156 mulxU64(&x22, &x23, x20, 0xffffffffffffffff);
157 var x24: u64 = undefined;
158 var x25: u64 = undefined;
159 mulxU64(&x24, &x25, x20, 0xfffffffffffffffe);
160 var x26: u64 = undefined;
161 var x27: u64 = undefined;
162 mulxU64(&x26, &x27, x20, 0xbaaedce6af48a03b);
163 var x28: u64 = undefined;
164 var x29: u64 = undefined;
165 mulxU64(&x28, &x29, x20, 0xbfd25e8cd0364141);
166 var x30: u64 = undefined;
167 var x31: u1 = undefined;
168 addcarryxU64(&x30, &x31, 0x0, x29, x26);
169 var x32: u64 = undefined;
170 var x33: u1 = undefined;
171 addcarryxU64(&x32, &x33, x31, x27, x24);
172 var x34: u64 = undefined;
173 var x35: u1 = undefined;
174 addcarryxU64(&x34, &x35, x33, x25, x22);
175 const x36 = (@as(u64, x35) + x23);
176 var x37: u64 = undefined;
177 var x38: u1 = undefined;
178 addcarryxU64(&x37, &x38, 0x0, x11, x28);
179 var x39: u64 = undefined;
180 var x40: u1 = undefined;
181 addcarryxU64(&x39, &x40, x38, x13, x30);
182 var x41: u64 = undefined;
183 var x42: u1 = undefined;
184 addcarryxU64(&x41, &x42, x40, x15, x32);
185 var x43: u64 = undefined;
186 var x44: u1 = undefined;
187 addcarryxU64(&x43, &x44, x42, x17, x34);
188 var x45: u64 = undefined;
189 var x46: u1 = undefined;
190 addcarryxU64(&x45, &x46, x44, x19, x36);
191 var x47: u64 = undefined;
192 var x48: u64 = undefined;
193 mulxU64(&x47, &x48, x1, (arg2[3]));
194 var x49: u64 = undefined;
195 var x50: u64 = undefined;
196 mulxU64(&x49, &x50, x1, (arg2[2]));
197 var x51: u64 = undefined;
198 var x52: u64 = undefined;
199 mulxU64(&x51, &x52, x1, (arg2[1]));
200 var x53: u64 = undefined;
201 var x54: u64 = undefined;
202 mulxU64(&x53, &x54, x1, (arg2[0]));
203 var x55: u64 = undefined;
204 var x56: u1 = undefined;
205 addcarryxU64(&x55, &x56, 0x0, x54, x51);
206 var x57: u64 = undefined;
207 var x58: u1 = undefined;
208 addcarryxU64(&x57, &x58, x56, x52, x49);
209 var x59: u64 = undefined;
210 var x60: u1 = undefined;
211 addcarryxU64(&x59, &x60, x58, x50, x47);
212 const x61 = (@as(u64, x60) + x48);
213 var x62: u64 = undefined;
214 var x63: u1 = undefined;
215 addcarryxU64(&x62, &x63, 0x0, x39, x53);
216 var x64: u64 = undefined;
217 var x65: u1 = undefined;
218 addcarryxU64(&x64, &x65, x63, x41, x55);
219 var x66: u64 = undefined;
220 var x67: u1 = undefined;
221 addcarryxU64(&x66, &x67, x65, x43, x57);
222 var x68: u64 = undefined;
223 var x69: u1 = undefined;
224 addcarryxU64(&x68, &x69, x67, x45, x59);
225 var x70: u64 = undefined;
226 var x71: u1 = undefined;
227 addcarryxU64(&x70, &x71, x69, @as(u64, x46), x61);
228 var x72: u64 = undefined;
229 var x73: u64 = undefined;
230 mulxU64(&x72, &x73, x62, 0x4b0dff665588b13f);
231 var x74: u64 = undefined;
232 var x75: u64 = undefined;
233 mulxU64(&x74, &x75, x72, 0xffffffffffffffff);
234 var x76: u64 = undefined;
235 var x77: u64 = undefined;
236 mulxU64(&x76, &x77, x72, 0xfffffffffffffffe);
237 var x78: u64 = undefined;
238 var x79: u64 = undefined;
239 mulxU64(&x78, &x79, x72, 0xbaaedce6af48a03b);
240 var x80: u64 = undefined;
241 var x81: u64 = undefined;
242 mulxU64(&x80, &x81, x72, 0xbfd25e8cd0364141);
243 var x82: u64 = undefined;
244 var x83: u1 = undefined;
245 addcarryxU64(&x82, &x83, 0x0, x81, x78);
246 var x84: u64 = undefined;
247 var x85: u1 = undefined;
248 addcarryxU64(&x84, &x85, x83, x79, x76);
249 var x86: u64 = undefined;
250 var x87: u1 = undefined;
251 addcarryxU64(&x86, &x87, x85, x77, x74);
252 const x88 = (@as(u64, x87) + x75);
253 var x89: u64 = undefined;
254 var x90: u1 = undefined;
255 addcarryxU64(&x89, &x90, 0x0, x62, x80);
256 var x91: u64 = undefined;
257 var x92: u1 = undefined;
258 addcarryxU64(&x91, &x92, x90, x64, x82);
259 var x93: u64 = undefined;
260 var x94: u1 = undefined;
261 addcarryxU64(&x93, &x94, x92, x66, x84);
262 var x95: u64 = undefined;
263 var x96: u1 = undefined;
264 addcarryxU64(&x95, &x96, x94, x68, x86);
265 var x97: u64 = undefined;
266 var x98: u1 = undefined;
267 addcarryxU64(&x97, &x98, x96, x70, x88);
268 const x99 = (@as(u64, x98) + @as(u64, x71));
269 var x100: u64 = undefined;
270 var x101: u64 = undefined;
271 mulxU64(&x100, &x101, x2, (arg2[3]));
272 var x102: u64 = undefined;
273 var x103: u64 = undefined;
274 mulxU64(&x102, &x103, x2, (arg2[2]));
275 var x104: u64 = undefined;
276 var x105: u64 = undefined;
277 mulxU64(&x104, &x105, x2, (arg2[1]));
278 var x106: u64 = undefined;
279 var x107: u64 = undefined;
280 mulxU64(&x106, &x107, x2, (arg2[0]));
281 var x108: u64 = undefined;
282 var x109: u1 = undefined;
283 addcarryxU64(&x108, &x109, 0x0, x107, x104);
284 var x110: u64 = undefined;
285 var x111: u1 = undefined;
286 addcarryxU64(&x110, &x111, x109, x105, x102);
287 var x112: u64 = undefined;
288 var x113: u1 = undefined;
289 addcarryxU64(&x112, &x113, x111, x103, x100);
290 const x114 = (@as(u64, x113) + x101);
291 var x115: u64 = undefined;
292 var x116: u1 = undefined;
293 addcarryxU64(&x115, &x116, 0x0, x91, x106);
294 var x117: u64 = undefined;
295 var x118: u1 = undefined;
296 addcarryxU64(&x117, &x118, x116, x93, x108);
297 var x119: u64 = undefined;
298 var x120: u1 = undefined;
299 addcarryxU64(&x119, &x120, x118, x95, x110);
300 var x121: u64 = undefined;
301 var x122: u1 = undefined;
302 addcarryxU64(&x121, &x122, x120, x97, x112);
303 var x123: u64 = undefined;
304 var x124: u1 = undefined;
305 addcarryxU64(&x123, &x124, x122, x99, x114);
306 var x125: u64 = undefined;
307 var x126: u64 = undefined;
308 mulxU64(&x125, &x126, x115, 0x4b0dff665588b13f);
309 var x127: u64 = undefined;
310 var x128: u64 = undefined;
311 mulxU64(&x127, &x128, x125, 0xffffffffffffffff);
312 var x129: u64 = undefined;
313 var x130: u64 = undefined;
314 mulxU64(&x129, &x130, x125, 0xfffffffffffffffe);
315 var x131: u64 = undefined;
316 var x132: u64 = undefined;
317 mulxU64(&x131, &x132, x125, 0xbaaedce6af48a03b);
318 var x133: u64 = undefined;
319 var x134: u64 = undefined;
320 mulxU64(&x133, &x134, x125, 0xbfd25e8cd0364141);
321 var x135: u64 = undefined;
322 var x136: u1 = undefined;
323 addcarryxU64(&x135, &x136, 0x0, x134, x131);
324 var x137: u64 = undefined;
325 var x138: u1 = undefined;
326 addcarryxU64(&x137, &x138, x136, x132, x129);
327 var x139: u64 = undefined;
328 var x140: u1 = undefined;
329 addcarryxU64(&x139, &x140, x138, x130, x127);
330 const x141 = (@as(u64, x140) + x128);
331 var x142: u64 = undefined;
332 var x143: u1 = undefined;
333 addcarryxU64(&x142, &x143, 0x0, x115, x133);
334 var x144: u64 = undefined;
335 var x145: u1 = undefined;
336 addcarryxU64(&x144, &x145, x143, x117, x135);
337 var x146: u64 = undefined;
338 var x147: u1 = undefined;
339 addcarryxU64(&x146, &x147, x145, x119, x137);
340 var x148: u64 = undefined;
341 var x149: u1 = undefined;
342 addcarryxU64(&x148, &x149, x147, x121, x139);
343 var x150: u64 = undefined;
344 var x151: u1 = undefined;
345 addcarryxU64(&x150, &x151, x149, x123, x141);
346 const x152 = (@as(u64, x151) + @as(u64, x124));
347 var x153: u64 = undefined;
348 var x154: u64 = undefined;
349 mulxU64(&x153, &x154, x3, (arg2[3]));
350 var x155: u64 = undefined;
351 var x156: u64 = undefined;
352 mulxU64(&x155, &x156, x3, (arg2[2]));
353 var x157: u64 = undefined;
354 var x158: u64 = undefined;
355 mulxU64(&x157, &x158, x3, (arg2[1]));
356 var x159: u64 = undefined;
357 var x160: u64 = undefined;
358 mulxU64(&x159, &x160, x3, (arg2[0]));
359 var x161: u64 = undefined;
360 var x162: u1 = undefined;
361 addcarryxU64(&x161, &x162, 0x0, x160, x157);
362 var x163: u64 = undefined;
363 var x164: u1 = undefined;
364 addcarryxU64(&x163, &x164, x162, x158, x155);
365 var x165: u64 = undefined;
366 var x166: u1 = undefined;
367 addcarryxU64(&x165, &x166, x164, x156, x153);
368 const x167 = (@as(u64, x166) + x154);
369 var x168: u64 = undefined;
370 var x169: u1 = undefined;
371 addcarryxU64(&x168, &x169, 0x0, x144, x159);
372 var x170: u64 = undefined;
373 var x171: u1 = undefined;
374 addcarryxU64(&x170, &x171, x169, x146, x161);
375 var x172: u64 = undefined;
376 var x173: u1 = undefined;
377 addcarryxU64(&x172, &x173, x171, x148, x163);
378 var x174: u64 = undefined;
379 var x175: u1 = undefined;
380 addcarryxU64(&x174, &x175, x173, x150, x165);
381 var x176: u64 = undefined;
382 var x177: u1 = undefined;
383 addcarryxU64(&x176, &x177, x175, x152, x167);
384 var x178: u64 = undefined;
385 var x179: u64 = undefined;
386 mulxU64(&x178, &x179, x168, 0x4b0dff665588b13f);
387 var x180: u64 = undefined;
388 var x181: u64 = undefined;
389 mulxU64(&x180, &x181, x178, 0xffffffffffffffff);
390 var x182: u64 = undefined;
391 var x183: u64 = undefined;
392 mulxU64(&x182, &x183, x178, 0xfffffffffffffffe);
393 var x184: u64 = undefined;
394 var x185: u64 = undefined;
395 mulxU64(&x184, &x185, x178, 0xbaaedce6af48a03b);
396 var x186: u64 = undefined;
397 var x187: u64 = undefined;
398 mulxU64(&x186, &x187, x178, 0xbfd25e8cd0364141);
399 var x188: u64 = undefined;
400 var x189: u1 = undefined;
401 addcarryxU64(&x188, &x189, 0x0, x187, x184);
402 var x190: u64 = undefined;
403 var x191: u1 = undefined;
404 addcarryxU64(&x190, &x191, x189, x185, x182);
405 var x192: u64 = undefined;
406 var x193: u1 = undefined;
407 addcarryxU64(&x192, &x193, x191, x183, x180);
408 const x194 = (@as(u64, x193) + x181);
409 var x195: u64 = undefined;
410 var x196: u1 = undefined;
411 addcarryxU64(&x195, &x196, 0x0, x168, x186);
412 var x197: u64 = undefined;
413 var x198: u1 = undefined;
414 addcarryxU64(&x197, &x198, x196, x170, x188);
415 var x199: u64 = undefined;
416 var x200: u1 = undefined;
417 addcarryxU64(&x199, &x200, x198, x172, x190);
418 var x201: u64 = undefined;
419 var x202: u1 = undefined;
420 addcarryxU64(&x201, &x202, x200, x174, x192);
421 var x203: u64 = undefined;
422 var x204: u1 = undefined;
423 addcarryxU64(&x203, &x204, x202, x176, x194);
424 const x205 = (@as(u64, x204) + @as(u64, x177));
425 var x206: u64 = undefined;
426 var x207: u1 = undefined;
427 subborrowxU64(&x206, &x207, 0x0, x197, 0xbfd25e8cd0364141);
428 var x208: u64 = undefined;
429 var x209: u1 = undefined;
430 subborrowxU64(&x208, &x209, x207, x199, 0xbaaedce6af48a03b);
431 var x210: u64 = undefined;
432 var x211: u1 = undefined;
433 subborrowxU64(&x210, &x211, x209, x201, 0xfffffffffffffffe);
434 var x212: u64 = undefined;
435 var x213: u1 = undefined;
436 subborrowxU64(&x212, &x213, x211, x203, 0xffffffffffffffff);
437 var x214: u64 = undefined;
438 var x215: u1 = undefined;
439 subborrowxU64(&x214, &x215, x213, x205, 0x0);
440 var x216: u64 = undefined;
441 cmovznzU64(&x216, x215, x206, x197);
442 var x217: u64 = undefined;
443 cmovznzU64(&x217, x215, x208, x199);
444 var x218: u64 = undefined;
445 cmovznzU64(&x218, x215, x210, x201);
446 var x219: u64 = undefined;
447 cmovznzU64(&x219, x215, x212, x203);
448 out1[0] = x216;
449 out1[1] = x217;
450 out1[2] = x218;
451 out1[3] = x219;
452}
453
454/// The function square squares a field element in the Montgomery domain.
455///
456/// Preconditions:
457/// 0 ≤ eval arg1 < m
458/// Postconditions:
459/// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m
460/// 0 ≤ eval out1 < m
461///
462pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void {
463 @setRuntimeSafety(mode == .Debug);
464
465 const x1 = (arg1[1]);
466 const x2 = (arg1[2]);
467 const x3 = (arg1[3]);
468 const x4 = (arg1[0]);
469 var x5: u64 = undefined;
470 var x6: u64 = undefined;
471 mulxU64(&x5, &x6, x4, (arg1[3]));
472 var x7: u64 = undefined;
473 var x8: u64 = undefined;
474 mulxU64(&x7, &x8, x4, (arg1[2]));
475 var x9: u64 = undefined;
476 var x10: u64 = undefined;
477 mulxU64(&x9, &x10, x4, (arg1[1]));
478 var x11: u64 = undefined;
479 var x12: u64 = undefined;
480 mulxU64(&x11, &x12, x4, (arg1[0]));
481 var x13: u64 = undefined;
482 var x14: u1 = undefined;
483 addcarryxU64(&x13, &x14, 0x0, x12, x9);
484 var x15: u64 = undefined;
485 var x16: u1 = undefined;
486 addcarryxU64(&x15, &x16, x14, x10, x7);
487 var x17: u64 = undefined;
488 var x18: u1 = undefined;
489 addcarryxU64(&x17, &x18, x16, x8, x5);
490 const x19 = (@as(u64, x18) + x6);
491 var x20: u64 = undefined;
492 var x21: u64 = undefined;
493 mulxU64(&x20, &x21, x11, 0x4b0dff665588b13f);
494 var x22: u64 = undefined;
495 var x23: u64 = undefined;
496 mulxU64(&x22, &x23, x20, 0xffffffffffffffff);
497 var x24: u64 = undefined;
498 var x25: u64 = undefined;
499 mulxU64(&x24, &x25, x20, 0xfffffffffffffffe);
500 var x26: u64 = undefined;
501 var x27: u64 = undefined;
502 mulxU64(&x26, &x27, x20, 0xbaaedce6af48a03b);
503 var x28: u64 = undefined;
504 var x29: u64 = undefined;
505 mulxU64(&x28, &x29, x20, 0xbfd25e8cd0364141);
506 var x30: u64 = undefined;
507 var x31: u1 = undefined;
508 addcarryxU64(&x30, &x31, 0x0, x29, x26);
509 var x32: u64 = undefined;
510 var x33: u1 = undefined;
511 addcarryxU64(&x32, &x33, x31, x27, x24);
512 var x34: u64 = undefined;
513 var x35: u1 = undefined;
514 addcarryxU64(&x34, &x35, x33, x25, x22);
515 const x36 = (@as(u64, x35) + x23);
516 var x37: u64 = undefined;
517 var x38: u1 = undefined;
518 addcarryxU64(&x37, &x38, 0x0, x11, x28);
519 var x39: u64 = undefined;
520 var x40: u1 = undefined;
521 addcarryxU64(&x39, &x40, x38, x13, x30);
522 var x41: u64 = undefined;
523 var x42: u1 = undefined;
524 addcarryxU64(&x41, &x42, x40, x15, x32);
525 var x43: u64 = undefined;
526 var x44: u1 = undefined;
527 addcarryxU64(&x43, &x44, x42, x17, x34);
528 var x45: u64 = undefined;
529 var x46: u1 = undefined;
530 addcarryxU64(&x45, &x46, x44, x19, x36);
531 var x47: u64 = undefined;
532 var x48: u64 = undefined;
533 mulxU64(&x47, &x48, x1, (arg1[3]));
534 var x49: u64 = undefined;
535 var x50: u64 = undefined;
536 mulxU64(&x49, &x50, x1, (arg1[2]));
537 var x51: u64 = undefined;
538 var x52: u64 = undefined;
539 mulxU64(&x51, &x52, x1, (arg1[1]));
540 var x53: u64 = undefined;
541 var x54: u64 = undefined;
542 mulxU64(&x53, &x54, x1, (arg1[0]));
543 var x55: u64 = undefined;
544 var x56: u1 = undefined;
545 addcarryxU64(&x55, &x56, 0x0, x54, x51);
546 var x57: u64 = undefined;
547 var x58: u1 = undefined;
548 addcarryxU64(&x57, &x58, x56, x52, x49);
549 var x59: u64 = undefined;
550 var x60: u1 = undefined;
551 addcarryxU64(&x59, &x60, x58, x50, x47);
552 const x61 = (@as(u64, x60) + x48);
553 var x62: u64 = undefined;
554 var x63: u1 = undefined;
555 addcarryxU64(&x62, &x63, 0x0, x39, x53);
556 var x64: u64 = undefined;
557 var x65: u1 = undefined;
558 addcarryxU64(&x64, &x65, x63, x41, x55);
559 var x66: u64 = undefined;
560 var x67: u1 = undefined;
561 addcarryxU64(&x66, &x67, x65, x43, x57);
562 var x68: u64 = undefined;
563 var x69: u1 = undefined;
564 addcarryxU64(&x68, &x69, x67, x45, x59);
565 var x70: u64 = undefined;
566 var x71: u1 = undefined;
567 addcarryxU64(&x70, &x71, x69, @as(u64, x46), x61);
568 var x72: u64 = undefined;
569 var x73: u64 = undefined;
570 mulxU64(&x72, &x73, x62, 0x4b0dff665588b13f);
571 var x74: u64 = undefined;
572 var x75: u64 = undefined;
573 mulxU64(&x74, &x75, x72, 0xffffffffffffffff);
574 var x76: u64 = undefined;
575 var x77: u64 = undefined;
576 mulxU64(&x76, &x77, x72, 0xfffffffffffffffe);
577 var x78: u64 = undefined;
578 var x79: u64 = undefined;
579 mulxU64(&x78, &x79, x72, 0xbaaedce6af48a03b);
580 var x80: u64 = undefined;
581 var x81: u64 = undefined;
582 mulxU64(&x80, &x81, x72, 0xbfd25e8cd0364141);
583 var x82: u64 = undefined;
584 var x83: u1 = undefined;
585 addcarryxU64(&x82, &x83, 0x0, x81, x78);
586 var x84: u64 = undefined;
587 var x85: u1 = undefined;
588 addcarryxU64(&x84, &x85, x83, x79, x76);
589 var x86: u64 = undefined;
590 var x87: u1 = undefined;
591 addcarryxU64(&x86, &x87, x85, x77, x74);
592 const x88 = (@as(u64, x87) + x75);
593 var x89: u64 = undefined;
594 var x90: u1 = undefined;
595 addcarryxU64(&x89, &x90, 0x0, x62, x80);
596 var x91: u64 = undefined;
597 var x92: u1 = undefined;
598 addcarryxU64(&x91, &x92, x90, x64, x82);
599 var x93: u64 = undefined;
600 var x94: u1 = undefined;
601 addcarryxU64(&x93, &x94, x92, x66, x84);
602 var x95: u64 = undefined;
603 var x96: u1 = undefined;
604 addcarryxU64(&x95, &x96, x94, x68, x86);
605 var x97: u64 = undefined;
606 var x98: u1 = undefined;
607 addcarryxU64(&x97, &x98, x96, x70, x88);
608 const x99 = (@as(u64, x98) + @as(u64, x71));
609 var x100: u64 = undefined;
610 var x101: u64 = undefined;
611 mulxU64(&x100, &x101, x2, (arg1[3]));
612 var x102: u64 = undefined;
613 var x103: u64 = undefined;
614 mulxU64(&x102, &x103, x2, (arg1[2]));
615 var x104: u64 = undefined;
616 var x105: u64 = undefined;
617 mulxU64(&x104, &x105, x2, (arg1[1]));
618 var x106: u64 = undefined;
619 var x107: u64 = undefined;
620 mulxU64(&x106, &x107, x2, (arg1[0]));
621 var x108: u64 = undefined;
622 var x109: u1 = undefined;
623 addcarryxU64(&x108, &x109, 0x0, x107, x104);
624 var x110: u64 = undefined;
625 var x111: u1 = undefined;
626 addcarryxU64(&x110, &x111, x109, x105, x102);
627 var x112: u64 = undefined;
628 var x113: u1 = undefined;
629 addcarryxU64(&x112, &x113, x111, x103, x100);
630 const x114 = (@as(u64, x113) + x101);
631 var x115: u64 = undefined;
632 var x116: u1 = undefined;
633 addcarryxU64(&x115, &x116, 0x0, x91, x106);
634 var x117: u64 = undefined;
635 var x118: u1 = undefined;
636 addcarryxU64(&x117, &x118, x116, x93, x108);
637 var x119: u64 = undefined;
638 var x120: u1 = undefined;
639 addcarryxU64(&x119, &x120, x118, x95, x110);
640 var x121: u64 = undefined;
641 var x122: u1 = undefined;
642 addcarryxU64(&x121, &x122, x120, x97, x112);
643 var x123: u64 = undefined;
644 var x124: u1 = undefined;
645 addcarryxU64(&x123, &x124, x122, x99, x114);
646 var x125: u64 = undefined;
647 var x126: u64 = undefined;
648 mulxU64(&x125, &x126, x115, 0x4b0dff665588b13f);
649 var x127: u64 = undefined;
650 var x128: u64 = undefined;
651 mulxU64(&x127, &x128, x125, 0xffffffffffffffff);
652 var x129: u64 = undefined;
653 var x130: u64 = undefined;
654 mulxU64(&x129, &x130, x125, 0xfffffffffffffffe);
655 var x131: u64 = undefined;
656 var x132: u64 = undefined;
657 mulxU64(&x131, &x132, x125, 0xbaaedce6af48a03b);
658 var x133: u64 = undefined;
659 var x134: u64 = undefined;
660 mulxU64(&x133, &x134, x125, 0xbfd25e8cd0364141);
661 var x135: u64 = undefined;
662 var x136: u1 = undefined;
663 addcarryxU64(&x135, &x136, 0x0, x134, x131);
664 var x137: u64 = undefined;
665 var x138: u1 = undefined;
666 addcarryxU64(&x137, &x138, x136, x132, x129);
667 var x139: u64 = undefined;
668 var x140: u1 = undefined;
669 addcarryxU64(&x139, &x140, x138, x130, x127);
670 const x141 = (@as(u64, x140) + x128);
671 var x142: u64 = undefined;
672 var x143: u1 = undefined;
673 addcarryxU64(&x142, &x143, 0x0, x115, x133);
674 var x144: u64 = undefined;
675 var x145: u1 = undefined;
676 addcarryxU64(&x144, &x145, x143, x117, x135);
677 var x146: u64 = undefined;
678 var x147: u1 = undefined;
679 addcarryxU64(&x146, &x147, x145, x119, x137);
680 var x148: u64 = undefined;
681 var x149: u1 = undefined;
682 addcarryxU64(&x148, &x149, x147, x121, x139);
683 var x150: u64 = undefined;
684 var x151: u1 = undefined;
685 addcarryxU64(&x150, &x151, x149, x123, x141);
686 const x152 = (@as(u64, x151) + @as(u64, x124));
687 var x153: u64 = undefined;
688 var x154: u64 = undefined;
689 mulxU64(&x153, &x154, x3, (arg1[3]));
690 var x155: u64 = undefined;
691 var x156: u64 = undefined;
692 mulxU64(&x155, &x156, x3, (arg1[2]));
693 var x157: u64 = undefined;
694 var x158: u64 = undefined;
695 mulxU64(&x157, &x158, x3, (arg1[1]));
696 var x159: u64 = undefined;
697 var x160: u64 = undefined;
698 mulxU64(&x159, &x160, x3, (arg1[0]));
699 var x161: u64 = undefined;
700 var x162: u1 = undefined;
701 addcarryxU64(&x161, &x162, 0x0, x160, x157);
702 var x163: u64 = undefined;
703 var x164: u1 = undefined;
704 addcarryxU64(&x163, &x164, x162, x158, x155);
705 var x165: u64 = undefined;
706 var x166: u1 = undefined;
707 addcarryxU64(&x165, &x166, x164, x156, x153);
708 const x167 = (@as(u64, x166) + x154);
709 var x168: u64 = undefined;
710 var x169: u1 = undefined;
711 addcarryxU64(&x168, &x169, 0x0, x144, x159);
712 var x170: u64 = undefined;
713 var x171: u1 = undefined;
714 addcarryxU64(&x170, &x171, x169, x146, x161);
715 var x172: u64 = undefined;
716 var x173: u1 = undefined;
717 addcarryxU64(&x172, &x173, x171, x148, x163);
718 var x174: u64 = undefined;
719 var x175: u1 = undefined;
720 addcarryxU64(&x174, &x175, x173, x150, x165);
721 var x176: u64 = undefined;
722 var x177: u1 = undefined;
723 addcarryxU64(&x176, &x177, x175, x152, x167);
724 var x178: u64 = undefined;
725 var x179: u64 = undefined;
726 mulxU64(&x178, &x179, x168, 0x4b0dff665588b13f);
727 var x180: u64 = undefined;
728 var x181: u64 = undefined;
729 mulxU64(&x180, &x181, x178, 0xffffffffffffffff);
730 var x182: u64 = undefined;
731 var x183: u64 = undefined;
732 mulxU64(&x182, &x183, x178, 0xfffffffffffffffe);
733 var x184: u64 = undefined;
734 var x185: u64 = undefined;
735 mulxU64(&x184, &x185, x178, 0xbaaedce6af48a03b);
736 var x186: u64 = undefined;
737 var x187: u64 = undefined;
738 mulxU64(&x186, &x187, x178, 0xbfd25e8cd0364141);
739 var x188: u64 = undefined;
740 var x189: u1 = undefined;
741 addcarryxU64(&x188, &x189, 0x0, x187, x184);
742 var x190: u64 = undefined;
743 var x191: u1 = undefined;
744 addcarryxU64(&x190, &x191, x189, x185, x182);
745 var x192: u64 = undefined;
746 var x193: u1 = undefined;
747 addcarryxU64(&x192, &x193, x191, x183, x180);
748 const x194 = (@as(u64, x193) + x181);
749 var x195: u64 = undefined;
750 var x196: u1 = undefined;
751 addcarryxU64(&x195, &x196, 0x0, x168, x186);
752 var x197: u64 = undefined;
753 var x198: u1 = undefined;
754 addcarryxU64(&x197, &x198, x196, x170, x188);
755 var x199: u64 = undefined;
756 var x200: u1 = undefined;
757 addcarryxU64(&x199, &x200, x198, x172, x190);
758 var x201: u64 = undefined;
759 var x202: u1 = undefined;
760 addcarryxU64(&x201, &x202, x200, x174, x192);
761 var x203: u64 = undefined;
762 var x204: u1 = undefined;
763 addcarryxU64(&x203, &x204, x202, x176, x194);
764 const x205 = (@as(u64, x204) + @as(u64, x177));
765 var x206: u64 = undefined;
766 var x207: u1 = undefined;
767 subborrowxU64(&x206, &x207, 0x0, x197, 0xbfd25e8cd0364141);
768 var x208: u64 = undefined;
769 var x209: u1 = undefined;
770 subborrowxU64(&x208, &x209, x207, x199, 0xbaaedce6af48a03b);
771 var x210: u64 = undefined;
772 var x211: u1 = undefined;
773 subborrowxU64(&x210, &x211, x209, x201, 0xfffffffffffffffe);
774 var x212: u64 = undefined;
775 var x213: u1 = undefined;
776 subborrowxU64(&x212, &x213, x211, x203, 0xffffffffffffffff);
777 var x214: u64 = undefined;
778 var x215: u1 = undefined;
779 subborrowxU64(&x214, &x215, x213, x205, 0x0);
780 var x216: u64 = undefined;
781 cmovznzU64(&x216, x215, x206, x197);
782 var x217: u64 = undefined;
783 cmovznzU64(&x217, x215, x208, x199);
784 var x218: u64 = undefined;
785 cmovznzU64(&x218, x215, x210, x201);
786 var x219: u64 = undefined;
787 cmovznzU64(&x219, x215, x212, x203);
788 out1[0] = x216;
789 out1[1] = x217;
790 out1[2] = x218;
791 out1[3] = x219;
792}
793
794/// The function add adds two field elements in the Montgomery domain.
795///
796/// Preconditions:
797/// 0 ≤ eval arg1 < m
798/// 0 ≤ eval arg2 < m
799/// Postconditions:
800/// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m
801/// 0 ≤ eval out1 < m
802///
803pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void {
804 @setRuntimeSafety(mode == .Debug);
805
806 var x1: u64 = undefined;
807 var x2: u1 = undefined;
808 addcarryxU64(&x1, &x2, 0x0, (arg1[0]), (arg2[0]));
809 var x3: u64 = undefined;
810 var x4: u1 = undefined;
811 addcarryxU64(&x3, &x4, x2, (arg1[1]), (arg2[1]));
812 var x5: u64 = undefined;
813 var x6: u1 = undefined;
814 addcarryxU64(&x5, &x6, x4, (arg1[2]), (arg2[2]));
815 var x7: u64 = undefined;
816 var x8: u1 = undefined;
817 addcarryxU64(&x7, &x8, x6, (arg1[3]), (arg2[3]));
818 var x9: u64 = undefined;
819 var x10: u1 = undefined;
820 subborrowxU64(&x9, &x10, 0x0, x1, 0xbfd25e8cd0364141);
821 var x11: u64 = undefined;
822 var x12: u1 = undefined;
823 subborrowxU64(&x11, &x12, x10, x3, 0xbaaedce6af48a03b);
824 var x13: u64 = undefined;
825 var x14: u1 = undefined;
826 subborrowxU64(&x13, &x14, x12, x5, 0xfffffffffffffffe);
827 var x15: u64 = undefined;
828 var x16: u1 = undefined;
829 subborrowxU64(&x15, &x16, x14, x7, 0xffffffffffffffff);
830 var x17: u64 = undefined;
831 var x18: u1 = undefined;
832 subborrowxU64(&x17, &x18, x16, @as(u64, x8), 0x0);
833 var x19: u64 = undefined;
834 cmovznzU64(&x19, x18, x9, x1);
835 var x20: u64 = undefined;
836 cmovznzU64(&x20, x18, x11, x3);
837 var x21: u64 = undefined;
838 cmovznzU64(&x21, x18, x13, x5);
839 var x22: u64 = undefined;
840 cmovznzU64(&x22, x18, x15, x7);
841 out1[0] = x19;
842 out1[1] = x20;
843 out1[2] = x21;
844 out1[3] = x22;
845}
846
847/// The function sub subtracts two field elements in the Montgomery domain.
848///
849/// Preconditions:
850/// 0 ≤ eval arg1 < m
851/// 0 ≤ eval arg2 < m
852/// Postconditions:
853/// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m
854/// 0 ≤ eval out1 < m
855///
856pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void {
857 @setRuntimeSafety(mode == .Debug);
858
859 var x1: u64 = undefined;
860 var x2: u1 = undefined;
861 subborrowxU64(&x1, &x2, 0x0, (arg1[0]), (arg2[0]));
862 var x3: u64 = undefined;
863 var x4: u1 = undefined;
864 subborrowxU64(&x3, &x4, x2, (arg1[1]), (arg2[1]));
865 var x5: u64 = undefined;
866 var x6: u1 = undefined;
867 subborrowxU64(&x5, &x6, x4, (arg1[2]), (arg2[2]));
868 var x7: u64 = undefined;
869 var x8: u1 = undefined;
870 subborrowxU64(&x7, &x8, x6, (arg1[3]), (arg2[3]));
871 var x9: u64 = undefined;
872 cmovznzU64(&x9, x8, 0x0, 0xffffffffffffffff);
873 var x10: u64 = undefined;
874 var x11: u1 = undefined;
875 addcarryxU64(&x10, &x11, 0x0, x1, (x9 & 0xbfd25e8cd0364141));
876 var x12: u64 = undefined;
877 var x13: u1 = undefined;
878 addcarryxU64(&x12, &x13, x11, x3, (x9 & 0xbaaedce6af48a03b));
879 var x14: u64 = undefined;
880 var x15: u1 = undefined;
881 addcarryxU64(&x14, &x15, x13, x5, (x9 & 0xfffffffffffffffe));
882 var x16: u64 = undefined;
883 var x17: u1 = undefined;
884 addcarryxU64(&x16, &x17, x15, x7, x9);
885 out1[0] = x10;
886 out1[1] = x12;
887 out1[2] = x14;
888 out1[3] = x16;
889}
890
891/// The function opp negates a field element in the Montgomery domain.
892///
893/// Preconditions:
894/// 0 ≤ eval arg1 < m
895/// Postconditions:
896/// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m
897/// 0 ≤ eval out1 < m
898///
899pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void {
900 @setRuntimeSafety(mode == .Debug);
901
902 var x1: u64 = undefined;
903 var x2: u1 = undefined;
904 subborrowxU64(&x1, &x2, 0x0, 0x0, (arg1[0]));
905 var x3: u64 = undefined;
906 var x4: u1 = undefined;
907 subborrowxU64(&x3, &x4, x2, 0x0, (arg1[1]));
908 var x5: u64 = undefined;
909 var x6: u1 = undefined;
910 subborrowxU64(&x5, &x6, x4, 0x0, (arg1[2]));
911 var x7: u64 = undefined;
912 var x8: u1 = undefined;
913 subborrowxU64(&x7, &x8, x6, 0x0, (arg1[3]));
914 var x9: u64 = undefined;
915 cmovznzU64(&x9, x8, 0x0, 0xffffffffffffffff);
916 var x10: u64 = undefined;
917 var x11: u1 = undefined;
918 addcarryxU64(&x10, &x11, 0x0, x1, (x9 & 0xbfd25e8cd0364141));
919 var x12: u64 = undefined;
920 var x13: u1 = undefined;
921 addcarryxU64(&x12, &x13, x11, x3, (x9 & 0xbaaedce6af48a03b));
922 var x14: u64 = undefined;
923 var x15: u1 = undefined;
924 addcarryxU64(&x14, &x15, x13, x5, (x9 & 0xfffffffffffffffe));
925 var x16: u64 = undefined;
926 var x17: u1 = undefined;
927 addcarryxU64(&x16, &x17, x15, x7, x9);
928 out1[0] = x10;
929 out1[1] = x12;
930 out1[2] = x14;
931 out1[3] = x16;
932}
933
934/// The function fromMontgomery translates a field element out of the Montgomery domain.
935///
936/// Preconditions:
937/// 0 ≤ eval arg1 < m
938/// Postconditions:
939/// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m
940/// 0 ≤ eval out1 < m
941///
942pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void {
943 @setRuntimeSafety(mode == .Debug);
944
945 const x1 = (arg1[0]);
946 var x2: u64 = undefined;
947 var x3: u64 = undefined;
948 mulxU64(&x2, &x3, x1, 0x4b0dff665588b13f);
949 var x4: u64 = undefined;
950 var x5: u64 = undefined;
951 mulxU64(&x4, &x5, x2, 0xffffffffffffffff);
952 var x6: u64 = undefined;
953 var x7: u64 = undefined;
954 mulxU64(&x6, &x7, x2, 0xfffffffffffffffe);
955 var x8: u64 = undefined;
956 var x9: u64 = undefined;
957 mulxU64(&x8, &x9, x2, 0xbaaedce6af48a03b);
958 var x10: u64 = undefined;
959 var x11: u64 = undefined;
960 mulxU64(&x10, &x11, x2, 0xbfd25e8cd0364141);
961 var x12: u64 = undefined;
962 var x13: u1 = undefined;
963 addcarryxU64(&x12, &x13, 0x0, x11, x8);
964 var x14: u64 = undefined;
965 var x15: u1 = undefined;
966 addcarryxU64(&x14, &x15, x13, x9, x6);
967 var x16: u64 = undefined;
968 var x17: u1 = undefined;
969 addcarryxU64(&x16, &x17, x15, x7, x4);
970 var x18: u64 = undefined;
971 var x19: u1 = undefined;
972 addcarryxU64(&x18, &x19, 0x0, x1, x10);
973 var x20: u64 = undefined;
974 var x21: u1 = undefined;
975 addcarryxU64(&x20, &x21, x19, 0x0, x12);
976 var x22: u64 = undefined;
977 var x23: u1 = undefined;
978 addcarryxU64(&x22, &x23, x21, 0x0, x14);
979 var x24: u64 = undefined;
980 var x25: u1 = undefined;
981 addcarryxU64(&x24, &x25, x23, 0x0, x16);
982 var x26: u64 = undefined;
983 var x27: u1 = undefined;
984 addcarryxU64(&x26, &x27, x25, 0x0, (@as(u64, x17) + x5));
985 var x28: u64 = undefined;
986 var x29: u1 = undefined;
987 addcarryxU64(&x28, &x29, 0x0, x20, (arg1[1]));
988 var x30: u64 = undefined;
989 var x31: u1 = undefined;
990 addcarryxU64(&x30, &x31, x29, x22, 0x0);
991 var x32: u64 = undefined;
992 var x33: u1 = undefined;
993 addcarryxU64(&x32, &x33, x31, x24, 0x0);
994 var x34: u64 = undefined;
995 var x35: u1 = undefined;
996 addcarryxU64(&x34, &x35, x33, x26, 0x0);
997 var x36: u64 = undefined;
998 var x37: u64 = undefined;
999 mulxU64(&x36, &x37, x28, 0x4b0dff665588b13f);
1000 var x38: u64 = undefined;
1001 var x39: u64 = undefined;
1002 mulxU64(&x38, &x39, x36, 0xffffffffffffffff);
1003 var x40: u64 = undefined;
1004 var x41: u64 = undefined;
1005 mulxU64(&x40, &x41, x36, 0xfffffffffffffffe);
1006 var x42: u64 = undefined;
1007 var x43: u64 = undefined;
1008 mulxU64(&x42, &x43, x36, 0xbaaedce6af48a03b);
1009 var x44: u64 = undefined;
1010 var x45: u64 = undefined;
1011 mulxU64(&x44, &x45, x36, 0xbfd25e8cd0364141);
1012 var x46: u64 = undefined;
1013 var x47: u1 = undefined;
1014 addcarryxU64(&x46, &x47, 0x0, x45, x42);
1015 var x48: u64 = undefined;
1016 var x49: u1 = undefined;
1017 addcarryxU64(&x48, &x49, x47, x43, x40);
1018 var x50: u64 = undefined;
1019 var x51: u1 = undefined;
1020 addcarryxU64(&x50, &x51, x49, x41, x38);
1021 var x52: u64 = undefined;
1022 var x53: u1 = undefined;
1023 addcarryxU64(&x52, &x53, 0x0, x28, x44);
1024 var x54: u64 = undefined;
1025 var x55: u1 = undefined;
1026 addcarryxU64(&x54, &x55, x53, x30, x46);
1027 var x56: u64 = undefined;
1028 var x57: u1 = undefined;
1029 addcarryxU64(&x56, &x57, x55, x32, x48);
1030 var x58: u64 = undefined;
1031 var x59: u1 = undefined;
1032 addcarryxU64(&x58, &x59, x57, x34, x50);
1033 var x60: u64 = undefined;
1034 var x61: u1 = undefined;
1035 addcarryxU64(&x60, &x61, x59, (@as(u64, x35) + @as(u64, x27)), (@as(u64, x51) + x39));
1036 var x62: u64 = undefined;
1037 var x63: u1 = undefined;
1038 addcarryxU64(&x62, &x63, 0x0, x54, (arg1[2]));
1039 var x64: u64 = undefined;
1040 var x65: u1 = undefined;
1041 addcarryxU64(&x64, &x65, x63, x56, 0x0);
1042 var x66: u64 = undefined;
1043 var x67: u1 = undefined;
1044 addcarryxU64(&x66, &x67, x65, x58, 0x0);
1045 var x68: u64 = undefined;
1046 var x69: u1 = undefined;
1047 addcarryxU64(&x68, &x69, x67, x60, 0x0);
1048 var x70: u64 = undefined;
1049 var x71: u64 = undefined;
1050 mulxU64(&x70, &x71, x62, 0x4b0dff665588b13f);
1051 var x72: u64 = undefined;
1052 var x73: u64 = undefined;
1053 mulxU64(&x72, &x73, x70, 0xffffffffffffffff);
1054 var x74: u64 = undefined;
1055 var x75: u64 = undefined;
1056 mulxU64(&x74, &x75, x70, 0xfffffffffffffffe);
1057 var x76: u64 = undefined;
1058 var x77: u64 = undefined;
1059 mulxU64(&x76, &x77, x70, 0xbaaedce6af48a03b);
1060 var x78: u64 = undefined;
1061 var x79: u64 = undefined;
1062 mulxU64(&x78, &x79, x70, 0xbfd25e8cd0364141);
1063 var x80: u64 = undefined;
1064 var x81: u1 = undefined;
1065 addcarryxU64(&x80, &x81, 0x0, x79, x76);
1066 var x82: u64 = undefined;
1067 var x83: u1 = undefined;
1068 addcarryxU64(&x82, &x83, x81, x77, x74);
1069 var x84: u64 = undefined;
1070 var x85: u1 = undefined;
1071 addcarryxU64(&x84, &x85, x83, x75, x72);
1072 var x86: u64 = undefined;
1073 var x87: u1 = undefined;
1074 addcarryxU64(&x86, &x87, 0x0, x62, x78);
1075 var x88: u64 = undefined;
1076 var x89: u1 = undefined;
1077 addcarryxU64(&x88, &x89, x87, x64, x80);
1078 var x90: u64 = undefined;
1079 var x91: u1 = undefined;
1080 addcarryxU64(&x90, &x91, x89, x66, x82);
1081 var x92: u64 = undefined;
1082 var x93: u1 = undefined;
1083 addcarryxU64(&x92, &x93, x91, x68, x84);
1084 var x94: u64 = undefined;
1085 var x95: u1 = undefined;
1086 addcarryxU64(&x94, &x95, x93, (@as(u64, x69) + @as(u64, x61)), (@as(u64, x85) + x73));
1087 var x96: u64 = undefined;
1088 var x97: u1 = undefined;
1089 addcarryxU64(&x96, &x97, 0x0, x88, (arg1[3]));
1090 var x98: u64 = undefined;
1091 var x99: u1 = undefined;
1092 addcarryxU64(&x98, &x99, x97, x90, 0x0);
1093 var x100: u64 = undefined;
1094 var x101: u1 = undefined;
1095 addcarryxU64(&x100, &x101, x99, x92, 0x0);
1096 var x102: u64 = undefined;
1097 var x103: u1 = undefined;
1098 addcarryxU64(&x102, &x103, x101, x94, 0x0);
1099 var x104: u64 = undefined;
1100 var x105: u64 = undefined;
1101 mulxU64(&x104, &x105, x96, 0x4b0dff665588b13f);
1102 var x106: u64 = undefined;
1103 var x107: u64 = undefined;
1104 mulxU64(&x106, &x107, x104, 0xffffffffffffffff);
1105 var x108: u64 = undefined;
1106 var x109: u64 = undefined;
1107 mulxU64(&x108, &x109, x104, 0xfffffffffffffffe);
1108 var x110: u64 = undefined;
1109 var x111: u64 = undefined;
1110 mulxU64(&x110, &x111, x104, 0xbaaedce6af48a03b);
1111 var x112: u64 = undefined;
1112 var x113: u64 = undefined;
1113 mulxU64(&x112, &x113, x104, 0xbfd25e8cd0364141);
1114 var x114: u64 = undefined;
1115 var x115: u1 = undefined;
1116 addcarryxU64(&x114, &x115, 0x0, x113, x110);
1117 var x116: u64 = undefined;
1118 var x117: u1 = undefined;
1119 addcarryxU64(&x116, &x117, x115, x111, x108);
1120 var x118: u64 = undefined;
1121 var x119: u1 = undefined;
1122 addcarryxU64(&x118, &x119, x117, x109, x106);
1123 var x120: u64 = undefined;
1124 var x121: u1 = undefined;
1125 addcarryxU64(&x120, &x121, 0x0, x96, x112);
1126 var x122: u64 = undefined;
1127 var x123: u1 = undefined;
1128 addcarryxU64(&x122, &x123, x121, x98, x114);
1129 var x124: u64 = undefined;
1130 var x125: u1 = undefined;
1131 addcarryxU64(&x124, &x125, x123, x100, x116);
1132 var x126: u64 = undefined;
1133 var x127: u1 = undefined;
1134 addcarryxU64(&x126, &x127, x125, x102, x118);
1135 var x128: u64 = undefined;
1136 var x129: u1 = undefined;
1137 addcarryxU64(&x128, &x129, x127, (@as(u64, x103) + @as(u64, x95)), (@as(u64, x119) + x107));
1138 var x130: u64 = undefined;
1139 var x131: u1 = undefined;
1140 subborrowxU64(&x130, &x131, 0x0, x122, 0xbfd25e8cd0364141);
1141 var x132: u64 = undefined;
1142 var x133: u1 = undefined;
1143 subborrowxU64(&x132, &x133, x131, x124, 0xbaaedce6af48a03b);
1144 var x134: u64 = undefined;
1145 var x135: u1 = undefined;
1146 subborrowxU64(&x134, &x135, x133, x126, 0xfffffffffffffffe);
1147 var x136: u64 = undefined;
1148 var x137: u1 = undefined;
1149 subborrowxU64(&x136, &x137, x135, x128, 0xffffffffffffffff);
1150 var x138: u64 = undefined;
1151 var x139: u1 = undefined;
1152 subborrowxU64(&x138, &x139, x137, @as(u64, x129), 0x0);
1153 var x140: u64 = undefined;
1154 cmovznzU64(&x140, x139, x130, x122);
1155 var x141: u64 = undefined;
1156 cmovznzU64(&x141, x139, x132, x124);
1157 var x142: u64 = undefined;
1158 cmovznzU64(&x142, x139, x134, x126);
1159 var x143: u64 = undefined;
1160 cmovznzU64(&x143, x139, x136, x128);
1161 out1[0] = x140;
1162 out1[1] = x141;
1163 out1[2] = x142;
1164 out1[3] = x143;
1165}
1166
1167/// The function toMontgomery translates a field element into the Montgomery domain.
1168///
1169/// Preconditions:
1170/// 0 ≤ eval arg1 < m
1171/// Postconditions:
1172/// eval (from_montgomery out1) mod m = eval arg1 mod m
1173/// 0 ≤ eval out1 < m
1174///
1175pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void {
1176 @setRuntimeSafety(mode == .Debug);
1177
1178 const x1 = (arg1[1]);
1179 const x2 = (arg1[2]);
1180 const x3 = (arg1[3]);
1181 const x4 = (arg1[0]);
1182 var x5: u64 = undefined;
1183 var x6: u64 = undefined;
1184 mulxU64(&x5, &x6, x4, 0x9d671cd581c69bc5);
1185 var x7: u64 = undefined;
1186 var x8: u64 = undefined;
1187 mulxU64(&x7, &x8, x4, 0xe697f5e45bcd07c6);
1188 var x9: u64 = undefined;
1189 var x10: u64 = undefined;
1190 mulxU64(&x9, &x10, x4, 0x741496c20e7cf878);
1191 var x11: u64 = undefined;
1192 var x12: u64 = undefined;
1193 mulxU64(&x11, &x12, x4, 0x896cf21467d7d140);
1194 var x13: u64 = undefined;
1195 var x14: u1 = undefined;
1196 addcarryxU64(&x13, &x14, 0x0, x12, x9);
1197 var x15: u64 = undefined;
1198 var x16: u1 = undefined;
1199 addcarryxU64(&x15, &x16, x14, x10, x7);
1200 var x17: u64 = undefined;
1201 var x18: u1 = undefined;
1202 addcarryxU64(&x17, &x18, x16, x8, x5);
1203 var x19: u64 = undefined;
1204 var x20: u64 = undefined;
1205 mulxU64(&x19, &x20, x11, 0x4b0dff665588b13f);
1206 var x21: u64 = undefined;
1207 var x22: u64 = undefined;
1208 mulxU64(&x21, &x22, x19, 0xffffffffffffffff);
1209 var x23: u64 = undefined;
1210 var x24: u64 = undefined;
1211 mulxU64(&x23, &x24, x19, 0xfffffffffffffffe);
1212 var x25: u64 = undefined;
1213 var x26: u64 = undefined;
1214 mulxU64(&x25, &x26, x19, 0xbaaedce6af48a03b);
1215 var x27: u64 = undefined;
1216 var x28: u64 = undefined;
1217 mulxU64(&x27, &x28, x19, 0xbfd25e8cd0364141);
1218 var x29: u64 = undefined;
1219 var x30: u1 = undefined;
1220 addcarryxU64(&x29, &x30, 0x0, x28, x25);
1221 var x31: u64 = undefined;
1222 var x32: u1 = undefined;
1223 addcarryxU64(&x31, &x32, x30, x26, x23);
1224 var x33: u64 = undefined;
1225 var x34: u1 = undefined;
1226 addcarryxU64(&x33, &x34, x32, x24, x21);
1227 var x35: u64 = undefined;
1228 var x36: u1 = undefined;
1229 addcarryxU64(&x35, &x36, 0x0, x11, x27);
1230 var x37: u64 = undefined;
1231 var x38: u1 = undefined;
1232 addcarryxU64(&x37, &x38, x36, x13, x29);
1233 var x39: u64 = undefined;
1234 var x40: u1 = undefined;
1235 addcarryxU64(&x39, &x40, x38, x15, x31);
1236 var x41: u64 = undefined;
1237 var x42: u1 = undefined;
1238 addcarryxU64(&x41, &x42, x40, x17, x33);
1239 var x43: u64 = undefined;
1240 var x44: u1 = undefined;
1241 addcarryxU64(&x43, &x44, x42, (@as(u64, x18) + x6), (@as(u64, x34) + x22));
1242 var x45: u64 = undefined;
1243 var x46: u64 = undefined;
1244 mulxU64(&x45, &x46, x1, 0x9d671cd581c69bc5);
1245 var x47: u64 = undefined;
1246 var x48: u64 = undefined;
1247 mulxU64(&x47, &x48, x1, 0xe697f5e45bcd07c6);
1248 var x49: u64 = undefined;
1249 var x50: u64 = undefined;
1250 mulxU64(&x49, &x50, x1, 0x741496c20e7cf878);
1251 var x51: u64 = undefined;
1252 var x52: u64 = undefined;
1253 mulxU64(&x51, &x52, x1, 0x896cf21467d7d140);
1254 var x53: u64 = undefined;
1255 var x54: u1 = undefined;
1256 addcarryxU64(&x53, &x54, 0x0, x52, x49);
1257 var x55: u64 = undefined;
1258 var x56: u1 = undefined;
1259 addcarryxU64(&x55, &x56, x54, x50, x47);
1260 var x57: u64 = undefined;
1261 var x58: u1 = undefined;
1262 addcarryxU64(&x57, &x58, x56, x48, x45);
1263 var x59: u64 = undefined;
1264 var x60: u1 = undefined;
1265 addcarryxU64(&x59, &x60, 0x0, x37, x51);
1266 var x61: u64 = undefined;
1267 var x62: u1 = undefined;
1268 addcarryxU64(&x61, &x62, x60, x39, x53);
1269 var x63: u64 = undefined;
1270 var x64: u1 = undefined;
1271 addcarryxU64(&x63, &x64, x62, x41, x55);
1272 var x65: u64 = undefined;
1273 var x66: u1 = undefined;
1274 addcarryxU64(&x65, &x66, x64, x43, x57);
1275 var x67: u64 = undefined;
1276 var x68: u64 = undefined;
1277 mulxU64(&x67, &x68, x59, 0x4b0dff665588b13f);
1278 var x69: u64 = undefined;
1279 var x70: u64 = undefined;
1280 mulxU64(&x69, &x70, x67, 0xffffffffffffffff);
1281 var x71: u64 = undefined;
1282 var x72: u64 = undefined;
1283 mulxU64(&x71, &x72, x67, 0xfffffffffffffffe);
1284 var x73: u64 = undefined;
1285 var x74: u64 = undefined;
1286 mulxU64(&x73, &x74, x67, 0xbaaedce6af48a03b);
1287 var x75: u64 = undefined;
1288 var x76: u64 = undefined;
1289 mulxU64(&x75, &x76, x67, 0xbfd25e8cd0364141);
1290 var x77: u64 = undefined;
1291 var x78: u1 = undefined;
1292 addcarryxU64(&x77, &x78, 0x0, x76, x73);
1293 var x79: u64 = undefined;
1294 var x80: u1 = undefined;
1295 addcarryxU64(&x79, &x80, x78, x74, x71);
1296 var x81: u64 = undefined;
1297 var x82: u1 = undefined;
1298 addcarryxU64(&x81, &x82, x80, x72, x69);
1299 var x83: u64 = undefined;
1300 var x84: u1 = undefined;
1301 addcarryxU64(&x83, &x84, 0x0, x59, x75);
1302 var x85: u64 = undefined;
1303 var x86: u1 = undefined;
1304 addcarryxU64(&x85, &x86, x84, x61, x77);
1305 var x87: u64 = undefined;
1306 var x88: u1 = undefined;
1307 addcarryxU64(&x87, &x88, x86, x63, x79);
1308 var x89: u64 = undefined;
1309 var x90: u1 = undefined;
1310 addcarryxU64(&x89, &x90, x88, x65, x81);
1311 var x91: u64 = undefined;
1312 var x92: u1 = undefined;
1313 addcarryxU64(&x91, &x92, x90, ((@as(u64, x66) + @as(u64, x44)) + (@as(u64, x58) + x46)), (@as(u64, x82) + x70));
1314 var x93: u64 = undefined;
1315 var x94: u64 = undefined;
1316 mulxU64(&x93, &x94, x2, 0x9d671cd581c69bc5);
1317 var x95: u64 = undefined;
1318 var x96: u64 = undefined;
1319 mulxU64(&x95, &x96, x2, 0xe697f5e45bcd07c6);
1320 var x97: u64 = undefined;
1321 var x98: u64 = undefined;
1322 mulxU64(&x97, &x98, x2, 0x741496c20e7cf878);
1323 var x99: u64 = undefined;
1324 var x100: u64 = undefined;
1325 mulxU64(&x99, &x100, x2, 0x896cf21467d7d140);
1326 var x101: u64 = undefined;
1327 var x102: u1 = undefined;
1328 addcarryxU64(&x101, &x102, 0x0, x100, x97);
1329 var x103: u64 = undefined;
1330 var x104: u1 = undefined;
1331 addcarryxU64(&x103, &x104, x102, x98, x95);
1332 var x105: u64 = undefined;
1333 var x106: u1 = undefined;
1334 addcarryxU64(&x105, &x106, x104, x96, x93);
1335 var x107: u64 = undefined;
1336 var x108: u1 = undefined;
1337 addcarryxU64(&x107, &x108, 0x0, x85, x99);
1338 var x109: u64 = undefined;
1339 var x110: u1 = undefined;
1340 addcarryxU64(&x109, &x110, x108, x87, x101);
1341 var x111: u64 = undefined;
1342 var x112: u1 = undefined;
1343 addcarryxU64(&x111, &x112, x110, x89, x103);
1344 var x113: u64 = undefined;
1345 var x114: u1 = undefined;
1346 addcarryxU64(&x113, &x114, x112, x91, x105);
1347 var x115: u64 = undefined;
1348 var x116: u64 = undefined;
1349 mulxU64(&x115, &x116, x107, 0x4b0dff665588b13f);
1350 var x117: u64 = undefined;
1351 var x118: u64 = undefined;
1352 mulxU64(&x117, &x118, x115, 0xffffffffffffffff);
1353 var x119: u64 = undefined;
1354 var x120: u64 = undefined;
1355 mulxU64(&x119, &x120, x115, 0xfffffffffffffffe);
1356 var x121: u64 = undefined;
1357 var x122: u64 = undefined;
1358 mulxU64(&x121, &x122, x115, 0xbaaedce6af48a03b);
1359 var x123: u64 = undefined;
1360 var x124: u64 = undefined;
1361 mulxU64(&x123, &x124, x115, 0xbfd25e8cd0364141);
1362 var x125: u64 = undefined;
1363 var x126: u1 = undefined;
1364 addcarryxU64(&x125, &x126, 0x0, x124, x121);
1365 var x127: u64 = undefined;
1366 var x128: u1 = undefined;
1367 addcarryxU64(&x127, &x128, x126, x122, x119);
1368 var x129: u64 = undefined;
1369 var x130: u1 = undefined;
1370 addcarryxU64(&x129, &x130, x128, x120, x117);
1371 var x131: u64 = undefined;
1372 var x132: u1 = undefined;
1373 addcarryxU64(&x131, &x132, 0x0, x107, x123);
1374 var x133: u64 = undefined;
1375 var x134: u1 = undefined;
1376 addcarryxU64(&x133, &x134, x132, x109, x125);
1377 var x135: u64 = undefined;
1378 var x136: u1 = undefined;
1379 addcarryxU64(&x135, &x136, x134, x111, x127);
1380 var x137: u64 = undefined;
1381 var x138: u1 = undefined;
1382 addcarryxU64(&x137, &x138, x136, x113, x129);
1383 var x139: u64 = undefined;
1384 var x140: u1 = undefined;
1385 addcarryxU64(&x139, &x140, x138, ((@as(u64, x114) + @as(u64, x92)) + (@as(u64, x106) + x94)), (@as(u64, x130) + x118));
1386 var x141: u64 = undefined;
1387 var x142: u64 = undefined;
1388 mulxU64(&x141, &x142, x3, 0x9d671cd581c69bc5);
1389 var x143: u64 = undefined;
1390 var x144: u64 = undefined;
1391 mulxU64(&x143, &x144, x3, 0xe697f5e45bcd07c6);
1392 var x145: u64 = undefined;
1393 var x146: u64 = undefined;
1394 mulxU64(&x145, &x146, x3, 0x741496c20e7cf878);
1395 var x147: u64 = undefined;
1396 var x148: u64 = undefined;
1397 mulxU64(&x147, &x148, x3, 0x896cf21467d7d140);
1398 var x149: u64 = undefined;
1399 var x150: u1 = undefined;
1400 addcarryxU64(&x149, &x150, 0x0, x148, x145);
1401 var x151: u64 = undefined;
1402 var x152: u1 = undefined;
1403 addcarryxU64(&x151, &x152, x150, x146, x143);
1404 var x153: u64 = undefined;
1405 var x154: u1 = undefined;
1406 addcarryxU64(&x153, &x154, x152, x144, x141);
1407 var x155: u64 = undefined;
1408 var x156: u1 = undefined;
1409 addcarryxU64(&x155, &x156, 0x0, x133, x147);
1410 var x157: u64 = undefined;
1411 var x158: u1 = undefined;
1412 addcarryxU64(&x157, &x158, x156, x135, x149);
1413 var x159: u64 = undefined;
1414 var x160: u1 = undefined;
1415 addcarryxU64(&x159, &x160, x158, x137, x151);
1416 var x161: u64 = undefined;
1417 var x162: u1 = undefined;
1418 addcarryxU64(&x161, &x162, x160, x139, x153);
1419 var x163: u64 = undefined;
1420 var x164: u64 = undefined;
1421 mulxU64(&x163, &x164, x155, 0x4b0dff665588b13f);
1422 var x165: u64 = undefined;
1423 var x166: u64 = undefined;
1424 mulxU64(&x165, &x166, x163, 0xffffffffffffffff);
1425 var x167: u64 = undefined;
1426 var x168: u64 = undefined;
1427 mulxU64(&x167, &x168, x163, 0xfffffffffffffffe);
1428 var x169: u64 = undefined;
1429 var x170: u64 = undefined;
1430 mulxU64(&x169, &x170, x163, 0xbaaedce6af48a03b);
1431 var x171: u64 = undefined;
1432 var x172: u64 = undefined;
1433 mulxU64(&x171, &x172, x163, 0xbfd25e8cd0364141);
1434 var x173: u64 = undefined;
1435 var x174: u1 = undefined;
1436 addcarryxU64(&x173, &x174, 0x0, x172, x169);
1437 var x175: u64 = undefined;
1438 var x176: u1 = undefined;
1439 addcarryxU64(&x175, &x176, x174, x170, x167);
1440 var x177: u64 = undefined;
1441 var x178: u1 = undefined;
1442 addcarryxU64(&x177, &x178, x176, x168, x165);
1443 var x179: u64 = undefined;
1444 var x180: u1 = undefined;
1445 addcarryxU64(&x179, &x180, 0x0, x155, x171);
1446 var x181: u64 = undefined;
1447 var x182: u1 = undefined;
1448 addcarryxU64(&x181, &x182, x180, x157, x173);
1449 var x183: u64 = undefined;
1450 var x184: u1 = undefined;
1451 addcarryxU64(&x183, &x184, x182, x159, x175);
1452 var x185: u64 = undefined;
1453 var x186: u1 = undefined;
1454 addcarryxU64(&x185, &x186, x184, x161, x177);
1455 var x187: u64 = undefined;
1456 var x188: u1 = undefined;
1457 addcarryxU64(&x187, &x188, x186, ((@as(u64, x162) + @as(u64, x140)) + (@as(u64, x154) + x142)), (@as(u64, x178) + x166));
1458 var x189: u64 = undefined;
1459 var x190: u1 = undefined;
1460 subborrowxU64(&x189, &x190, 0x0, x181, 0xbfd25e8cd0364141);
1461 var x191: u64 = undefined;
1462 var x192: u1 = undefined;
1463 subborrowxU64(&x191, &x192, x190, x183, 0xbaaedce6af48a03b);
1464 var x193: u64 = undefined;
1465 var x194: u1 = undefined;
1466 subborrowxU64(&x193, &x194, x192, x185, 0xfffffffffffffffe);
1467 var x195: u64 = undefined;
1468 var x196: u1 = undefined;
1469 subborrowxU64(&x195, &x196, x194, x187, 0xffffffffffffffff);
1470 var x197: u64 = undefined;
1471 var x198: u1 = undefined;
1472 subborrowxU64(&x197, &x198, x196, @as(u64, x188), 0x0);
1473 var x199: u64 = undefined;
1474 cmovznzU64(&x199, x198, x189, x181);
1475 var x200: u64 = undefined;
1476 cmovznzU64(&x200, x198, x191, x183);
1477 var x201: u64 = undefined;
1478 cmovznzU64(&x201, x198, x193, x185);
1479 var x202: u64 = undefined;
1480 cmovznzU64(&x202, x198, x195, x187);
1481 out1[0] = x199;
1482 out1[1] = x200;
1483 out1[2] = x201;
1484 out1[3] = x202;
1485}
1486
1487/// The function nonzero outputs a single non-zero word if the input is non-zero and zero otherwise.
1488///
1489/// Preconditions:
1490/// 0 ≤ eval arg1 < m
1491/// Postconditions:
1492/// out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0
1493///
1494/// Input Bounds:
1495/// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1496/// Output Bounds:
1497/// out1: [0x0 ~> 0xffffffffffffffff]
1498pub fn nonzero(out1: *u64, arg1: [4]u64) void {
1499 @setRuntimeSafety(mode == .Debug);
1500
1501 const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3]))));
1502 out1.* = x1;
1503}
1504
1505/// The function selectznz is a multi-limb conditional select.
1506///
1507/// Postconditions:
1508/// out1 = (if arg1 = 0 then arg2 else arg3)
1509///
1510/// Input Bounds:
1511/// arg1: [0x0 ~> 0x1]
1512/// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1513/// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1514/// Output Bounds:
1515/// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1516pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void {
1517 @setRuntimeSafety(mode == .Debug);
1518
1519 var x1: u64 = undefined;
1520 cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0]));
1521 var x2: u64 = undefined;
1522 cmovznzU64(&x2, arg1, (arg2[1]), (arg3[1]));
1523 var x3: u64 = undefined;
1524 cmovznzU64(&x3, arg1, (arg2[2]), (arg3[2]));
1525 var x4: u64 = undefined;
1526 cmovznzU64(&x4, arg1, (arg2[3]), (arg3[3]));
1527 out1[0] = x1;
1528 out1[1] = x2;
1529 out1[2] = x3;
1530 out1[3] = x4;
1531}
1532
1533/// The function toBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order.
1534///
1535/// Preconditions:
1536/// 0 ≤ eval arg1 < m
1537/// Postconditions:
1538/// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31]
1539///
1540/// Input Bounds:
1541/// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1542/// Output Bounds:
1543/// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]]
1544pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void {
1545 @setRuntimeSafety(mode == .Debug);
1546
1547 const x1 = (arg1[3]);
1548 const x2 = (arg1[2]);
1549 const x3 = (arg1[1]);
1550 const x4 = (arg1[0]);
1551 const x5 = @truncate(u8, (x4 & 0xff));
1552 const x6 = (x4 >> 8);
1553 const x7 = @truncate(u8, (x6 & 0xff));
1554 const x8 = (x6 >> 8);
1555 const x9 = @truncate(u8, (x8 & 0xff));
1556 const x10 = (x8 >> 8);
1557 const x11 = @truncate(u8, (x10 & 0xff));
1558 const x12 = (x10 >> 8);
1559 const x13 = @truncate(u8, (x12 & 0xff));
1560 const x14 = (x12 >> 8);
1561 const x15 = @truncate(u8, (x14 & 0xff));
1562 const x16 = (x14 >> 8);
1563 const x17 = @truncate(u8, (x16 & 0xff));
1564 const x18 = @truncate(u8, (x16 >> 8));
1565 const x19 = @truncate(u8, (x3 & 0xff));
1566 const x20 = (x3 >> 8);
1567 const x21 = @truncate(u8, (x20 & 0xff));
1568 const x22 = (x20 >> 8);
1569 const x23 = @truncate(u8, (x22 & 0xff));
1570 const x24 = (x22 >> 8);
1571 const x25 = @truncate(u8, (x24 & 0xff));
1572 const x26 = (x24 >> 8);
1573 const x27 = @truncate(u8, (x26 & 0xff));
1574 const x28 = (x26 >> 8);
1575 const x29 = @truncate(u8, (x28 & 0xff));
1576 const x30 = (x28 >> 8);
1577 const x31 = @truncate(u8, (x30 & 0xff));
1578 const x32 = @truncate(u8, (x30 >> 8));
1579 const x33 = @truncate(u8, (x2 & 0xff));
1580 const x34 = (x2 >> 8);
1581 const x35 = @truncate(u8, (x34 & 0xff));
1582 const x36 = (x34 >> 8);
1583 const x37 = @truncate(u8, (x36 & 0xff));
1584 const x38 = (x36 >> 8);
1585 const x39 = @truncate(u8, (x38 & 0xff));
1586 const x40 = (x38 >> 8);
1587 const x41 = @truncate(u8, (x40 & 0xff));
1588 const x42 = (x40 >> 8);
1589 const x43 = @truncate(u8, (x42 & 0xff));
1590 const x44 = (x42 >> 8);
1591 const x45 = @truncate(u8, (x44 & 0xff));
1592 const x46 = @truncate(u8, (x44 >> 8));
1593 const x47 = @truncate(u8, (x1 & 0xff));
1594 const x48 = (x1 >> 8);
1595 const x49 = @truncate(u8, (x48 & 0xff));
1596 const x50 = (x48 >> 8);
1597 const x51 = @truncate(u8, (x50 & 0xff));
1598 const x52 = (x50 >> 8);
1599 const x53 = @truncate(u8, (x52 & 0xff));
1600 const x54 = (x52 >> 8);
1601 const x55 = @truncate(u8, (x54 & 0xff));
1602 const x56 = (x54 >> 8);
1603 const x57 = @truncate(u8, (x56 & 0xff));
1604 const x58 = (x56 >> 8);
1605 const x59 = @truncate(u8, (x58 & 0xff));
1606 const x60 = @truncate(u8, (x58 >> 8));
1607 out1[0] = x5;
1608 out1[1] = x7;
1609 out1[2] = x9;
1610 out1[3] = x11;
1611 out1[4] = x13;
1612 out1[5] = x15;
1613 out1[6] = x17;
1614 out1[7] = x18;
1615 out1[8] = x19;
1616 out1[9] = x21;
1617 out1[10] = x23;
1618 out1[11] = x25;
1619 out1[12] = x27;
1620 out1[13] = x29;
1621 out1[14] = x31;
1622 out1[15] = x32;
1623 out1[16] = x33;
1624 out1[17] = x35;
1625 out1[18] = x37;
1626 out1[19] = x39;
1627 out1[20] = x41;
1628 out1[21] = x43;
1629 out1[22] = x45;
1630 out1[23] = x46;
1631 out1[24] = x47;
1632 out1[25] = x49;
1633 out1[26] = x51;
1634 out1[27] = x53;
1635 out1[28] = x55;
1636 out1[29] = x57;
1637 out1[30] = x59;
1638 out1[31] = x60;
1639}
1640
1641/// The function fromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order.
1642///
1643/// Preconditions:
1644/// 0 ≤ bytes_eval arg1 < m
1645/// Postconditions:
1646/// eval out1 mod m = bytes_eval arg1 mod m
1647/// 0 ≤ eval out1 < m
1648///
1649/// Input Bounds:
1650/// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]]
1651/// Output Bounds:
1652/// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1653pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void {
1654 @setRuntimeSafety(mode == .Debug);
1655
1656 const x1 = (@as(u64, (arg1[31])) << 56);
1657 const x2 = (@as(u64, (arg1[30])) << 48);
1658 const x3 = (@as(u64, (arg1[29])) << 40);
1659 const x4 = (@as(u64, (arg1[28])) << 32);
1660 const x5 = (@as(u64, (arg1[27])) << 24);
1661 const x6 = (@as(u64, (arg1[26])) << 16);
1662 const x7 = (@as(u64, (arg1[25])) << 8);
1663 const x8 = (arg1[24]);
1664 const x9 = (@as(u64, (arg1[23])) << 56);
1665 const x10 = (@as(u64, (arg1[22])) << 48);
1666 const x11 = (@as(u64, (arg1[21])) << 40);
1667 const x12 = (@as(u64, (arg1[20])) << 32);
1668 const x13 = (@as(u64, (arg1[19])) << 24);
1669 const x14 = (@as(u64, (arg1[18])) << 16);
1670 const x15 = (@as(u64, (arg1[17])) << 8);
1671 const x16 = (arg1[16]);
1672 const x17 = (@as(u64, (arg1[15])) << 56);
1673 const x18 = (@as(u64, (arg1[14])) << 48);
1674 const x19 = (@as(u64, (arg1[13])) << 40);
1675 const x20 = (@as(u64, (arg1[12])) << 32);
1676 const x21 = (@as(u64, (arg1[11])) << 24);
1677 const x22 = (@as(u64, (arg1[10])) << 16);
1678 const x23 = (@as(u64, (arg1[9])) << 8);
1679 const x24 = (arg1[8]);
1680 const x25 = (@as(u64, (arg1[7])) << 56);
1681 const x26 = (@as(u64, (arg1[6])) << 48);
1682 const x27 = (@as(u64, (arg1[5])) << 40);
1683 const x28 = (@as(u64, (arg1[4])) << 32);
1684 const x29 = (@as(u64, (arg1[3])) << 24);
1685 const x30 = (@as(u64, (arg1[2])) << 16);
1686 const x31 = (@as(u64, (arg1[1])) << 8);
1687 const x32 = (arg1[0]);
1688 const x33 = (x31 + @as(u64, x32));
1689 const x34 = (x30 + x33);
1690 const x35 = (x29 + x34);
1691 const x36 = (x28 + x35);
1692 const x37 = (x27 + x36);
1693 const x38 = (x26 + x37);
1694 const x39 = (x25 + x38);
1695 const x40 = (x23 + @as(u64, x24));
1696 const x41 = (x22 + x40);
1697 const x42 = (x21 + x41);
1698 const x43 = (x20 + x42);
1699 const x44 = (x19 + x43);
1700 const x45 = (x18 + x44);
1701 const x46 = (x17 + x45);
1702 const x47 = (x15 + @as(u64, x16));
1703 const x48 = (x14 + x47);
1704 const x49 = (x13 + x48);
1705 const x50 = (x12 + x49);
1706 const x51 = (x11 + x50);
1707 const x52 = (x10 + x51);
1708 const x53 = (x9 + x52);
1709 const x54 = (x7 + @as(u64, x8));
1710 const x55 = (x6 + x54);
1711 const x56 = (x5 + x55);
1712 const x57 = (x4 + x56);
1713 const x58 = (x3 + x57);
1714 const x59 = (x2 + x58);
1715 const x60 = (x1 + x59);
1716 out1[0] = x39;
1717 out1[1] = x46;
1718 out1[2] = x53;
1719 out1[3] = x60;
1720}
1721
1722/// The function setOne returns the field element one in the Montgomery domain.
1723///
1724/// Postconditions:
1725/// eval (from_montgomery out1) mod m = 1 mod m
1726/// 0 ≤ eval out1 < m
1727///
1728pub fn setOne(out1: *MontgomeryDomainFieldElement) void {
1729 @setRuntimeSafety(mode == .Debug);
1730
1731 out1[0] = 0x402da1732fc9bebf;
1732 out1[1] = 0x4551231950b75fc4;
1733 out1[2] = 0x1;
1734 out1[3] = 0x0;
1735}
1736
1737/// The function msat returns the saturated representation of the prime modulus.
1738///
1739/// Postconditions:
1740/// twos_complement_eval out1 = m
1741/// 0 ≤ eval out1 < m
1742///
1743/// Output Bounds:
1744/// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1745pub fn msat(out1: *[5]u64) void {
1746 @setRuntimeSafety(mode == .Debug);
1747
1748 out1[0] = 0xbfd25e8cd0364141;
1749 out1[1] = 0xbaaedce6af48a03b;
1750 out1[2] = 0xfffffffffffffffe;
1751 out1[3] = 0xffffffffffffffff;
1752 out1[4] = 0x0;
1753}
1754
1755/// The function divstep computes a divstep.
1756///
1757/// Preconditions:
1758/// 0 ≤ eval arg4 < m
1759/// 0 ≤ eval arg5 < m
1760/// Postconditions:
1761/// out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1)
1762/// twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2)
1763/// twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋)
1764/// eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m)
1765/// eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m)
1766/// 0 ≤ eval out5 < m
1767/// 0 ≤ eval out5 < m
1768/// 0 ≤ eval out2 < m
1769/// 0 ≤ eval out3 < m
1770///
1771/// Input Bounds:
1772/// arg1: [0x0 ~> 0xffffffffffffffff]
1773/// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1774/// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1775/// arg4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1776/// arg5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1777/// Output Bounds:
1778/// out1: [0x0 ~> 0xffffffffffffffff]
1779/// out2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1780/// out3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1781/// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1782/// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
1783pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void {
1784 @setRuntimeSafety(mode == .Debug);
1785
1786 var x1: u64 = undefined;
1787 var x2: u1 = undefined;
1788 addcarryxU64(&x1, &x2, 0x0, (~arg1), 0x1);
1789 const x3 = (@truncate(u1, (x1 >> 63)) & @truncate(u1, ((arg3[0]) & 0x1)));
1790 var x4: u64 = undefined;
1791 var x5: u1 = undefined;
1792 addcarryxU64(&x4, &x5, 0x0, (~arg1), 0x1);
1793 var x6: u64 = undefined;
1794 cmovznzU64(&x6, x3, arg1, x4);
1795 var x7: u64 = undefined;
1796 cmovznzU64(&x7, x3, (arg2[0]), (arg3[0]));
1797 var x8: u64 = undefined;
1798 cmovznzU64(&x8, x3, (arg2[1]), (arg3[1]));
1799 var x9: u64 = undefined;
1800 cmovznzU64(&x9, x3, (arg2[2]), (arg3[2]));
1801 var x10: u64 = undefined;
1802 cmovznzU64(&x10, x3, (arg2[3]), (arg3[3]));
1803 var x11: u64 = undefined;
1804 cmovznzU64(&x11, x3, (arg2[4]), (arg3[4]));
1805 var x12: u64 = undefined;
1806 var x13: u1 = undefined;
1807 addcarryxU64(&x12, &x13, 0x0, 0x1, (~(arg2[0])));
1808 var x14: u64 = undefined;
1809 var x15: u1 = undefined;
1810 addcarryxU64(&x14, &x15, x13, 0x0, (~(arg2[1])));
1811 var x16: u64 = undefined;
1812 var x17: u1 = undefined;
1813 addcarryxU64(&x16, &x17, x15, 0x0, (~(arg2[2])));
1814 var x18: u64 = undefined;
1815 var x19: u1 = undefined;
1816 addcarryxU64(&x18, &x19, x17, 0x0, (~(arg2[3])));
1817 var x20: u64 = undefined;
1818 var x21: u1 = undefined;
1819 addcarryxU64(&x20, &x21, x19, 0x0, (~(arg2[4])));
1820 var x22: u64 = undefined;
1821 cmovznzU64(&x22, x3, (arg3[0]), x12);
1822 var x23: u64 = undefined;
1823 cmovznzU64(&x23, x3, (arg3[1]), x14);
1824 var x24: u64 = undefined;
1825 cmovznzU64(&x24, x3, (arg3[2]), x16);
1826 var x25: u64 = undefined;
1827 cmovznzU64(&x25, x3, (arg3[3]), x18);
1828 var x26: u64 = undefined;
1829 cmovznzU64(&x26, x3, (arg3[4]), x20);
1830 var x27: u64 = undefined;
1831 cmovznzU64(&x27, x3, (arg4[0]), (arg5[0]));
1832 var x28: u64 = undefined;
1833 cmovznzU64(&x28, x3, (arg4[1]), (arg5[1]));
1834 var x29: u64 = undefined;
1835 cmovznzU64(&x29, x3, (arg4[2]), (arg5[2]));
1836 var x30: u64 = undefined;
1837 cmovznzU64(&x30, x3, (arg4[3]), (arg5[3]));
1838 var x31: u64 = undefined;
1839 var x32: u1 = undefined;
1840 addcarryxU64(&x31, &x32, 0x0, x27, x27);
1841 var x33: u64 = undefined;
1842 var x34: u1 = undefined;
1843 addcarryxU64(&x33, &x34, x32, x28, x28);
1844 var x35: u64 = undefined;
1845 var x36: u1 = undefined;
1846 addcarryxU64(&x35, &x36, x34, x29, x29);
1847 var x37: u64 = undefined;
1848 var x38: u1 = undefined;
1849 addcarryxU64(&x37, &x38, x36, x30, x30);
1850 var x39: u64 = undefined;
1851 var x40: u1 = undefined;
1852 subborrowxU64(&x39, &x40, 0x0, x31, 0xbfd25e8cd0364141);
1853 var x41: u64 = undefined;
1854 var x42: u1 = undefined;
1855 subborrowxU64(&x41, &x42, x40, x33, 0xbaaedce6af48a03b);
1856 var x43: u64 = undefined;
1857 var x44: u1 = undefined;
1858 subborrowxU64(&x43, &x44, x42, x35, 0xfffffffffffffffe);
1859 var x45: u64 = undefined;
1860 var x46: u1 = undefined;
1861 subborrowxU64(&x45, &x46, x44, x37, 0xffffffffffffffff);
1862 var x47: u64 = undefined;
1863 var x48: u1 = undefined;
1864 subborrowxU64(&x47, &x48, x46, @as(u64, x38), 0x0);
1865 const x49 = (arg4[3]);
1866 const x50 = (arg4[2]);
1867 const x51 = (arg4[1]);
1868 const x52 = (arg4[0]);
1869 var x53: u64 = undefined;
1870 var x54: u1 = undefined;
1871 subborrowxU64(&x53, &x54, 0x0, 0x0, x52);
1872 var x55: u64 = undefined;
1873 var x56: u1 = undefined;
1874 subborrowxU64(&x55, &x56, x54, 0x0, x51);
1875 var x57: u64 = undefined;
1876 var x58: u1 = undefined;
1877 subborrowxU64(&x57, &x58, x56, 0x0, x50);
1878 var x59: u64 = undefined;
1879 var x60: u1 = undefined;
1880 subborrowxU64(&x59, &x60, x58, 0x0, x49);
1881 var x61: u64 = undefined;
1882 cmovznzU64(&x61, x60, 0x0, 0xffffffffffffffff);
1883 var x62: u64 = undefined;
1884 var x63: u1 = undefined;
1885 addcarryxU64(&x62, &x63, 0x0, x53, (x61 & 0xbfd25e8cd0364141));
1886 var x64: u64 = undefined;
1887 var x65: u1 = undefined;
1888 addcarryxU64(&x64, &x65, x63, x55, (x61 & 0xbaaedce6af48a03b));
1889 var x66: u64 = undefined;
1890 var x67: u1 = undefined;
1891 addcarryxU64(&x66, &x67, x65, x57, (x61 & 0xfffffffffffffffe));
1892 var x68: u64 = undefined;
1893 var x69: u1 = undefined;
1894 addcarryxU64(&x68, &x69, x67, x59, x61);
1895 var x70: u64 = undefined;
1896 cmovznzU64(&x70, x3, (arg5[0]), x62);
1897 var x71: u64 = undefined;
1898 cmovznzU64(&x71, x3, (arg5[1]), x64);
1899 var x72: u64 = undefined;
1900 cmovznzU64(&x72, x3, (arg5[2]), x66);
1901 var x73: u64 = undefined;
1902 cmovznzU64(&x73, x3, (arg5[3]), x68);
1903 const x74 = @truncate(u1, (x22 & 0x1));
1904 var x75: u64 = undefined;
1905 cmovznzU64(&x75, x74, 0x0, x7);
1906 var x76: u64 = undefined;
1907 cmovznzU64(&x76, x74, 0x0, x8);
1908 var x77: u64 = undefined;
1909 cmovznzU64(&x77, x74, 0x0, x9);
1910 var x78: u64 = undefined;
1911 cmovznzU64(&x78, x74, 0x0, x10);
1912 var x79: u64 = undefined;
1913 cmovznzU64(&x79, x74, 0x0, x11);
1914 var x80: u64 = undefined;
1915 var x81: u1 = undefined;
1916 addcarryxU64(&x80, &x81, 0x0, x22, x75);
1917 var x82: u64 = undefined;
1918 var x83: u1 = undefined;
1919 addcarryxU64(&x82, &x83, x81, x23, x76);
1920 var x84: u64 = undefined;
1921 var x85: u1 = undefined;
1922 addcarryxU64(&x84, &x85, x83, x24, x77);
1923 var x86: u64 = undefined;
1924 var x87: u1 = undefined;
1925 addcarryxU64(&x86, &x87, x85, x25, x78);
1926 var x88: u64 = undefined;
1927 var x89: u1 = undefined;
1928 addcarryxU64(&x88, &x89, x87, x26, x79);
1929 var x90: u64 = undefined;
1930 cmovznzU64(&x90, x74, 0x0, x27);
1931 var x91: u64 = undefined;
1932 cmovznzU64(&x91, x74, 0x0, x28);
1933 var x92: u64 = undefined;
1934 cmovznzU64(&x92, x74, 0x0, x29);
1935 var x93: u64 = undefined;
1936 cmovznzU64(&x93, x74, 0x0, x30);
1937 var x94: u64 = undefined;
1938 var x95: u1 = undefined;
1939 addcarryxU64(&x94, &x95, 0x0, x70, x90);
1940 var x96: u64 = undefined;
1941 var x97: u1 = undefined;
1942 addcarryxU64(&x96, &x97, x95, x71, x91);
1943 var x98: u64 = undefined;
1944 var x99: u1 = undefined;
1945 addcarryxU64(&x98, &x99, x97, x72, x92);
1946 var x100: u64 = undefined;
1947 var x101: u1 = undefined;
1948 addcarryxU64(&x100, &x101, x99, x73, x93);
1949 var x102: u64 = undefined;
1950 var x103: u1 = undefined;
1951 subborrowxU64(&x102, &x103, 0x0, x94, 0xbfd25e8cd0364141);
1952 var x104: u64 = undefined;
1953 var x105: u1 = undefined;
1954 subborrowxU64(&x104, &x105, x103, x96, 0xbaaedce6af48a03b);
1955 var x106: u64 = undefined;
1956 var x107: u1 = undefined;
1957 subborrowxU64(&x106, &x107, x105, x98, 0xfffffffffffffffe);
1958 var x108: u64 = undefined;
1959 var x109: u1 = undefined;
1960 subborrowxU64(&x108, &x109, x107, x100, 0xffffffffffffffff);
1961 var x110: u64 = undefined;
1962 var x111: u1 = undefined;
1963 subborrowxU64(&x110, &x111, x109, @as(u64, x101), 0x0);
1964 var x112: u64 = undefined;
1965 var x113: u1 = undefined;
1966 addcarryxU64(&x112, &x113, 0x0, x6, 0x1);
1967 const x114 = ((x80 >> 1) | ((x82 << 63) & 0xffffffffffffffff));
1968 const x115 = ((x82 >> 1) | ((x84 << 63) & 0xffffffffffffffff));
1969 const x116 = ((x84 >> 1) | ((x86 << 63) & 0xffffffffffffffff));
1970 const x117 = ((x86 >> 1) | ((x88 << 63) & 0xffffffffffffffff));
1971 const x118 = ((x88 & 0x8000000000000000) | (x88 >> 1));
1972 var x119: u64 = undefined;
1973 cmovznzU64(&x119, x48, x39, x31);
1974 var x120: u64 = undefined;
1975 cmovznzU64(&x120, x48, x41, x33);
1976 var x121: u64 = undefined;
1977 cmovznzU64(&x121, x48, x43, x35);
1978 var x122: u64 = undefined;
1979 cmovznzU64(&x122, x48, x45, x37);
1980 var x123: u64 = undefined;
1981 cmovznzU64(&x123, x111, x102, x94);
1982 var x124: u64 = undefined;
1983 cmovznzU64(&x124, x111, x104, x96);
1984 var x125: u64 = undefined;
1985 cmovznzU64(&x125, x111, x106, x98);
1986 var x126: u64 = undefined;
1987 cmovznzU64(&x126, x111, x108, x100);
1988 out1.* = x112;
1989 out2[0] = x7;
1990 out2[1] = x8;
1991 out2[2] = x9;
1992 out2[3] = x10;
1993 out2[4] = x11;
1994 out3[0] = x114;
1995 out3[1] = x115;
1996 out3[2] = x116;
1997 out3[3] = x117;
1998 out3[4] = x118;
1999 out4[0] = x119;
2000 out4[1] = x120;
2001 out4[2] = x121;
2002 out4[3] = x122;
2003 out5[0] = x123;
2004 out5[1] = x124;
2005 out5[2] = x125;
2006 out5[3] = x126;
2007}
2008
2009/// The function divstepPrecomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form).
2010///
2011/// Postconditions:
2012/// eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋)
2013/// 0 ≤ eval out1 < m
2014///
2015/// Output Bounds:
2016/// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
2017pub fn divstepPrecomp(out1: *[4]u64) void {
2018 @setRuntimeSafety(mode == .Debug);
2019
2020 out1[0] = 0xd7431a4d2b9cb4e9;
2021 out1[1] = 0xab67d35a32d9c503;
2022 out1[2] = 0xadf6c7e5859ce35f;
2023 out1[3] = 0x615441451df6c379;
2024}
lib/std/crypto/pcurves/tests/secp256k1.zig created+137
...@@ -0,0 +1,137 @@
1const std = @import("std");
2const fmt = std.fmt;
3const testing = std.testing;
4
5const Secp256k1 = @import("../secp256k1.zig").Secp256k1;
6
7test "secp256k1 ECDH key exchange" {
8 const dha = Secp256k1.scalar.random(.Little);
9 const dhb = Secp256k1.scalar.random(.Little);
10 const dhA = try Secp256k1.basePoint.mul(dha, .Little);
11 const dhB = try Secp256k1.basePoint.mul(dhb, .Little);
12 const shareda = try dhA.mul(dhb, .Little);
13 const sharedb = try dhB.mul(dha, .Little);
14 try testing.expect(shareda.equivalent(sharedb));
15}
16
17test "secp256k1 ECDH key exchange including public multiplication" {
18 const dha = Secp256k1.scalar.random(.Little);
19 const dhb = Secp256k1.scalar.random(.Little);
20 const dhA = try Secp256k1.basePoint.mul(dha, .Little);
21 const dhB = try Secp256k1.basePoint.mulPublic(dhb, .Little);
22 const shareda = try dhA.mul(dhb, .Little);
23 const sharedb = try dhB.mulPublic(dha, .Little);
24 try testing.expect(shareda.equivalent(sharedb));
25}
26
27test "secp256k1 point from affine coordinates" {
28 const xh = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798";
29 const yh = "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8";
30 var xs: [32]u8 = undefined;
31 _ = try fmt.hexToBytes(&xs, xh);
32 var ys: [32]u8 = undefined;
33 _ = try fmt.hexToBytes(&ys, yh);
34 var p = try Secp256k1.fromSerializedAffineCoordinates(xs, ys, .Big);
35 try testing.expect(p.equivalent(Secp256k1.basePoint));
36}
37
38test "secp256k1 test vectors" {
39 const expected = [_][]const u8{
40 "0000000000000000000000000000000000000000000000000000000000000000",
41 "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
42 "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
43 "f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9",
44 "e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13",
45 "2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4",
46 "fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556",
47 "5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc",
48 "2f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01",
49 "acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe",
50 };
51 var p = Secp256k1.identityElement;
52 for (expected) |xh| {
53 const x = p.affineCoordinates().x;
54 p = p.add(Secp256k1.basePoint);
55 var xs: [32]u8 = undefined;
56 _ = try fmt.hexToBytes(&xs, xh);
57 try testing.expectEqualSlices(u8, &x.toBytes(.Big), &xs);
58 }
59}
60
61test "secp256k1 test vectors - doubling" {
62 const expected = [_][]const u8{
63 "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
64 "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
65 "e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13",
66 "2f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01",
67 "e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a",
68 };
69 var p = Secp256k1.basePoint;
70 for (expected) |xh| {
71 const x = p.affineCoordinates().x;
72 p = p.dbl();
73 var xs: [32]u8 = undefined;
74 _ = try fmt.hexToBytes(&xs, xh);
75 try testing.expectEqualSlices(u8, &x.toBytes(.Big), &xs);
76 }
77}
78
79test "secp256k1 compressed sec1 encoding/decoding" {
80 const p = Secp256k1.random();
81 const s = p.toCompressedSec1();
82 const q = try Secp256k1.fromSec1(&s);
83 try testing.expect(p.equivalent(q));
84}
85
86test "secp256k1 uncompressed sec1 encoding/decoding" {
87 const p = Secp256k1.random();
88 const s = p.toUncompressedSec1();
89 const q = try Secp256k1.fromSec1(&s);
90 try testing.expect(p.equivalent(q));
91}
92
93test "secp256k1 public key is the neutral element" {
94 const n = Secp256k1.scalar.Scalar.zero.toBytes(.Little);
95 const p = Secp256k1.random();
96 try testing.expectError(error.IdentityElement, p.mul(n, .Little));
97}
98
99test "secp256k1 public key is the neutral element (public verification)" {
100 const n = Secp256k1.scalar.Scalar.zero.toBytes(.Little);
101 const p = Secp256k1.random();
102 try testing.expectError(error.IdentityElement, p.mulPublic(n, .Little));
103}
104
105test "secp256k1 field element non-canonical encoding" {
106 const s = [_]u8{0xff} ** 32;
107 try testing.expectError(error.NonCanonical, Secp256k1.Fe.fromBytes(s, .Little));
108}
109
110test "secp256k1 neutral element decoding" {
111 try testing.expectError(error.InvalidEncoding, Secp256k1.fromAffineCoordinates(.{ .x = Secp256k1.Fe.zero, .y = Secp256k1.Fe.zero }));
112 const p = try Secp256k1.fromAffineCoordinates(.{ .x = Secp256k1.Fe.zero, .y = Secp256k1.Fe.one });
113 try testing.expectError(error.IdentityElement, p.rejectIdentity());
114}
115
116test "secp256k1 double base multiplication" {
117 const p1 = Secp256k1.basePoint;
118 const p2 = Secp256k1.basePoint.dbl();
119 const s1 = [_]u8{0x01} ** 32;
120 const s2 = [_]u8{0x02} ** 32;
121 const pr1 = try Secp256k1.mulDoubleBasePublic(p1, s1, p2, s2, .Little);
122 const pr2 = (try p1.mul(s1, .Little)).add(try p2.mul(s2, .Little));
123 try testing.expect(pr1.equivalent(pr2));
124}
125
126test "secp256k1 scalar inverse" {
127 const expected = "08d0684a0fe8ea978b68a29e4b4ffdbd19eeb59db25301cf23ecbe568e1f9822";
128 var out: [32]u8 = undefined;
129 _ = try std.fmt.hexToBytes(&out, expected);
130
131 const scalar = try Secp256k1.scalar.Scalar.fromBytes(.{
132 0x94, 0xa1, 0xbb, 0xb1, 0x4b, 0x90, 0x6a, 0x61, 0xa2, 0x80, 0xf2, 0x45, 0xf9, 0xe9, 0x3c, 0x7f,
133 0x3b, 0x4a, 0x62, 0x47, 0x82, 0x4f, 0x5d, 0x33, 0xb9, 0x67, 0x07, 0x87, 0x64, 0x2a, 0x68, 0xde,
134 }, .Big);
135 const inverse = scalar.invert();
136 try std.testing.expectEqualSlices(u8, &out, &inverse.toBytes(.Big));
137}