public static void InvAllVar(Fe[] r, Fe[] a, int len) { if (len < 1) { return; } for (int index = 0; index < len; ++index) { r[index] = a[index].Clone(); } int index1 = 0; while (++index1 < len) { Field.Mul(r[index1], r[index1 - 1], a[index1]); } Fe fe = new Fe(); int index2; Field.InvVar(fe, r[index2 = index1 - 1]); while (index2 > 0) { int index3 = index2--; Field.Mul(r[index3], r[index2], fe); Field.Mul(fe, fe, a[index3]); } r[0] = fe.Clone(); }
/** Compare two field elements. Requires both inputs to be normalized */ //static int secp256k1_fe_cmp_var(const secp256k1_fe* a, const secp256k1_fe* b); /** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ //static int SetB32(secp256k1_fe* r, const unsigned char* a); /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ //static void GetB32(unsigned char* r, const secp256k1_fe* a); /** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input * as an argument. The magnitude of the output is one higher. */ //static void Negate(secp256k1_fe* r, const secp256k1_fe* a, int m); /** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that * small integer. */ //static void MulInt(secp256k1_fe* r, int a); /** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ //static void Add(secp256k1_fe* r, const secp256k1_fe* a); /** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. * The output magnitude is 1 (but not guaranteed to be normalized). */ //static void Mul(secp256k1_fe* r, const secp256k1_fe* a, const secp256k1_fe* SECP256K1_RESTRICT b); /** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. * The output magnitude is 1 (but not guaranteed to be normalized). */ //static void Sqr(secp256k1_fe* r, const secp256k1_fe* a); /// <summary> /// If a has a square root, it is computed in r and 1 is returned. If a does not have a square root, the root of its negation is computed and 0 is returned. The input's magnitude can be at most 8. The output magnitude is 1 (but not guaranteed to be normalized). The result in r will always be a square itself. /// </summary> /// <param name="r"></param> /// <param name="a"></param> /// <returns></returns> public static bool Sqrt(Fe r, Fe a) { /** Given that p is congruent to 3 mod 4, we can compute the square root of * a mod p as the (p+1)/4'th power of a. * * As (p+1)/4 is an even number, it will have the same result for a and for * (-a). Only one of these two numbers actually has a square root however, * so we test at the end by squaring and comparing to the input. * Also because (p+1)/4 is an even number, the computed square root is * itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)). */ Fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; int j; /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: * 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] */ x2 = new Fe(); Sqr(x2, a); Mul(x2, x2, a); x3 = new Fe(); Sqr(x3, x2); Mul(x3, x3, a); x6 = x3.Clone(); for (j = 0; j < 3; j++) { Sqr(x6, x6); } Mul(x6, x6, x3); x9 = x6.Clone(); for (j = 0; j < 3; j++) { Sqr(x9, x9); } Mul(x9, x9, x3); x11 = x9.Clone(); for (j = 0; j < 2; j++) { Sqr(x11, x11); } Mul(x11, x11, x2); x22 = x11.Clone(); for (j = 0; j < 11; j++) { Sqr(x22, x22); } Mul(x22, x22, x11); x44 = x22.Clone(); for (j = 0; j < 22; j++) { Sqr(x44, x44); } Mul(x44, x44, x22); x88 = x44.Clone(); for (j = 0; j < 44; j++) { Sqr(x88, x88); } Mul(x88, x88, x44); x176 = x88.Clone(); for (j = 0; j < 88; j++) { Sqr(x176, x176); } Mul(x176, x176, x88); x220 = x176.Clone(); for (j = 0; j < 44; j++) { Sqr(x220, x220); } Mul(x220, x220, x44); x223 = x220.Clone(); for (j = 0; j < 3; j++) { Sqr(x223, x223); } Mul(x223, x223, x3); /* The final result is then assembled using a sliding window over the blocks. */ t1 = x223.Clone(); for (j = 0; j < 23; j++) { Sqr(t1, t1); } Mul(t1, t1, x22); for (j = 0; j < 6; j++) { Sqr(t1, t1); } Mul(t1, t1, x2); Sqr(t1, t1); Sqr(r, t1); /* Check that a square root was actually calculated */ Sqr(t1, r); return(Equal(t1, a)); }
/** Checks whether a field element is a quadratic residue. */ // static int secp256k1_fe_is_quad_var(const secp256k1_fe* a) // { //# ifndef USE_NUM_NONE // unsigned char b[32]; // secp256k1_num n; // secp256k1_num m; // /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ // static const unsigned char prime[32] = { // 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F // }; // secp256k1_fe c = *a; // NormalizeVar(c); // GetB32(b, c); // secp256k1_num_set_bin(n, b, 32); // secp256k1_num_set_bin(m, prime, 32); // return secp256k1_num_jacobi(n, m) >= 0; //#else // secp256k1_fe r; // return Sqrt(r, a); //#endif //} /// <summary> /// Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be normalized). /// </summary> /// <param name="r"></param> /// <param name="a"></param> /// <returns></returns> public static void Inv(Fe r, Fe a) { Fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; int j; /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in * { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: * [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] */ x2 = new Fe(); Sqr(x2, a); Mul(x2, x2, a); x3 = new Fe(); Sqr(x3, x2); Mul(x3, x3, a); x6 = x3.Clone(); for (j = 0; j < 3; j++) { Sqr(x6, x6); } Mul(x6, x6, x3); x9 = x6.Clone(); for (j = 0; j < 3; j++) { Sqr(x9, x9); } Mul(x9, x9, x3); x11 = x9.Clone(); for (j = 0; j < 2; j++) { Sqr(x11, x11); } Mul(x11, x11, x2); x22 = x11.Clone(); for (j = 0; j < 11; j++) { Sqr(x22, x22); } Mul(x22, x22, x11); x44 = x22.Clone(); for (j = 0; j < 22; j++) { Sqr(x44, x44); } Mul(x44, x44, x22); x88 = x44.Clone(); for (j = 0; j < 44; j++) { Sqr(x88, x88); } Mul(x88, x88, x44); x176 = x88.Clone(); for (j = 0; j < 88; j++) { Sqr(x176, x176); } Mul(x176, x176, x88); x220 = x176.Clone(); for (j = 0; j < 44; j++) { Sqr(x220, x220); } Mul(x220, x220, x44); x223 = x220.Clone(); for (j = 0; j < 3; j++) { Sqr(x223, x223); } Mul(x223, x223, x3); /* The final result is then assembled using a sliding window over the blocks. */ t1 = x223.Clone(); for (j = 0; j < 23; j++) { Sqr(t1, t1); } Mul(t1, t1, x22); for (j = 0; j < 5; j++) { Sqr(t1, t1); } Mul(t1, t1, a); for (j = 0; j < 3; j++) { Sqr(t1, t1); } Mul(t1, t1, x2); for (j = 0; j < 2; j++) { Sqr(t1, t1); } Mul(r, a, t1); }
public static bool Sqrt(Fe r, Fe a) { Fe fe1 = new Fe(); Field.Sqr(fe1, a); Field.Mul(fe1, fe1, a); Fe fe2 = new Fe(); Field.Sqr(fe2, fe1); Field.Mul(fe2, fe2, a); Fe fe3 = fe2.Clone(); for (int index = 0; index < 3; ++index) { Field.Sqr(fe3, fe3); } Field.Mul(fe3, fe3, fe2); Fe fe4 = fe3.Clone(); for (int index = 0; index < 3; ++index) { Field.Sqr(fe4, fe4); } Field.Mul(fe4, fe4, fe2); Fe fe5 = fe4.Clone(); for (int index = 0; index < 2; ++index) { Field.Sqr(fe5, fe5); } Field.Mul(fe5, fe5, fe1); Fe fe6 = fe5.Clone(); for (int index = 0; index < 11; ++index) { Field.Sqr(fe6, fe6); } Field.Mul(fe6, fe6, fe5); Fe fe7 = fe6.Clone(); for (int index = 0; index < 22; ++index) { Field.Sqr(fe7, fe7); } Field.Mul(fe7, fe7, fe6); Fe fe8 = fe7.Clone(); for (int index = 0; index < 44; ++index) { Field.Sqr(fe8, fe8); } Field.Mul(fe8, fe8, fe7); Fe fe9 = fe8.Clone(); for (int index = 0; index < 88; ++index) { Field.Sqr(fe9, fe9); } Field.Mul(fe9, fe9, fe8); Fe fe10 = fe9.Clone(); for (int index = 0; index < 44; ++index) { Field.Sqr(fe10, fe10); } Field.Mul(fe10, fe10, fe7); Fe fe11 = fe10.Clone(); for (int index = 0; index < 3; ++index) { Field.Sqr(fe11, fe11); } Field.Mul(fe11, fe11, fe2); Fe fe12 = fe11.Clone(); for (int index = 0; index < 23; ++index) { Field.Sqr(fe12, fe12); } Field.Mul(fe12, fe12, fe6); for (int index = 0; index < 6; ++index) { Field.Sqr(fe12, fe12); } Field.Mul(fe12, fe12, fe1); Field.Sqr(fe12, fe12); Field.Sqr(r, fe12); Field.Sqr(fe12, r); return(Field.Equal(fe12, a)); }
public GeJ Clone() { return(new GeJ(X?.Clone(), Y?.Clone(), Z?.Clone())); }
public static void Inv(Fe r, Fe a) { var fe1 = new Fe(); Field.Sqr(fe1, a); Field.Mul(fe1, fe1, a); var fe2 = new Fe(); Field.Sqr(fe2, fe1); Field.Mul(fe2, fe2, a); var fe3 = fe2.Clone(); for (var index = 0; index < 3; ++index) { Field.Sqr(fe3, fe3); } Field.Mul(fe3, fe3, fe2); var fe4 = fe3.Clone(); for (var index = 0; index < 3; ++index) { Field.Sqr(fe4, fe4); } Field.Mul(fe4, fe4, fe2); var fe5 = fe4.Clone(); for (var index = 0; index < 2; ++index) { Field.Sqr(fe5, fe5); } Field.Mul(fe5, fe5, fe1); var fe6 = fe5.Clone(); for (var index = 0; index < 11; ++index) { Field.Sqr(fe6, fe6); } Field.Mul(fe6, fe6, fe5); var fe7 = fe6.Clone(); for (var index = 0; index < 22; ++index) { Field.Sqr(fe7, fe7); } Field.Mul(fe7, fe7, fe6); var fe8 = fe7.Clone(); for (var index = 0; index < 44; ++index) { Field.Sqr(fe8, fe8); } Field.Mul(fe8, fe8, fe7); var fe9 = fe8.Clone(); for (var index = 0; index < 88; ++index) { Field.Sqr(fe9, fe9); } Field.Mul(fe9, fe9, fe8); var fe10 = fe9.Clone(); for (var index = 0; index < 44; ++index) { Field.Sqr(fe10, fe10); } Field.Mul(fe10, fe10, fe7); var fe11 = fe10.Clone(); for (var index = 0; index < 3; ++index) { Field.Sqr(fe11, fe11); } Field.Mul(fe11, fe11, fe2); var fe12 = fe11.Clone(); for (var index = 0; index < 23; ++index) { Field.Sqr(fe12, fe12); } Field.Mul(fe12, fe12, fe6); for (var index = 0; index < 5; ++index) { Field.Sqr(fe12, fe12); } Field.Mul(fe12, fe12, a); for (var index = 0; index < 3; ++index) { Field.Sqr(fe12, fe12); } Field.Mul(fe12, fe12, fe1); for (var index = 0; index < 2; ++index) { Field.Sqr(fe12, fe12); } Field.Mul(r, a, fe12); }