feature. See also
. The project being documented here (as the example) is the Zig library itself.
scalar.ScalarDouble
const ScalarDouble = struct
File
Code
const ScalarDouble = struct {
const Limbs = [10]u64;
limbs: Limbs = undefined,
fn fromBytes64(bytes: [64]u8) ScalarDouble {
var limbs: Limbs = undefined;
var i: usize = 0;
while (i < 9) : (i += 1) {
limbs[i] = mem.readInt(u64, bytes[i * 7 ..][0..8], .little) & 0xffffffffffffff;
}
limbs[i] = @as(u64, bytes[i * 7]);
return ScalarDouble{ .limbs = limbs };
}
fn fromBytes32(bytes: CompressedScalar) ScalarDouble {
var limbs: Limbs = undefined;
var i: usize = 0;
while (i < 4) : (i += 1) {
limbs[i] = mem.readInt(u64, bytes[i * 7 ..][0..8], .little) & 0xffffffffffffff;
}
limbs[i] = @as(u64, mem.readInt(u32, bytes[i * 7 ..][0..4], .little));
@memset(limbs[5..], 0);
return ScalarDouble{ .limbs = limbs };
}
fn toBytes(expanded_double: *ScalarDouble) CompressedScalar {
return expanded_double.reduce(10).toBytes();
}
fn reduce(expanded: *ScalarDouble, comptime limbs_count: usize) Scalar {
const t = expanded.limbs;
const t0 = if (limbs_count <= 0) 0 else t[0];
const t1 = if (limbs_count <= 1) 0 else t[1];
const t2 = if (limbs_count <= 2) 0 else t[2];
const t3 = if (limbs_count <= 3) 0 else t[3];
const t4 = if (limbs_count <= 4) 0 else t[4];
const t5 = if (limbs_count <= 5) 0 else t[5];
const t6 = if (limbs_count <= 6) 0 else t[6];
const t7 = if (limbs_count <= 7) 0 else t[7];
const t8 = if (limbs_count <= 8) 0 else t[8];
const t9 = if (limbs_count <= 9) 0 else t[9];
const m0: u64 = 5175514460705773;
const m1: u64 = 70332060721272408;
const m2: u64 = 5342;
const m3: u64 = 0;
const m4: u64 = 268435456;
const mu0: u64 = 44162584779952923;
const mu1: u64 = 9390964836247533;
const mu2: u64 = 72057594036560134;
const mu3: u64 = 0xffffffffffffff;
const mu4: u64 = 68719476735;
const y_ = (t5 & 0xffffff) << 32;
const x_ = t4 >> 24;
const z00 = x_ | y_;
const y_0 = (t6 & 0xffffff) << 32;
const x_0 = t5 >> 24;
const z10 = x_0 | y_0;
const y_1 = (t7 & 0xffffff) << 32;
const x_1 = t6 >> 24;
const z20 = x_1 | y_1;
const y_2 = (t8 & 0xffffff) << 32;
const x_2 = t7 >> 24;
const z30 = x_2 | y_2;
const y_3 = (t9 & 0xffffff) << 32;
const x_3 = t8 >> 24;
const z40 = x_3 | y_3;
const q0 = z00;
const q1 = z10;
const q2 = z20;
const q3 = z30;
const q4 = z40;
const xy000 = @as(u128, q0) * @as(u128, mu0);
const xy010 = @as(u128, q0) * @as(u128, mu1);
const xy020 = @as(u128, q0) * @as(u128, mu2);
const xy030 = @as(u128, q0) * @as(u128, mu3);
const xy040 = @as(u128, q0) * @as(u128, mu4);
const xy100 = @as(u128, q1) * @as(u128, mu0);
const xy110 = @as(u128, q1) * @as(u128, mu1);
const xy120 = @as(u128, q1) * @as(u128, mu2);
const xy130 = @as(u128, q1) * @as(u128, mu3);
const xy14 = @as(u128, q1) * @as(u128, mu4);
const xy200 = @as(u128, q2) * @as(u128, mu0);
const xy210 = @as(u128, q2) * @as(u128, mu1);
const xy220 = @as(u128, q2) * @as(u128, mu2);
const xy23 = @as(u128, q2) * @as(u128, mu3);
const xy24 = @as(u128, q2) * @as(u128, mu4);
const xy300 = @as(u128, q3) * @as(u128, mu0);
const xy310 = @as(u128, q3) * @as(u128, mu1);
const xy32 = @as(u128, q3) * @as(u128, mu2);
const xy33 = @as(u128, q3) * @as(u128, mu3);
const xy34 = @as(u128, q3) * @as(u128, mu4);
const xy400 = @as(u128, q4) * @as(u128, mu0);
const xy41 = @as(u128, q4) * @as(u128, mu1);
const xy42 = @as(u128, q4) * @as(u128, mu2);
const xy43 = @as(u128, q4) * @as(u128, mu3);
const xy44 = @as(u128, q4) * @as(u128, mu4);
const z01 = xy000;
const z11 = xy010 + xy100;
const z21 = xy020 + xy110 + xy200;
const z31 = xy030 + xy120 + xy210 + xy300;
const z41 = xy040 + xy130 + xy220 + xy310 + xy400;
const z5 = xy14 + xy23 + xy32 + xy41;
const z6 = xy24 + xy33 + xy42;
const z7 = xy34 + xy43;
const z8 = xy44;
const carry0 = z01 >> 56;
const c00 = carry0;
const carry1 = (z11 + c00) >> 56;
const c10 = carry1;
const carry2 = (z21 + c10) >> 56;
const c20 = carry2;
const carry3 = (z31 + c20) >> 56;
const c30 = carry3;
const carry4 = (z41 + c30) >> 56;
const t103 = @as(u64, @as(u64, @truncate(z41 + c30))) & 0xffffffffffffff;
const c40 = carry4;
const t410 = t103;
const carry5 = (z5 + c40) >> 56;
const t104 = @as(u64, @as(u64, @truncate(z5 + c40))) & 0xffffffffffffff;
const c5 = carry5;
const t51 = t104;
const carry6 = (z6 + c5) >> 56;
const t105 = @as(u64, @as(u64, @truncate(z6 + c5))) & 0xffffffffffffff;
const c6 = carry6;
const t61 = t105;
const carry7 = (z7 + c6) >> 56;
const t106 = @as(u64, @as(u64, @truncate(z7 + c6))) & 0xffffffffffffff;
const c7 = carry7;
const t71 = t106;
const carry8 = (z8 + c7) >> 56;
const t107 = @as(u64, @as(u64, @truncate(z8 + c7))) & 0xffffffffffffff;
const c8 = carry8;
const t81 = t107;
const t91 = @as(u64, @as(u64, @truncate(c8)));
const qmu4_ = t410;
const qmu5_ = t51;
const qmu6_ = t61;
const qmu7_ = t71;
const qmu8_ = t81;
const qmu9_ = t91;
const y_4 = (qmu5_ & 0xffffffffff) << 16;
const x_4 = qmu4_ >> 40;
const z02 = x_4 | y_4;
const y_5 = (qmu6_ & 0xffffffffff) << 16;
const x_5 = qmu5_ >> 40;
const z12 = x_5 | y_5;
const y_6 = (qmu7_ & 0xffffffffff) << 16;
const x_6 = qmu6_ >> 40;
const z22 = x_6 | y_6;
const y_7 = (qmu8_ & 0xffffffffff) << 16;
const x_7 = qmu7_ >> 40;
const z32 = x_7 | y_7;
const y_8 = (qmu9_ & 0xffffffffff) << 16;
const x_8 = qmu8_ >> 40;
const z42 = x_8 | y_8;
const qdiv0 = z02;
const qdiv1 = z12;
const qdiv2 = z22;
const qdiv3 = z32;
const qdiv4 = z42;
const r0 = t0;
const r1 = t1;
const r2 = t2;
const r3 = t3;
const r4 = t4 & 0xffffffffff;
const xy00 = @as(u128, qdiv0) * @as(u128, m0);
const xy01 = @as(u128, qdiv0) * @as(u128, m1);
const xy02 = @as(u128, qdiv0) * @as(u128, m2);
const xy03 = @as(u128, qdiv0) * @as(u128, m3);
const xy04 = @as(u128, qdiv0) * @as(u128, m4);
const xy10 = @as(u128, qdiv1) * @as(u128, m0);
const xy11 = @as(u128, qdiv1) * @as(u128, m1);
const xy12 = @as(u128, qdiv1) * @as(u128, m2);
const xy13 = @as(u128, qdiv1) * @as(u128, m3);
const xy20 = @as(u128, qdiv2) * @as(u128, m0);
const xy21 = @as(u128, qdiv2) * @as(u128, m1);
const xy22 = @as(u128, qdiv2) * @as(u128, m2);
const xy30 = @as(u128, qdiv3) * @as(u128, m0);
const xy31 = @as(u128, qdiv3) * @as(u128, m1);
const xy40 = @as(u128, qdiv4) * @as(u128, m0);
const carry9 = xy00 >> 56;
const t108 = @as(u64, @truncate(xy00)) & 0xffffffffffffff;
const c0 = carry9;
const t010 = t108;
const carry10 = (xy01 + xy10 + c0) >> 56;
const t109 = @as(u64, @truncate(xy01 + xy10 + c0)) & 0xffffffffffffff;
const c11 = carry10;
const t110 = t109;
const carry11 = (xy02 + xy11 + xy20 + c11) >> 56;
const t1010 = @as(u64, @truncate(xy02 + xy11 + xy20 + c11)) & 0xffffffffffffff;
const c21 = carry11;
const t210 = t1010;
const carry = (xy03 + xy12 + xy21 + xy30 + c21) >> 56;
const t1011 = @as(u64, @truncate(xy03 + xy12 + xy21 + xy30 + c21)) & 0xffffffffffffff;
const c31 = carry;
const t310 = t1011;
const t411 = @as(u64, @truncate(xy04 + xy13 + xy22 + xy31 + xy40 + c31)) & 0xffffffffff;
const qmul0 = t010;
const qmul1 = t110;
const qmul2 = t210;
const qmul3 = t310;
const qmul4 = t411;
const b5 = (r0 -% qmul0) >> 63;
const t1012 = ((b5 << 56) + r0) -% qmul0;
const c1 = b5;
const t011 = t1012;
const b6 = (r1 -% (qmul1 + c1)) >> 63;
const t1013 = ((b6 << 56) + r1) -% (qmul1 + c1);
const c2 = b6;
const t111 = t1013;
const b7 = (r2 -% (qmul2 + c2)) >> 63;
const t1014 = ((b7 << 56) + r2) -% (qmul2 + c2);
const c3 = b7;
const t211 = t1014;
const b8 = (r3 -% (qmul3 + c3)) >> 63;
const t1015 = ((b8 << 56) + r3) -% (qmul3 + c3);
const c4 = b8;
const t311 = t1015;
const b9 = (r4 -% (qmul4 + c4)) >> 63;
const t1016 = ((b9 << 40) + r4) -% (qmul4 + c4);
const t412 = t1016;
const s0 = t011;
const s1 = t111;
const s2 = t211;
const s3 = t311;
const s4 = t412;
const y0: u64 = 5175514460705773;
const y1: u64 = 70332060721272408;
const y2: u64 = 5342;
const y3: u64 = 0;
const y4: u64 = 268435456;
const b10 = (s0 -% y0) >> 63;
const t1017 = ((b10 << 56) + s0) -% y0;
const b0 = b10;
const t01 = t1017;
const b11 = (s1 -% (y1 + b0)) >> 63;
const t1018 = ((b11 << 56) + s1) -% (y1 + b0);
const b1 = b11;
const t11 = t1018;
const b12 = (s2 -% (y2 + b1)) >> 63;
const t1019 = ((b12 << 56) + s2) -% (y2 + b1);
const b2 = b12;
const t21 = t1019;
const b13 = (s3 -% (y3 + b2)) >> 63;
const t1020 = ((b13 << 56) + s3) -% (y3 + b2);
const b3 = b13;
const t31 = t1020;
const b = (s4 -% (y4 + b3)) >> 63;
const t10 = ((b << 56) + s4) -% (y4 + b3);
const b4 = b;
const t41 = t10;
const mask = b4 -% @as(u64, @as(u64, 1));
const z03 = s0 ^ (mask & (s0 ^ t01));
const z13 = s1 ^ (mask & (s1 ^ t11));
const z23 = s2 ^ (mask & (s2 ^ t21));
const z33 = s3 ^ (mask & (s3 ^ t31));
const z43 = s4 ^ (mask & (s4 ^ t41));
return Scalar{ .limbs = .{ z03, z13, z23, z33, z43 } };
}
}