public static VLong Parse(string data, bool isHex) { //int segSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(uint)) * 2; System.Globalization.NumberStyles style = isHex ? System.Globalization.NumberStyles.AllowHexSpecifier : System.Globalization.NumberStyles.None; int pos = 0; VLong ret = new VLong(); while (pos < data.Length) { ret *= 0x100; uint piece = uint.Parse( data.Substring(pos, 2), style); ret.Add(piece); pos += 2; } return(ret); }
public int Product(VLong other) { VLong right = new VLong(other); int max = Math.Min(UnitsUsed, right.UnitsUsed); uint tmp = 0; for (int i = 0; i < max; i += 1) { tmp ^= this.data.Get(i) & right.data.Get(i); } uint count = 0; while (tmp > 0) { if ((tmp & 1) != 0) { count++; } tmp >>= 1; } return((int)(count & 1)); }
public void Divide(VLong left, VLong right, VLong remainder) { Init(0); remainder.Copy(left); VLong m = new VLong(); VLong s = new VLong(); m.Copy(right); s.Init(1); while (remainder.Compare(m) > 0) { m.Shl(); s.Shl(); } while (remainder.Compare(right) >= 0) { while (remainder.Compare(m) < 0) { m.Shr(); s.Shr(); } remainder.Subtract(m); Add(s); } }
public static VLong ModInv(VLong a, VLong m) { VLong j = new VLong(1u); VLong i = new VLong(0); VLong b = new VLong(m); VLong c = new VLong(a); VLong x = new VLong(); VLong y = new VLong(); while (!c.IsZero) { x = b / c; y = b - (x * c); b = c; c = y; y = j; j = i - (j * x); i = y; } if (i < 0) { i += m; } return(i); }
public VLong MontyExp(VLong x, VLong e) { VLong result = R - this.m; VLong t = new VLong(x); this.t = new VLong(); this.k = new VLong(); int bits = e.GetBits(); int i = 0; while (true) { if (e.GetBit(i)) { Mul(ref result, t); } i++; if (i == bits) { break; } Mul(ref t, t); } return(result); }
public static VLong operator *(VLong left, VLong right) { VLong result = new VLong(); result.Mul(left, right); result.negative = left.negative ^ right.negative; return(result); }
public static VLong operator >>(VLong left, int factor) { VLong result = new VLong(); result.Copy(left); result.Shr(factor); return(result); }
public static VLong operator &(VLong left, VLong right) { VLong result = new VLong(); result.Copy(left); result.And(right); return(result); }
public static VLong operator /(VLong left, VLong right) { VLong result = new VLong(); VLong remainder = new VLong(); result.Divide(left, right, remainder); result.negative = left.negative ^ right.negative; return(result); }
public void And(VLong other) { VLong right = new VLong(other); int max = Math.Max(UnitsUsed, right.UnitsUsed); this.data.Reserve(max); for (int i = 0; i < max; i += 1) { this.data.Set(i, this.data.Get(i) & right.data.Get(i)); } }
public static VLong Unpack(uint[] values) { VLong tmp = new VLong(); uint len = values[0]; uint[] values2 = new uint[values.Length - 1]; Array.Copy(values, 1, values2, 0, len); tmp.Load(values2); return(tmp); }
public static VLong operator <<(VLong left, int factor) { VLong result = new VLong(); result.Copy(left); while (factor > 0) { factor--; result += result; } return(result); }
private void Mul(ref VLong x, VLong y) { this.t.data.FastMul(x.data, y.data, this.rBits * 2); this.k.data.FastMul(this.t.data, this.n1.data, this.rBits); x.data.FastMul(this.k.data, this.m.data, this.rBits * 2); x += this.t; x.Shr(this.rBits); if (x >= this.m) { x -= this.m; } }
public Monty(VLong mod) { this.m = mod; this.rBits = 0; R = new VLong(1u); while (R < this.m) { R += R; //R.Add(R); this.rBits++; } R1 = ModInv(R - m, m); n1 = R - ModInv(this.m, R); }
public void Subtract(VLong other) { VLong right = new VLong(other); uint carry = 0; int N = UnitsUsed; for (int i = 0; i < N; i += 1) { uint ux = right.data.Get(i); ux += carry; if (ux >= carry) { uint u = this.data.Get(i); uint nu = u - ux; carry = (nu > u) ? 1u : 0; this.data.Set(i, nu); } } }
public static VLong Subtract(VLong left, VLong right) { VLong result = new VLong(); uint carry = 0; int used = left.UnitsUsed; for (int i = 0; i < used; i += 1) { uint ux = right.data.Get(i); ux += carry; if (ux >= carry) { uint u = left.data.Get(i); uint nu = u - ux; carry = (nu > u) ? 1u : 0; result.data.Set(i, nu); } } return(result); }
public void Add(VLong other) { VLong right = new VLong(other); uint carry = 0; int max = Math.Max(UnitsUsed, right.UnitsUsed); this.data.Reserve(max); for (int i = 0; i < max + 1; i += 1) { uint u = this.data.Get(i); u += carry; carry = (u < carry) ? 1u : 0; uint ux = right.data.Get(i); u += ux; carry += (u < ux) ? 1u : 0; this.data.Set(i, u); } }
// cf public int Compare(VLong other) { bool neg = this.negative != 0 && !IsZero; if (!object.Equals(other, null) && neg == (other.negative != 0 && !other.IsZero)) { if (UnitsUsed > other.UnitsUsed) { return(1); } if (UnitsUsed < other.UnitsUsed) { return(-1); } int i = UnitsUsed; while (i > 0) { i--; if (this.data.Get(i) > other.data.Get(i)) { return(1); } if (this.data.Get(i) < other.data.Get(i)) { return(-1); } } return(0); } else if (neg) { return(-1); } else { return(1); } }
public static int Product(VLong left, VLong right) { int max = Math.Min(left.UnitsUsed, right.UnitsUsed); uint tmp = 0; for (int i = 0; i < max; i += 1) { tmp ^= left.data.Get(i) & right.data.Get(i); } uint count = 0; while (tmp > 0) { if ((tmp & 1) != 0) { count++; } tmp >>= 1; } return((int)(count & 1)); }
public static VLong Add(VLong left, VLong right) { VLong result = new VLong(); uint carry = 0; int max = Math.Max(left.UnitsUsed, right.UnitsUsed); result.data.Reserve(max); for (int i = 0; i < max + 1; i += 1) { uint u = left.data.Get(i); u += carry; carry = (u < carry) ? 1u : 0; uint ux = right.data.Get(i); u += ux; carry += (u < ux) ? 1u : 0; result.data.Set(i, u); } return(result); }
public static VLong operator -(VLong left, VLong right) { VLong result = null; if (left.negative != right.negative) { result = new VLong(left); result.Add(right); } else if (left.Compare(right) >= 0) { result = new VLong(left); result.Subtract(right); } else { result = new VLong(right); result.Subtract(left); result.negative = 1 - result.negative; } return(result); }
public void Init(VLong sharedBase, VLong sharedPrime) { this.b = sharedBase; this.p = sharedPrime; }
public static VLong ModExp(VLong x, VLong e, VLong m) { Monty me = new Monty(m); return(me.Exp(x, e)); }
public VLong Exp(VLong x, VLong e) { return((MontyExp((x * R) % this.m, e) * R1) % this.m); }
public VLong GenerateSession(VLong exchangePublicKey, VLong privateKey) { return(VLong.ModExp(exchangePublicKey, privateKey, this.p)); }
public VLong GenerateSession(VLong exchangePublicKey) { return(GenerateSession(exchangePublicKey, this.privateKey)); }
public VLong GeneratePublic(VLong privateKey) { return(VLong.ModExp(this.b, privateKey, this.p)); }
private void GenerateServerPrivateKey() { this.privateKey = new VLong(11); }
private void GenerateClientPrivateKey() { this.privateKey = new VLong(10); }
public void Init() { Init( VLong.Parse(KeyBase, true), VLong.Parse(KeyPrime, true)); }