Skip to content

Commit 615978a

Browse files
authored
Merge pull request #21 from dufkan/master
ECPoint improvements, SecP256k1 definition
2 parents febdb4d + 4427d1a commit 615978a

File tree

3 files changed

+160
-18
lines changed

3 files changed

+160
-18
lines changed

JCMathLib/src/opencrypto/jcmathlib/ECPoint.java

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ public void makeDouble() {
175175
public void add(ECPoint other) {
176176
PM.check(PM.TRAP_ECPOINT_ADD_1);
177177

178+
boolean samePoint = this == other || isEqual(other);
179+
178180
ech.lock(ech.uncompressed_point_arr1);
179181
this.thePoint.getW(ech.uncompressed_point_arr1, (short) 0);
180182
ech.fnc_add_x_p.lock();
@@ -194,7 +196,7 @@ public void add(ECPoint other) {
194196
// P+Q=R
195197
ech.fnc_add_nominator.lock();
196198
ech.fnc_add_denominator.lock();
197-
if (this == other) {
199+
if (samePoint) {
198200
//lambda = (3(x_p^2)+a)/(2y_p)
199201
//(3(x_p^2)+a)
200202
ech.fnc_add_nominator.clone(ech.fnc_add_x_p);
@@ -245,7 +247,7 @@ public void add(ECPoint other) {
245247

246248
//x_r=lambda^2-x_p-x_q
247249
ech.fnc_add_x_r.lock();
248-
if (this == other) {
250+
if (samePoint) {
249251
short len = this.multiplication_x(Bignat_Helper.TWO, ech.fnc_add_x_r.as_byte_array(), (short) 0);
250252
ech.fnc_add_x_r.set_size(len);
251253
} else {
@@ -422,7 +424,65 @@ public void negate() {
422424
ech.unlock(ech.uncompressed_point_arr1);
423425
PM.check(PM.TRAP_ECPOINT_NEGATE_5);
424426
}
425-
427+
428+
/**
429+
* Restore point from X coordinate. Stores one of the two results into this point.
430+
*
431+
* @param xCoord byte array containing the X coordinate
432+
* @param xOffset offset in the byte array
433+
* @param xLen length of the X coordinate
434+
*/
435+
public void from_x(byte[] xCoord, short xOffset, short xLen) {
436+
ech.fnc_from_x_x.lock();
437+
ech.fnc_from_x_x.set_size(xLen);
438+
ech.fnc_from_x_x.from_byte_array(xLen, (short) 0, xCoord, xOffset);
439+
from_x(ech.fnc_from_x_x);
440+
ech.fnc_from_x_x.unlock();
441+
}
442+
443+
/**
444+
* Restore point from X coordinate. Stores one of the two results into this point.
445+
*
446+
* @param x the x coordinate
447+
*/
448+
private void from_x(Bignat x) {
449+
//Y^2 = X^3 + XA + B = x(x^2+A)+B
450+
ech.fnc_from_x_y_sq.lock();
451+
ech.fnc_from_x_y_sq.clone(x);
452+
ech.fnc_from_x_y_sq.mod_exp(Bignat_Helper.TWO, this.theCurve.pBN);
453+
ech.fnc_from_x_y_sq.mod_add(this.theCurve.aBN, this.theCurve.pBN);
454+
ech.fnc_from_x_y_sq.mod_mult(ech.fnc_from_x_y_sq, x, this.theCurve.pBN);
455+
ech.fnc_from_x_y_sq.mod_add(this.theCurve.bBN, this.theCurve.pBN);
456+
ech.fnc_from_x_y.lock();
457+
ech.fnc_from_x_y.clone(ech.fnc_from_x_y_sq);
458+
ech.fnc_from_x_y_sq.unlock();
459+
ech.fnc_from_x_y.sqrt_FP(this.theCurve.pBN);
460+
461+
// Construct public key with <x, y_1>
462+
ech.lock(ech.uncompressed_point_arr1);
463+
ech.uncompressed_point_arr1[0] = 0x04;
464+
x.prepend_zeros(this.theCurve.COORD_SIZE, ech.uncompressed_point_arr1, (short) 1);
465+
ech.fnc_from_x_y.prepend_zeros(this.theCurve.COORD_SIZE, ech.uncompressed_point_arr1, (short) (1 + theCurve.COORD_SIZE));
466+
ech.fnc_from_x_y.unlock();
467+
this.setW(ech.uncompressed_point_arr1, (short) 0, theCurve.POINT_SIZE);
468+
ech.unlock(ech.uncompressed_point_arr1);
469+
}
470+
471+
/**
472+
* Returns true if Y coordinate is even; false otherwise.
473+
*
474+
* @return true if Y coordinate is even; false otherwise
475+
*/
476+
public boolean is_y_even() {
477+
ech.fnc_is_y.lock();
478+
ech.lock(ech.uncompressed_point_arr1);
479+
thePoint.getW(ech.uncompressed_point_arr1, (short) 0);
480+
boolean result = ech.uncompressed_point_arr1[(short)(theCurve.POINT_SIZE - 1)] % 2 == 0;
481+
ech.unlock(ech.uncompressed_point_arr1);
482+
ech.fnc_is_y.unlock();
483+
return result;
484+
}
485+
426486
/**
427487
* Compares this and provided point for equality. The comparison is made using hash of both values to prevent leak of position of mismatching byte.
428488
* @param other second point for comparison

JCMathLib/src/opencrypto/jcmathlib/ECPoint_Helper.java

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
/**
88
*
9-
* @author Petr Svenda
9+
* @author Petr Svenda
1010
*/
1111
public class ECPoint_Helper extends Base_Helper {
1212
// Selected constants missing from older JC API specs
@@ -15,15 +15,15 @@ public class ECPoint_Helper extends Base_Helper {
1515
public static final byte Signature_ALG_ECDSA_SHA_256 = (byte) 33;
1616

1717
/**
18-
* I true, fast multiplication of ECPoints via KeyAgreement can be used Is
18+
* If true, fast multiplication of ECPoints via KeyAgreement can be used. Is
1919
* set automatically after successful allocation of required engines
2020
*/
2121
public boolean FLAG_FAST_EC_MULT_VIA_KA = false;
22-
22+
2323
byte[] uncompressed_point_arr1;
2424
byte[] fnc_isEqual_hashArray;
2525
byte[] fnc_multiplication_resultArray;
26-
26+
2727
// These Bignats are just pointing to some helperEC_BN_? so reasonable naming is preserved yet no need to actually allocated whole Bignat object
2828
Bignat fnc_add_x_r; // frequent write
2929
Bignat fnc_add_y_r; // frequent write
@@ -33,21 +33,27 @@ public class ECPoint_Helper extends Base_Helper {
3333
Bignat fnc_add_lambda; // write mod_mul (but only final result)
3434
Bignat fnc_add_nominator; // frequent write
3535
Bignat fnc_add_denominator; // frequent write
36-
36+
3737
Bignat fnc_multiplication_x; // result write
3838
Bignat fnc_multiplication_y_sq; // frequent write
3939
Bignat fnc_multiplication_scalar; // write once, read
4040
Bignat fnc_multiplication_y1; // mostly just read, write inside sqrt_FP
4141
Bignat fnc_multiplication_y2; // mostly just read, result write
4242
Bignat fnc_negate_yBN; // mostly just read, result write
43-
43+
44+
Bignat fnc_from_x_x;
45+
Bignat fnc_from_x_y_sq;
46+
Bignat fnc_from_x_y;
47+
48+
Bignat fnc_is_y;
49+
4450
KeyAgreement fnc_multiplication_x_keyAgreement;
4551
Signature fnc_SignVerifyECDSA_signEngine;
4652
MessageDigest fnc_isEqual_hashEngine;
47-
53+
4854
public ECPoint_Helper(ResourceManager rm) {
4955
super(rm);
50-
56+
5157
FLAG_FAST_EC_MULT_VIA_KA = false; // set true only if succesfully allocated and tested below
5258
try {
5359
//fnc_multiplication_x_keyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DHC, false);
@@ -57,9 +63,9 @@ public ECPoint_Helper(ResourceManager rm) {
5763
fnc_SignVerifyECDSA_signEngine = Signature.getInstance(Signature_ALG_ECDSA_SHA_256, false);
5864
FLAG_FAST_EC_MULT_VIA_KA = true;
5965
} catch (Exception ignored) {
60-
} // Discard any exception
66+
} // Discard any exception
6167
}
62-
68+
6369
void initialize() {
6470
// Important: assignment of helper BNs is made according to two criteria:
6571
// 1. Correctness: same BN must not be assigned to overlapping operations (guarded by lock/unlock)
@@ -74,21 +80,25 @@ void initialize() {
7480
fnc_add_nominator = rm.helperEC_BN_B;
7581
fnc_add_denominator = rm.helperEC_BN_C;
7682
fnc_add_lambda = rm.helperEC_BN_A;
77-
83+
7884
fnc_multiplication_scalar = rm.helperEC_BN_F;
7985
fnc_multiplication_x = rm.helperEC_BN_B;
8086
fnc_multiplication_y_sq = rm.helperEC_BN_C;
8187
fnc_multiplication_y1 = rm.helperEC_BN_D;
8288
fnc_multiplication_y2 = rm.helperEC_BN_B;
8389
fnc_multiplication_resultArray = rm.helper_BN_array1;
84-
90+
8591
fnc_negate_yBN = rm.helperEC_BN_C;
86-
92+
93+
Bignat fnc_from_x_x;
94+
Bignat fnc_from_x_y_sq;
95+
Bignat fnc_from_x_y;
96+
97+
fnc_is_y = rm.helperEC_BN_C;
98+
8799
fnc_isEqual_hashArray = rm.helper_hashArray;
88100
fnc_isEqual_hashEngine = rm.hashEngine;
89101

90102
uncompressed_point_arr1 = rm.helper_uncompressed_point_arr1;
91-
92103
}
93-
94104
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package opencrypto.jcmathlib;
2+
3+
public class SecP256k1 {
4+
5+
public final static short KEY_LENGTH = 256; // Bits
6+
public final static short POINT_SIZE = 65; // Bytes
7+
public final static short COORD_SIZE = 32; // Bytes
8+
9+
public final static byte[] p = {
10+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
11+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
12+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
13+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
14+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
15+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
16+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xfe,
17+
(byte) 0xff, (byte) 0xff, (byte) 0xfc, (byte) 0x2f
18+
};
19+
20+
public final static byte[] a = {
21+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
22+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
23+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
24+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
25+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
26+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
27+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
28+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
29+
};
30+
31+
public final static byte[] b = {
32+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
33+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
34+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
35+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
36+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
37+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
38+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
39+
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x07
40+
};
41+
42+
public final static byte[] G = {
43+
(byte) 0x04,
44+
(byte) 0x79, (byte) 0xbe, (byte) 0x66, (byte) 0x7e,
45+
(byte) 0xf9, (byte) 0xdc, (byte) 0xbb, (byte) 0xac,
46+
(byte) 0x55, (byte) 0xa0, (byte) 0x62, (byte) 0x95,
47+
(byte) 0xce, (byte) 0x87, (byte) 0x0b, (byte) 0x07,
48+
(byte) 0x02, (byte) 0x9b, (byte) 0xfc, (byte) 0xdb,
49+
(byte) 0x2d, (byte) 0xce, (byte) 0x28, (byte) 0xd9,
50+
(byte) 0x59, (byte) 0xf2, (byte) 0x81, (byte) 0x5b,
51+
(byte) 0x16, (byte) 0xf8, (byte) 0x17, (byte) 0x98,
52+
(byte) 0x48, (byte) 0x3a, (byte) 0xda, (byte) 0x77,
53+
(byte) 0x26, (byte) 0xa3, (byte) 0xc4, (byte) 0x65,
54+
(byte) 0x5d, (byte) 0xa4, (byte) 0xfb, (byte) 0xfc,
55+
(byte) 0x0e, (byte) 0x11, (byte) 0x08, (byte) 0xa8,
56+
(byte) 0xfd, (byte) 0x17, (byte) 0xb4, (byte) 0x48,
57+
(byte) 0xa6, (byte) 0x85, (byte) 0x54, (byte) 0x19,
58+
(byte) 0x9c, (byte) 0x47, (byte) 0xd0, (byte) 0x8f,
59+
(byte) 0xfb, (byte) 0x10, (byte) 0xd4, (byte) 0xb8
60+
};
61+
62+
public final static byte[] r = {
63+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
64+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
65+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
66+
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xfe,
67+
(byte) 0xba, (byte) 0xae, (byte) 0xdc, (byte) 0xe6,
68+
(byte) 0xaf, (byte) 0x48, (byte) 0xa0, (byte) 0x3b,
69+
(byte) 0xbf, (byte) 0xd2, (byte) 0x5e, (byte) 0x8c,
70+
(byte) 0xd0, (byte) 0x36, (byte) 0x41, (byte) 0x41,
71+
};
72+
}

0 commit comments

Comments
 (0)