public static int CryptoScalarmult(byte[] Q, byte[] N, byte[] P) { int[] work = new int[96]; byte[] e = new byte[32]; for (int i = 0; i < 32; ++i) { e[i] = N[i]; } e[0] &= 248; e[31] &= 127; e[31] |= 64; for (int i = 0; i < 32; ++i) { work[i] = P[i] & 0xFF; } Curve25519.Mainloop(work, e); Curve25519.Recip(work, 32, work, 32); Curve25519.Mult(work, 64, work, 0, work, 32); Curve25519.Freeze(work, 64); for (int i = 0; i < 32; ++i) { Q[i] = (byte)work[64 + i]; } return(0); }
public static void Mainloop(int[] Work, byte[] E) { int[] xzm1 = new int[64]; int[] xzm = new int[64]; int[] xzmb = new int[64]; int[] Xzm1B = new int[64]; int[] xznb = new int[64]; int[] Xzn1B = new int[64]; int[] a0 = new int[64]; int[] a1 = new int[64]; int[] b0 = new int[64]; int[] b1 = new int[64]; int[] c1 = new int[64]; int[] r = new int[32]; int[] s = new int[32]; int[] t = new int[32]; int[] u = new int[32]; for (int j = 0; j < 32; ++j) { xzm1[j] = Work[j]; } xzm1[32] = 1; for (int j = 33; j < 64; ++j) { xzm1[j] = 0; } xzm[0] = 1; for (int j = 1; j < 64; ++j) { xzm[j] = 0; } int[] xzmbp = xzmb, A0P = a0, Xzm1Bp = Xzm1B; int[] A1P = a1, B0P = b0, B1P = b1, C1P = c1; int[] xznbp = xznb, up = u, Xzn1Bp = Xzn1B; int[] workp = Work, sp = s, rp = r; for (int pos = 254; pos >= 0; --pos) { int b = (int)((uint)(E[pos / 8] & 0xFF) >> (pos & 7)); b &= 1; Curve25519.Select(xzmb, Xzm1B, xzm, xzm1, b); Curve25519.Add(a0, 0, xzmb, 0, xzmbp, 32); Curve25519.Sub(A0P, 32, xzmb, 0, xzmbp, 32); Curve25519.Add(a1, 0, Xzm1B, 0, Xzm1Bp, 32); Curve25519.Sub(A1P, 32, Xzm1B, 0, Xzm1Bp, 32); Curve25519.Square(B0P, 0, A0P, 0); Curve25519.Square(B0P, 32, A0P, 32); Curve25519.Mult(B1P, 0, A1P, 0, A0P, 32); Curve25519.Mult(B1P, 32, A1P, 32, A0P, 0); Curve25519.Add(c1, 0, b1, 0, B1P, 32); Curve25519.Sub(C1P, 32, b1, 0, B1P, 32); Curve25519.Square(rp, 0, C1P, 32); Curve25519.Sub(sp, 0, b0, 0, B0P, 32); Curve25519.Mult121665(t, s); Curve25519.Add(u, 0, t, 0, B0P, 0); Curve25519.Mult(xznbp, 0, B0P, 0, B0P, 32); Curve25519.Mult(xznbp, 32, sp, 0, up, 0); Curve25519.Square(Xzn1Bp, 0, C1P, 0); Curve25519.Mult(Xzn1Bp, 32, rp, 0, workp, 0); Curve25519.Select(xzm, xzm1, xznb, Xzn1B, b); } for (int j = 0; j < 64; ++j) { Work[j] = xzm[j]; } }
public static void Recip(int[] Outv, int Outvoffset, int[] Z, int Zoffset) { int[] z2 = new int[32]; int[] z9 = new int[32]; int[] z11 = new int[32]; int[] z2_5_0 = new int[32]; int[] z2_10_0 = new int[32]; int[] z2_20_0 = new int[32]; int[] z2_50_0 = new int[32]; int[] z2_100_0 = new int[32]; int[] t0 = new int[32]; int[] t1 = new int[32]; /* 2 */ int[] Z2P = z2; Curve25519.Square(Z2P, 0, Z, Zoffset); /* 4 */ Curve25519.Square(t1, 0, z2, 0); /* 8 */ Curve25519.Square(t0, 0, t1, 0); /* 9 */ int[] Z9P = z9, T0P = t0; Curve25519.Mult(Z9P, 0, T0P, 0, Z, Zoffset); /* 11 */ Curve25519.Mult(z11, 0, z9, 0, z2, 0); /* 22 */ Curve25519.Square(t0, 0, z11, 0); /* 2^5 - 2^0 = 31 */ Curve25519.Mult(z2_5_0, 0, t0, 0, z9, 0); /* 2^6 - 2^1 */ Curve25519.Square(t0, 0, z2_5_0, 0); /* 2^7 - 2^2 */ Curve25519.Square(t1, 0, t0, 0); /* 2^8 - 2^3 */ Curve25519.Square(t0, 0, t1, 0); /* 2^9 - 2^4 */ Curve25519.Square(t1, 0, t0, 0); /* 2^10 - 2^5 */ Curve25519.Square(t0, 0, t1, 0); /* 2^10 - 2^0 */ Curve25519.Mult(z2_10_0, 0, t0, 0, z2_5_0, 0); /* 2^11 - 2^1 */ Curve25519.Square(t0, 0, z2_10_0, 0); /* 2^12 - 2^2 */ Curve25519.Square(t1, 0, t0, 0); /* 2^20 - 2^10 */ for (int i = 2; i < 10; i += 2) { Curve25519.Square(t0, 0, t1, 0); Curve25519.Square(t1, 0, t0, 0); } /* 2^20 - 2^0 */ Curve25519.Mult(z2_20_0, 0, t1, 0, z2_10_0, 0); /* 2^21 - 2^1 */ Curve25519.Square(t0, 0, z2_20_0, 0); /* 2^22 - 2^2 */ Curve25519.Square(t1, 0, t0, 0); /* 2^40 - 2^20 */ for (int i = 2; i < 20; i += 2) { Curve25519.Square(t0, 0, t1, 0); Curve25519.Square(t1, 0, t0, 0); } /* 2^40 - 2^0 */ Curve25519.Mult(t0, 0, t1, 0, z2_20_0, 0); /* 2^41 - 2^1 */ Curve25519.Square(t1, 0, t0, 0); /* 2^42 - 2^2 */ Curve25519.Square(t0, 0, t1, 0); /* 2^50 - 2^10 */ for (int i = 2; i < 10; i += 2) { Curve25519.Square(t1, 0, t0, 0); Curve25519.Square(t0, 0, t1, 0); } /* 2^50 - 2^0 */ Curve25519.Mult(z2_50_0, 0, t0, 0, z2_10_0, 0); /* 2^51 - 2^1 */ Curve25519.Square(t0, 0, z2_50_0, 0); /* 2^52 - 2^2 */ Curve25519.Square(t1, 0, t0, 0); /* 2^100 - 2^50 */ for (int i = 2; i < 50; i += 2) { Curve25519.Square(t0, 0, t1, 0); Curve25519.Square(t1, 0, t0, 0); } /* 2^100 - 2^0 */ Curve25519.Mult(z2_100_0, 0, t1, 0, z2_50_0, 0); /* 2^101 - 2^1 */ Curve25519.Square(t1, 0, z2_100_0, 0); /* 2^102 - 2^2 */ Curve25519.Square(t0, 0, t1, 0); /* 2^200 - 2^100 */ for (int i = 2; i < 100; i += 2) { Curve25519.Square(t1, 0, t0, 0); Curve25519.Square(t0, 0, t1, 0); } /* 2^200 - 2^0 */ Curve25519.Mult(t1, 0, t0, 0, z2_100_0, 0); /* 2^201 - 2^1 */ Curve25519.Square(t0, 0, t1, 0); /* 2^202 - 2^2 */ Curve25519.Square(t1, 0, t0, 0); /* 2^250 - 2^50 */ for (int i = 2; i < 50; i += 2) { Curve25519.Square(t0, 0, t1, 0); Curve25519.Square(t1, 0, t0, 0); } /* 2^250 - 2^0 */ Curve25519.Mult(t0, 0, t1, 0, z2_50_0, 0); /* 2^251 - 2^1 */ Curve25519.Square(t1, 0, t0, 0); /* 2^252 - 2^2 */ Curve25519.Square(t0, 0, t1, 0); /* 2^253 - 2^3 */ Curve25519.Square(t1, 0, t0, 0); /* 2^254 - 2^4 */ Curve25519.Square(t0, 0, t1, 0); /* 2^255 - 2^5 */ Curve25519.Square(t1, 0, t0, 0); /* 2^255 - 21 */ int[] T1P = t1, Z11P = z11; Curve25519.Mult(Outv, Outvoffset, T1P, 0, Z11P, 0); }