1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| class Pare { long x; long y;
public Pare() { super(); }
public Pare(long x, long y) { super();
this.x = x; this.y = y; }
public Pare add(Pare pare) { if (this.x == Integer.MAX_VALUE) { return pare; } Pare res = new Pare(); if (this.y == pare.y && this.x == pare.x) { long d = moddivision(3 * this.x * this.x + EccUtil.e.a, EccUtil.e.p, 2 * this.y);
res.x = d * d - 2 * this.x; res.x = mod(res.x, EccUtil.e.p);
res.y = d * (this.x - res.x) - this.y; res.y = mod(res.y, EccUtil.e.p); } else if (pare.x - this.x != 0) { long d = moddivision(pare.y - this.y, EccUtil.e.p, pare.x - this.x); res.x = d * d - this.x - pare.x; res.x = mod(res.x, EccUtil.e.p);
res.y = d * (this.x - res.x) - this.y; res.y = mod(res.y, EccUtil.e.p); } else { res.x = Integer.MAX_VALUE; res.y = Integer.MAX_VALUE; }
return res; }
public Pare less(Pare p) { p.y *= -1; return add(p); }
public Pare multiply(long num) { Pare p = new Pare(this.x, this.y); for (long i = 1; i < num; i++) { p = p.add(this); } return p; }
public long mod(long a, long b) { a = a % b; while (a < 0) { a += b; } return a; }
public long moddivision(long a, long b, long c) { a = mod(a, b); c = mod(c, b); a = a * EccMath.exgcd(c, b); return mod(a, b); }
@Override public String toString() { return EccTools.obox(EccTools.long2hexStr(this.x), 4) + " " + EccTools.obox(EccTools.long2hexStr(this.y), 4); } }
public Message encryption(Pare g, Pare pbk, Pare word) { pbk = g.multiply(privatekey); int d = new Random().nextInt(1024); Pare dg = g.multiply(d); Pare dp = pbk.multiply(d); Pare send = word.add(dp); return new Message(dg, send); }
public Pare decryption(Message m) { Pare pab = m.pa.multiply(this.privatekey); Pare result = m.pb.less(pab); return result; }
|