private static void ge_p3_dbl(ref ge_p1p1 r, ge_p3 p) { ge_p2 q = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = 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); ge_p3_to_p2(ref q, p); ge_p2_dbl(ref result, q); 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_cached(ref ge_cached r, ge_p3 p) { ReadOnlySpan <int> d2 = stackalloc int[] { -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 }; ge_cached result = new() { YminusX = stackalloc int[10], YplusX = stackalloc int[10], T2d = stackalloc int[10], Z = stackalloc int[10], }; r.YminusX.CopyTo(result.YminusX); r.YplusX.CopyTo(result.YplusX); r.T2d.CopyTo(result.T2d); r.Z.CopyTo(result.Z); fe_add(ref result.YplusX, p.Y, p.X); fe_sub(ref result.YminusX, p.Y, p.X); fe_copy(ref result.Z, p.Z); fe_mul(ref result.T2d, p.T, d2); result.YminusX.CopyTo(r.YminusX); result.YplusX.CopyTo(r.YplusX); result.T2d.CopyTo(r.T2d); result.Z.CopyTo(r.Z); }
private static void ge_p1p1_to_p3(ref ge_p3 r, ge_p1p1 p) { ge_p3 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_mul(ref result.X, p.X, p.T); fe_mul(ref result.Y, p.Y, p.Z); fe_mul(ref result.Z, p.Z, p.T); fe_mul(ref result.T, p.X, p.Y); result.X.CopyTo(r.X); result.Y.CopyTo(r.Y); result.Z.CopyTo(r.Z); result.T.CopyTo(r.T); }
private static void ge_msub(ref ge_p1p1 r, ge_p3 p, ge_precomp q) { 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_add(ref result.X, p.Y, p.X); fe_sub(ref result.Y, p.Y, p.X); fe_mul(ref result.Z, result.X, q.yminusx); fe_mul(ref result.Y, result.Y, q.yplusx); fe_mul(ref result.T, q.xy2d, p.T); fe_add(ref t0, p.Z, p.Z); fe_sub(ref result.X, result.Z, result.Y); fe_add(ref result.Y, result.Z, result.Y); fe_sub(ref result.Z, t0, result.T); fe_add(ref result.T, t0, result.T); result.X.CopyTo(r.X); result.Y.CopyTo(r.Y); result.Z.CopyTo(r.Z); result.T.CopyTo(r.T); }
public string SecretKeyToPublicKey(string PrivateKey) { ge_p3 p = new ge_p3(); ge_scalarmult_base(p, HexStringToByteArray(PrivateKey)); byte[] b = new byte[32]; ge_p3_tobytes(ref b, p); return(ByteArrayToHexString(b)); }
public static PublicKey PrivateKeyToPublicKey(PrivateKey privateKey) { /* Computes aG where a is privateKey.data, and G is the ed25519 * base point, and pops the result in point */ ED25519.ge_p3 point = new ge_p3(); ge_scalarmult_base(point, privateKey.data); /* Stores the result of the derivation */ byte[] tmp = new byte[32]; /* Convert the point into a public key format */ ge_p3_tobytes(tmp, point); return(new PublicKey(tmp)); }
private static void ge_p3_tobytes(ref Span <byte> s, ge_p3 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]; 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_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); }
public string HashToEllipticCurve(string Hash) { if (!IsKey(Hash)) { return(null); } byte[] tmp = HexStringToByteArray(Hash); ge_p3 tmp3 = new ge_p3(); KeyOps.HashToEllipticCurve(tmp3, tmp); byte[] output = new byte[32]; ED25519.ge_p3_tobytes(ref output, tmp3); return(ByteArrayToHexString(output)); }
private static void ge_p3_0(ref ge_p3 h) { ge_p3 result = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], T = stackalloc int[10], }; fe_0(ref result.X); fe_1(ref result.Y); fe_1(ref result.Z); fe_0(ref result.T); result.X.CopyTo(h.X); result.Y.CopyTo(h.Y); result.Z.CopyTo(h.Z); result.T.CopyTo(h.T); }
public static bool IsValidKey(PublicKey key) { ED25519.ge_p3 point = new ge_p3(); return(ge_frombytes_vartime(point, key.data) == 0); }
private static void ge_scalarmult_base(ref ge_p3 h, ReadOnlySpan <byte> a) { sbyte carry; Span <sbyte> e = stackalloc sbyte[64]; ge_precomp t = new() { yminusx = stackalloc int[10], yplusx = stackalloc int[10], xy2d = stackalloc int[10], }; ge_p1p1 r = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], T = stackalloc int[10], }; ge_p2 s = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], }; ge_p3 result = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], T = stackalloc int[10], }; h.X.CopyTo(result.X); h.Y.CopyTo(result.Y); h.Z.CopyTo(result.Z); h.T.CopyTo(result.T); int i; for (i = 0; i < 32; ++i) { e[2 * i + 0] = (sbyte)((a[i] >> 0) & 15); e[2 * i + 1] = (sbyte)((a[i] >> 4) & 15); } /* each e[i] is between 0 and 15 */ /* e[63] is between 0 and 7 */ carry = 0; for (i = 0; i < 63; ++i) { e[i] += carry; carry = (sbyte)(e[i] + 8); carry >>= 4; e[i] -= (sbyte)(carry << 4); } e[63] += carry; /* each e[i] is between -8 and 8 */ ge_p3_0(ref result); for (i = 1; i < 64; i += 2) { select(ref t, i / 2, e[i]); ge_madd(ref r, result, t); ge_p1p1_to_p3(ref result, r); } ge_p3_dbl(ref r, result); ge_p1p1_to_p2(ref s, r); ge_p2_dbl(ref r, s); ge_p1p1_to_p2(ref s, r); ge_p2_dbl(ref r, s); ge_p1p1_to_p2(ref s, r); ge_p2_dbl(ref r, s); ge_p1p1_to_p3(ref result, r); for (i = 0; i < 64; i += 2) { select(ref t, i / 2, e[i]); ge_madd(ref r, result, t); ge_p1p1_to_p3(ref result, r); } result.X.CopyTo(h.X); result.Y.CopyTo(h.Y); result.Z.CopyTo(h.Z); result.T.CopyTo(h.T); }
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); }
private static int ge_frombytes_negate_vartime(ref ge_p3 h, ReadOnlySpan <byte> s) { ReadOnlySpan <int> d = stackalloc int[10] { -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116, }; ReadOnlySpan <int> sqrtm1 = stackalloc int[10] { -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482, }; Span <int> u = stackalloc int[10]; Span <int> v = stackalloc int[10]; Span <int> v3 = stackalloc int[10]; Span <int> vxx = stackalloc int[10]; Span <int> check = stackalloc int[10]; ge_p3 result = new() { X = stackalloc int[10], Y = stackalloc int[10], Z = stackalloc int[10], T = stackalloc int[10], }; h.X.CopyTo(result.X); h.Y.CopyTo(result.Y); h.Z.CopyTo(result.Z); h.T.CopyTo(result.T); fe_frombytes(ref result.Y, s); fe_1(ref result.Z); fe_sq(ref u, result.Y); fe_mul(ref v, u, d); fe_sub(ref u, u, result.Z); /* u = y^2-1 */ fe_add(ref v, v, result.Z); /* v = dy^2+1 */ fe_sq(ref v3, v); fe_mul(ref v3, v3, v); /* v3 = v^3 */ fe_sq(ref result.X, v3); fe_mul(ref result.X, result.X, v); fe_mul(ref result.X, result.X, u); /* x = uv^7 */ fe_pow22523(ref result.X, result.X); /* x = (uv^7)^((q-5)/8) */ fe_mul(ref result.X, result.X, v3); fe_mul(ref result.X, result.X, u); /* x = uv^3(uv^7)^((q-5)/8) */ fe_sq(ref vxx, result.X); fe_mul(ref vxx, vxx, v); fe_sub(ref check, vxx, u); /* vx^2-u */ if (fe_isnonzero(check)) { fe_add(ref check, vxx, u); /* vx^2+u */ if (fe_isnonzero(check)) { return(-1); } fe_mul(ref result.X, result.X, sqrtm1); } if (fe_isnegative(result.X) == (s[31] >> 7)) { fe_neg(ref result.X, result.X); } fe_mul(ref result.T, result.X, result.Y); result.X.CopyTo(h.X); result.Y.CopyTo(h.Y); result.Z.CopyTo(h.Z); result.T.CopyTo(h.T); return(0); }