private static void ge_p2_dbl(ref ge_p1p1 r, ge_p2 p) { Span <int> t0 = stackalloc int[10]; ge_p1p1 result = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], T = stackalloc int[10], }; r.X.CopyTo(result.X); r.Y.CopyTo(result.Y); r.Z.CopyTo(result.Z); r.T.CopyTo(result.T); fe_sq(ref result.X, p.X); fe_sq(ref result.Z, p.Y); fe_sq2(ref result.T, p.Z); fe_add(ref result.Y, p.X, p.Y); fe_sq(ref t0, result.Y); fe_add(ref result.Y, result.Z, result.X); fe_sub(ref result.Z, result.Z, result.X); fe_sub(ref result.X, t0, result.Y); fe_sub(ref result.T, result.T, result.Z); result.X.CopyTo(r.X); result.Y.CopyTo(r.Y); result.Z.CopyTo(r.Z); result.T.CopyTo(r.T); }
private static void ge_p3_to_p2(ref ge_p2 r, ge_p3 p) { ge_p2 result = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], }; fe_copy(ref result.X, p.X); fe_copy(ref result.Y, p.Y); fe_copy(ref result.Z, p.Z); result.X.CopyTo(r.X); result.Y.CopyTo(r.Y); result.Z.CopyTo(r.Z); }
private static void ge_p2_0(ref ge_p2 h) { ge_p2 result = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], }; fe_0(ref result.X); fe_1(ref result.Y); fe_1(ref result.Z); result.X.CopyTo(h.X); result.Y.CopyTo(h.Y); result.Z.CopyTo(h.Z); }
private static void ge_tobytes(ref Span <byte> s, ge_p2 h) { Span <int> x = stackalloc int[10]; Span <int> y = stackalloc int[10]; Span <int> recip = stackalloc int[10]; Span <byte> result = stackalloc byte[32]; s.CopyTo(result); fe_invert(ref recip, h.Z); fe_mul(ref x, h.X, recip); fe_mul(ref y, h.Y, recip); fe_tobytes(ref result, y); result[31] ^= (byte)(fe_isnegative(x) << 7); result.CopyTo(s); }
private static void ge_double_scalarmult_vartime(ref ge_p2 r, ReadOnlySpan <byte> a, ge_p3 A, ReadOnlySpan <byte> b) { Span <sbyte> aslide = stackalloc sbyte[256]; Span <sbyte> bslide = stackalloc sbyte[256]; ge_p2 result = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], }; r.X.CopyTo(result.X); r.Y.CopyTo(result.Y); r.Z.CopyTo(result.Z); /* A,3A,5A,7A,9A,11A,13A,15A */ ge_cached Ai0 = new() { YplusX = stackalloc int[10], T2d = stackalloc int[10], YminusX = stackalloc int[10], Z = stackalloc int[10], }; ge_cached Ai1 = new() { YplusX = stackalloc int[10], T2d = stackalloc int[10], YminusX = stackalloc int[10], Z = stackalloc int[10], }; ge_cached Ai2 = new() { YplusX = stackalloc int[10], T2d = stackalloc int[10], YminusX = stackalloc int[10], Z = stackalloc int[10], }; ge_cached Ai3 = new() { YplusX = stackalloc int[10], T2d = stackalloc int[10], YminusX = stackalloc int[10], Z = stackalloc int[10], }; ge_cached Ai4 = new() { YplusX = stackalloc int[10], T2d = stackalloc int[10], YminusX = stackalloc int[10], Z = stackalloc int[10], }; ge_cached Ai5 = new() { YplusX = stackalloc int[10], T2d = stackalloc int[10], YminusX = stackalloc int[10], Z = stackalloc int[10], }; ge_cached Ai6 = new() { YplusX = stackalloc int[10], T2d = stackalloc int[10], YminusX = stackalloc int[10], Z = stackalloc int[10], }; ge_cached Ai7 = new() { YplusX = stackalloc int[10], T2d = stackalloc int[10], YminusX = stackalloc int[10], Z = stackalloc int[10], }; ge_p1p1 t = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], T = stackalloc int[10], }; ge_p3 u = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], T = stackalloc int[10], }; ge_p3 A2 = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], T = stackalloc int[10], }; int i; slide(ref aslide, a); slide(ref bslide, b); ge_p3_to_cached(ref Ai0, A); ge_p3_dbl(ref t, A); ge_p1p1_to_p3(ref A2, t); ge_add(ref t, A2, Ai0); ge_p1p1_to_p3(ref u, t); ge_p3_to_cached(ref Ai1, u); ge_add(ref t, A2, Ai1); ge_p1p1_to_p3(ref u, t); ge_p3_to_cached(ref Ai2, u); ge_add(ref t, A2, Ai2); ge_p1p1_to_p3(ref u, t); ge_p3_to_cached(ref Ai3, u); ge_add(ref t, A2, Ai3); ge_p1p1_to_p3(ref u, t); ge_p3_to_cached(ref Ai4, u); ge_add(ref t, A2, Ai4); ge_p1p1_to_p3(ref u, t); ge_p3_to_cached(ref Ai5, u); ge_add(ref t, A2, Ai5); ge_p1p1_to_p3(ref u, t); ge_p3_to_cached(ref Ai6, u); ge_add(ref t, A2, Ai6); ge_p1p1_to_p3(ref u, t); ge_p3_to_cached(ref Ai7, u); ge_p2_0(ref result); ge_precomp bi = new() { yminusx = stackalloc int[10], yplusx = stackalloc int[10], xy2d = stackalloc int[10], }; for (i = 255; i >= 0; --i) { if (aslide[i] != 0 || bslide[i] != 0) { break; } } for (; i >= 0; --i) { ge_p2_dbl(ref t, result); switch (aslide[i]) { case > 0: { ge_p1p1_to_p3(ref u, t); switch (aslide[i] / 2) { case 0: ge_add(ref t, u, Ai0); break; case 1: ge_add(ref t, u, Ai1); break; case 2: ge_add(ref t, u, Ai2); break; case 3: ge_add(ref t, u, Ai3); break; case 4: ge_add(ref t, u, Ai4); break; case 5: ge_add(ref t, u, Ai5); break; case 6: ge_add(ref t, u, Ai6); break; case 7: ge_add(ref t, u, Ai7); break; } break; } case < 0: { ge_p1p1_to_p3(ref u, t); switch (-aslide[i] / 2) { case 0: ge_sub(ref t, u, Ai0); break; case 1: ge_sub(ref t, u, Ai1); break; case 2: ge_sub(ref t, u, Ai2); break; case 3: ge_sub(ref t, u, Ai3); break; case 4: ge_sub(ref t, u, Ai4); break; case 5: ge_sub(ref t, u, Ai5); break; case 6: ge_sub(ref t, u, Ai6); break; case 7: ge_sub(ref t, u, Ai7); break; } break; } } switch (bslide[i]) { case > 0: { GetPrecompBi(bslide[i] / 2, ref bi); ge_p1p1_to_p3(ref u, t); ge_madd(ref t, u, bi); break; } case < 0: { GetPrecompBi(-bslide[i] / 2, ref bi); ge_p1p1_to_p3(ref u, t); ge_msub(ref t, u, bi); break; } } ge_p1p1_to_p2(ref result, t); } result.X.CopyTo(r.X); result.Y.CopyTo(r.Y); result.Z.CopyTo(r.Z); }