Skip to content

Commit 49aac3c

Browse files
authored
Merge pull request #3 from OpenCryptoProject/devel
Devel
2 parents ea4436f + 33c9d79 commit 49aac3c

30 files changed

+3159
-683
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@
2121
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2222
hs_err_pid*
2323
/JCMathLibTests/build/
24-
/JCMathLibTests/dist/
24+
/JCMathLibTests/dist/
25+
/JCMathLibExamples/build/
26+
/JCMathLibExamples/dist/

JCMathLib/!uploader/opcrypto.cap

-950 Bytes
Binary file not shown.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package opencrypto.jcmathlib;
2+
3+
/**
4+
*
5+
* @author Petr Svenda
6+
*/
7+
public class Base_Helper {
8+
final ResourceManager rm;
9+
10+
/**
11+
* Helper flag which signalizes that code is executed inside simulator
12+
* (during tests). Is used to address simulator specific behaviour
13+
* workaround if required.
14+
*/
15+
public boolean bIsSimulator = false;
16+
17+
public Base_Helper(ResourceManager resman) {
18+
rm = resman;
19+
}
20+
21+
/**
22+
* Lock/reserve provided object for subsequent use. Used to protect
23+
* corruption of pre-allocated shared objects in different, potentially
24+
* nested, operations. Must be unlocked later on.
25+
*
26+
* @param objToLock array to be locked
27+
* @throws SW_ALREADYLOCKED if already locked (is already in use by other
28+
* operation)
29+
*/
30+
/*
31+
public void lock(Object objToLock) {
32+
rm.locker.lock(objToLock);
33+
}
34+
*/
35+
public void lock(byte[] objToLock) {
36+
rm.locker.lock(objToLock);
37+
}
38+
39+
/**
40+
* Unlock/release object from use. Used to protect corruption of
41+
* pre-allocated objects used in different nested operations. Must be locked
42+
* before.
43+
*
44+
* @param objToUnlock object to unlock
45+
* @throws SW_NOTLOCKED_BIGNAT if was not locked before (inconsistence in
46+
* lock/unlock sequence)
47+
*/
48+
/*
49+
public void unlock(Object objToUnlock) {
50+
rm.locker.unlock(objToUnlock);
51+
}
52+
*/
53+
public void unlock(byte[] objToUnlock) {
54+
rm.locker.unlock(objToUnlock);
55+
}
56+
57+
/**
58+
* Unlocks all locked objects
59+
*/
60+
public void unlockAll() {
61+
rm.locker.unlockAll();
62+
}
63+
64+
/**
65+
* Check if provided object is logically locked
66+
*
67+
* @param objToUnlock object to be checked
68+
* @return true of array is logically locked, false otherwise
69+
*/
70+
/*
71+
public boolean isLocked(Object objToUnlock) {
72+
return rm.locker.isLocked(objToUnlock);
73+
}
74+
*/
75+
/**
76+
* Allocates new byte[] array with provided length either in RAM or EEPROM
77+
* based on an allocator type. Method updates internal counters of bytes
78+
* allocated with specific allocator. Use {@code getAllocatedInRAM()} or
79+
* {@code getAllocatedInEEPROM} for counters readout.
80+
*
81+
* @param length length of array
82+
* @param allocatorType type of allocator
83+
* @return allocated array
84+
*/
85+
public byte[] allocateByteArray(short length, byte allocatorType) {
86+
return rm.memAlloc.allocateByteArray(length, allocatorType);
87+
}
88+
}

JCMathLib/src/opencrypto/jcmathlib/Bignat.java

Lines changed: 223 additions & 211 deletions
Large diffs are not rendered by default.

JCMathLib/src/opencrypto/jcmathlib/Bignat_Helper.java

Lines changed: 84 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,42 @@
1212
*
1313
* @author Petr Svenda
1414
*/
15-
public class Bignat_Helper {
16-
private final ECConfig ecc;
17-
15+
public class Bignat_Helper extends Base_Helper {
16+
/**
17+
* The size of speedup engine used for fast modulo exponent computation
18+
* (must be larger than biggest Bignat used)
19+
*/
20+
public short MODULO_RSA_ENGINE_MAX_LENGTH_BITS = (short) 512;
1821
/**
19-
* Helper flag which signalizes that code is executed inside simulator
20-
* (during tests). Is used to address simulator specific behaviour workaround
21-
* if required.
22+
* The size of speedup engine used for fast multiplication of large numbers
23+
* Must be larger than 2x biggest Bignat used
2224
*/
23-
public boolean bIsSimulator = false;
25+
public short MULT_RSA_ENGINE_MAX_LENGTH_BITS = (short) 768;
2426

25-
byte[] helper_BN_array1 = null;
26-
byte[] helper_BN_array2 = null;
2727
/**
28-
* Number of pre-allocated helper arrays
28+
* If true, fast multiplication of large numbers via RSA engine can be used.
29+
* Is set automatically after successful allocation of required engines
2930
*/
30-
public static final byte NUM_HELPER_ARRAYS = 2;
31-
32-
byte[] fnc_deep_resize_tmp = null;
33-
public byte[] fnc_mult_resultArray1 = null;
34-
byte[] fnc_mult_resultArray2 = null;
31+
public boolean FLAG_FAST_MULT_VIA_RSA = false;
32+
/**
33+
* Threshold length in bits of an operand after which speedup with RSA
34+
* multiplication is used. Schoolbook multiplication is used for shorter
35+
* operands
36+
*/
37+
public static final short FAST_MULT_VIA_RSA_TRESHOLD_LENGTH = (short) 16;
38+
3539
byte[] tmp_array_short = null;
3640

41+
//
42+
// References to underlaying shared objects
43+
//
44+
byte[] fnc_mult_resultArray1 = null;
45+
byte[] fnc_deep_resize_tmp = null;
46+
byte[] fnc_mult_resultArray2 = null;
3747
byte[] fnc_same_value_array1 = null;
3848
byte[] fnc_same_value_hash = null;
49+
byte[] fnc_shift_bytes_right_tmp = null;
3950

40-
41-
// These Bignats helper_BN_? are allocated
42-
Bignat helper_BN_A;
43-
Bignat helper_BN_B;
44-
Bignat helper_BN_C;
45-
Bignat helper_BN_D;
46-
Bignat helper_BN_E;
47-
Bignat helper_BN_F;
48-
4951
// These Bignats are just pointing to some helper_BN_? so reasonable naming is preserved yet no need to actually allocated whole Bignat object
5052
Bignat fnc_mod_exp_modBN;
5153

@@ -84,9 +86,9 @@ public class Bignat_Helper {
8486
RSAPublicKey fnc_NmodE_pubKey;
8587
Cipher fnc_NmodE_cipher;
8688

87-
public Bignat ONE;
88-
public Bignat TWO;
89-
public Bignat THREE;
89+
public static Bignat ONE;
90+
public static Bignat TWO;
91+
public static Bignat THREE;
9092

9193

9294
// Helper objects for fast multiplication of two large numbers (without modulo)
@@ -98,135 +100,98 @@ public class Bignat_Helper {
98100
static byte[] CONST_ONE = {0x01};
99101
static byte[] CONST_TWO = {0x02};
100102

101-
public Bignat_Helper(ECConfig ecCfg) {
102-
ecc = ecCfg;
103+
public Bignat_Helper(ResourceManager resman) {
104+
super(resman);
105+
}
106+
107+
void initialize(short modRSAEngineMaxBits, short multRSAEngineMaxBits) {
108+
MODULO_RSA_ENGINE_MAX_LENGTH_BITS = modRSAEngineMaxBits;
109+
MULT_RSA_ENGINE_MAX_LENGTH_BITS = multRSAEngineMaxBits;
110+
111+
fnc_deep_resize_tmp = rm.helper_BN_array1;
112+
fnc_mult_resultArray1 = rm.helper_BN_array1;
113+
fnc_mult_resultArray2 = rm.helper_BN_array2;
103114

104-
tmp_array_short = ecc.memAlloc.allocateByteArray((short) 2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // only 2b RAM for faster add(short)
105-
fnc_NmodE_cipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);
106-
fnc_NmodE_pubKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, ecc.MODULO_RSA_ENGINE_MAX_LENGTH_BITS, false);
115+
fnc_same_value_array1 = rm.helper_BN_array1;
116+
fnc_same_value_hash = rm.helper_BN_array2;
107117

108-
// Multiplication speedup engines and arrays used by Bignat.mult_RSATrick()
109-
helper_BN_array1 = ecc.memAlloc.allocateByteArray((short) (ecc.MULT_RSA_ENGINE_MAX_LENGTH_BITS / 8), ecc.memAlloc.getAllocatorType(ObjectAllocator.BNH_helper_BN_array1));
110-
ecc.locker.registerLock(helper_BN_array1);
111-
helper_BN_array2 = ecc.memAlloc.allocateByteArray((short) (ecc.MULT_RSA_ENGINE_MAX_LENGTH_BITS / 8), ecc.memAlloc.getAllocatorType(ObjectAllocator.BNH_helper_BN_array2));
112-
ecc.locker.registerLock(helper_BN_array2);
113-
114-
fnc_deep_resize_tmp = helper_BN_array1;
115-
fnc_mult_resultArray1 = helper_BN_array1;
116-
fnc_mult_resultArray2 = helper_BN_array2;
117-
118-
fnc_same_value_array1 = helper_BN_array1;
119-
fnc_same_value_hash = helper_BN_array2;
118+
fnc_shift_bytes_right_tmp = rm.helper_BN_array1;
120119

121-
helper_BN_A = new Bignat(ecc.MAX_BIGNAT_SIZE, ecc.memAlloc.getAllocatorType(ObjectAllocator.BNH_helper_BN_A), ecc);
122-
helper_BN_B = new Bignat(ecc.MAX_BIGNAT_SIZE, ecc.memAlloc.getAllocatorType(ObjectAllocator.BNH_helper_BN_B), ecc);
123-
helper_BN_C = new Bignat(ecc.MAX_BIGNAT_SIZE, ecc.memAlloc.getAllocatorType(ObjectAllocator.BNH_helper_BN_C), ecc);
124-
helper_BN_D = new Bignat(ecc.MAX_BIGNAT_SIZE, ecc.memAlloc.getAllocatorType(ObjectAllocator.BNH_helper_BN_D), ecc);
125-
helper_BN_E = new Bignat(ecc.MAX_BIGNAT_SIZE, ecc.memAlloc.getAllocatorType(ObjectAllocator.BNH_helper_BN_E), ecc);
126-
helper_BN_F = new Bignat((short) (ecc.MAX_BIGNAT_SIZE + 2), ecc.memAlloc.getAllocatorType(ObjectAllocator.BNH_helper_BN_F), ecc); // +2 is to correct for infrequent RSA result with two or more leading zeroes
127-
128120
// BN below are just reassigned allocated helper_BN_? so that same helper_BN_? is not used in parallel (checked by lock() unlock())
129-
fnc_mod_add_tmp = helper_BN_A;
121+
fnc_mod_add_tmp = rm.helper_BN_A;
130122

131-
fnc_mod_sub_tmpThis = helper_BN_A;
132-
fnc_mod_sub_tmp = helper_BN_B;
133-
fnc_mod_sub_tmpOther = helper_BN_C;
123+
fnc_mod_sub_tmpThis = rm.helper_BN_A;
124+
fnc_mod_sub_tmp = rm.helper_BN_B;
125+
fnc_mod_sub_tmpOther = rm.helper_BN_C;
134126

135-
fnc_mult_mod_tmpThis = helper_BN_A;
136-
fnc_mult_mod_tmp_mod = helper_BN_B;
137-
fnc_mult_mod_tmp_x = helper_BN_C;
127+
fnc_mult_mod_tmpThis = rm.helper_BN_A;
128+
fnc_mult_mod_tmp_mod = rm.helper_BN_B;
129+
fnc_mult_mod_tmp_x = rm.helper_BN_C;
138130

139-
fnc_exponentiation_tmp = helper_BN_A;
140-
fnc_exponentiation_i = helper_BN_B;
131+
fnc_exponentiation_tmp = rm.helper_BN_A;
132+
fnc_exponentiation_i = rm.helper_BN_B;
141133

142-
fnc_mod_minus_2 = helper_BN_B;
134+
fnc_mod_minus_2 = rm.helper_BN_B;
143135

144-
fnc_negate_tmp = helper_BN_B;
136+
fnc_negate_tmp = rm.helper_BN_B;
145137

146-
fnc_sqrt_S = helper_BN_A;
147-
fnc_sqrt_exp = helper_BN_A;
148-
fnc_sqrt_p_1 = helper_BN_B;
149-
fnc_sqrt_Q = helper_BN_C;
150-
fnc_sqrt_tmp = helper_BN_D;
151-
fnc_sqrt_z = helper_BN_E;
138+
fnc_sqrt_S = rm.helper_BN_A;
139+
fnc_sqrt_exp = rm.helper_BN_A;
140+
fnc_sqrt_p_1 = rm.helper_BN_B;
141+
fnc_sqrt_Q = rm.helper_BN_C;
142+
fnc_sqrt_tmp = rm.helper_BN_D;
143+
fnc_sqrt_z = rm.helper_BN_E;
152144

153-
fnc_mod_mult_tmpThis = helper_BN_E; // mod_mult is called from fnc_sqrt => requires helper_BN_E not being locked in fnc_sqrt when mod_mult is called
145+
fnc_mod_mult_tmpThis = rm.helper_BN_E; // mod_mult is called from fnc_sqrt => requires helper_BN_E not being locked in fnc_sqrt when mod_mult is called
154146

155-
fnc_divide_tmpThis = helper_BN_E; // divide is called from fnc_sqrt => requires helper_BN_E not being locked in fnc_sqrt when divide is called
147+
fnc_divide_tmpThis = rm.helper_BN_E; // divide is called from fnc_sqrt => requires helper_BN_E not being locked in fnc_sqrt when divide is called
156148

157-
fnc_mod_exp_modBN = helper_BN_F; // mod_exp is called from fnc_sqrt => requires helper_BN_F not being locked in fnc_sqrt when mod_exp is called
149+
fnc_mod_exp_modBN = rm.helper_BN_F; // mod_exp is called from fnc_sqrt => requires helper_BN_F not being locked in fnc_sqrt when mod_exp is called
158150

159-
fnc_int_add_tmpMag = helper_BN_A;
160-
fnc_int_multiply_mod = helper_BN_A;
161-
fnc_int_multiply_tmpThis = helper_BN_B;
162-
fnc_int_divide_tmpThis = helper_BN_A;
151+
fnc_int_add_tmpMag = rm.helper_BN_A;
152+
fnc_int_multiply_mod = rm.helper_BN_A;
153+
fnc_int_multiply_tmpThis = rm.helper_BN_B;
154+
fnc_int_divide_tmpThis = rm.helper_BN_A;
155+
163156

164157
// Allocate BN constants always in EEPROM (only reading)
165-
ONE = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, ecc);
158+
ONE = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, this);
166159
ONE.one();
167-
TWO = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, ecc);
160+
TWO = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, this);
168161
TWO.two();
169-
THREE = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, ecc);
162+
THREE = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, this);
170163
THREE.three();
171164

165+
tmp_array_short = rm.memAlloc.allocateByteArray((short) 2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // only 2b RAM for faster add(short)
166+
fnc_NmodE_cipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);
167+
fnc_NmodE_pubKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, MODULO_RSA_ENGINE_MAX_LENGTH_BITS, false);
168+
172169
// Speedup for fast multiplication
173-
fnc_mult_keypair = new KeyPair(KeyPair.ALG_RSA_CRT, ecc.MULT_RSA_ENGINE_MAX_LENGTH_BITS);
170+
fnc_mult_keypair = new KeyPair(KeyPair.ALG_RSA_CRT, MULT_RSA_ENGINE_MAX_LENGTH_BITS);
174171
fnc_mult_keypair.genKeyPair();
175172
fnc_mult_pubkey_pow2 = (RSAPublicKey) fnc_mult_keypair.getPublic();
176173
//mult_privkey_pow2 = (RSAPrivateCrtKey) mult_keypair.getPrivate();
177174
fnc_mult_pubkey_pow2.setExponent(CONST_TWO, (short) 0, (short) CONST_TWO.length);
178175
fnc_mult_cipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);
179-
180-
hashEngine = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false);
181176

182-
183-
ecc.FLAG_FAST_MULT_VIA_RSA = false; // set true only if succesfully allocated and tested below
177+
hashEngine = rm.hashEngine;
178+
179+
FLAG_FAST_MULT_VIA_RSA = false; // set true only if succesfully allocated and tested below
184180
try { // Subsequent code may fail on some real (e.g., Infineon CJTOP80K) cards - catch exception
185-
fnc_mult_cipher.init(fnc_mult_pubkey_pow2, Cipher.MODE_ENCRYPT);
181+
fnc_mult_cipher.init(fnc_mult_pubkey_pow2, Cipher.MODE_ENCRYPT);
186182
// Try operation - if doesn't work, exception SW_CANTALLOCATE_BIGNAT is emitted
187183
Util.arrayFillNonAtomic(fnc_mult_resultArray1, (short) 0, (short) fnc_mult_resultArray1.length, (byte) 6);
188184
fnc_mult_cipher.doFinal(fnc_mult_resultArray1, (short) 0, (short) fnc_mult_resultArray1.length, fnc_mult_resultArray1, (short) 0);
189-
ecc.FLAG_FAST_MULT_VIA_RSA = true;
190-
} catch (Exception ignored) {} // discard exception
185+
FLAG_FAST_MULT_VIA_RSA = true;
186+
} catch (Exception ignored) {
187+
} // discard exception
191188
}
192189

193190
/**
194191
* Erase all values stored in helper objects
195192
*/
196193
void erase() {
197-
helper_BN_A.erase();
198-
helper_BN_B.erase();
199-
helper_BN_C.erase();
200-
helper_BN_D.erase();
201-
helper_BN_E.erase();
202-
helper_BN_F.erase();
203-
194+
rm.erase();
204195
Util.arrayFillNonAtomic(tmp_array_short, (short) 0, (short) tmp_array_short.length, (byte) 0);
205-
Util.arrayFillNonAtomic(helper_BN_array1, (short) 0, (short) helper_BN_array1.length, (byte) 0);
206-
Util.arrayFillNonAtomic(helper_BN_array2, (short) 0, (short) helper_BN_array2.length, (byte) 0);
207-
}
208-
209-
/**
210-
* Unlocks all helper objects
211-
*/
212-
public void unlockAll() {
213-
if (helper_BN_A.isLocked()) {
214-
helper_BN_A.unlock();
215-
}
216-
if (helper_BN_B.isLocked()) {
217-
helper_BN_B.unlock();
218-
}
219-
if (helper_BN_C.isLocked()) {
220-
helper_BN_C.unlock();
221-
}
222-
if (helper_BN_D.isLocked()) {
223-
helper_BN_D.unlock();
224-
}
225-
if (helper_BN_E.isLocked()) {
226-
helper_BN_E.unlock();
227-
}
228-
if (helper_BN_F.isLocked()) {
229-
helper_BN_F.unlock();
230-
}
231196
}
232197
}

0 commit comments

Comments
 (0)