Skip to content

Commit 8f4da72

Browse files
committed
Merge pull request #8 from franks42/master
In TweetNaclFast.java, added additional methods for Box' box, open, a…
2 parents 55b97c5 + 816defa commit 8f4da72

File tree

4 files changed

+321
-34
lines changed

4 files changed

+321
-34
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ TweetNacl in Java
1212
* decryption: message = box.open(cipher);
1313
* Nonce MUST be unique for ever message passed between same peers
1414

15+
As an alternative, the nonce can be omitted from the Box() call, and passed in the box and open calls, like:
16+
17+
* byte [] nonce = new byte[nonceLength], randombytes(theNonce, nonceLength);
18+
* Box.KeyPair kp = Box.keyPair(), kp = Box.keyPair_fromSecretKey(sk)
19+
* Box box = new Box(theirPublicKey, mySecretKey);
20+
* encryption: cipher = box.box(message, nonce);
21+
* decryption: message = box.open(cipher, nonce);
22+
23+
1524

1625
#### Secret key authenticated encryption
1726

@@ -21,6 +30,13 @@ TweetNacl in Java
2130
* decryption: message = sbox.open(cipher);
2231
* Nonce MUST be unique for ever message passed between same peers
2332

33+
As an alternative, the nonce can be omitted from the SecretBox() call, and passed in the box and open calls, like:
34+
35+
* byte [] nonce = new byte[nonceLength], randombytes(theNonce, nonceLength);
36+
* SecretBox sbox = new SecretBox(sharedKey);
37+
* cipher = sbox.box(message, nonce);
38+
* decryption: message = sbox.open(cipher, nonce);
39+
2440

2541
### Signature
2642

src/com/iwebpp/crypto/TweetNaclFast.java

Lines changed: 134 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -83,27 +83,53 @@ private byte[] generateNonce() {
8383
* */
8484
public byte [] box(byte [] message) {
8585
if (message==null) return null;
86-
87-
// prepare shared key
88-
if (this.sharedKey == null) before();
89-
90-
return after(message, 0, message.length);
86+
return box(message, 0, message.length);
9187
}
88+
9289
public byte [] box(byte [] message, final int moff) {
9390
if (!(message!=null && message.length>moff)) return null;
91+
return box(message, moff, message.length-moff);
92+
}
93+
94+
public byte [] box(byte [] message, final int moff, final int mlen) {
95+
if (!(message!=null && message.length>=(moff+mlen))) return null;
9496

9597
// prepare shared key
9698
if (this.sharedKey == null) before();
9799

98-
return after(message, moff, message.length-moff);
100+
return after(message, moff, mlen);
99101
}
100-
public byte [] box(byte [] message, final int moff, final int mlen) {
101-
if (!(message!=null && message.length>=(moff+mlen))) return null;
102+
103+
/*
104+
* @description
105+
* Encrypt and authenticates message using peer's public key,
106+
* our secret key, and the given nonce, which must be unique
107+
* for each distinct message for a key pair.
108+
*
109+
* Explicitly pass the nonce
110+
*
111+
* Returns an encrypted and authenticated message,
112+
* which is nacl.box.overheadLength longer than the original message.
113+
* */
114+
public byte [] box(byte [] message, byte [] theNonce) {
115+
if (message==null) return null;
116+
return box(message, 0, message.length, theNonce);
117+
}
118+
119+
public byte [] box(byte [] message, final int moff, byte [] theNonce) {
120+
if (!(message!=null && message.length>moff)) return null;
121+
return box(message, moff, message.length-moff, theNonce);
122+
}
123+
124+
public byte [] box(byte [] message, final int moff, final int mlen, byte [] theNonce) {
125+
if (!(message!=null && message.length>=(moff+mlen) &&
126+
theNonce!=null && theNonce.length==nonceLength))
127+
return null;
102128

103129
// prepare shared key
104130
if (this.sharedKey == null) before();
105131

106-
return after(message, moff, mlen);
132+
return after(message, moff, mlen, theNonce);
107133
}
108134

109135
/*
@@ -138,6 +164,46 @@ private byte[] generateNonce() {
138164
return open_after(box, boxoff, boxlen);
139165
}
140166

167+
168+
/*
169+
* @description
170+
* Authenticates and decrypts the given box with peer's public key,
171+
* our secret key, and the given nonce.
172+
* Explicit passing of nonce
173+
* Returns the original message, or null if authentication fails.
174+
* */
175+
public byte [] open(byte [] box, byte [] theNonce) {
176+
if (!(box!=null &&
177+
theNonce!=null && theNonce.length==nonceLength))
178+
return null;
179+
180+
// prepare shared key
181+
if (this.sharedKey == null) before();
182+
183+
return open_after(box, 0, box.length, theNonce);
184+
}
185+
public byte [] open(byte [] box, final int boxoff, byte [] theNonce) {
186+
if (!(box!=null && box.length>boxoff &&
187+
theNonce!=null && theNonce.length==nonceLength))
188+
return null;
189+
190+
// prepare shared key
191+
if (this.sharedKey == null) before();
192+
193+
return open_after(box, boxoff, box.length-boxoff, theNonce);
194+
}
195+
public byte [] open(byte [] box, final int boxoff, final int boxlen, byte [] theNonce) {
196+
if (!(box!=null && box.length>=(boxoff+boxlen) &&
197+
theNonce!=null && theNonce.length==nonceLength))
198+
return null;
199+
200+
// prepare shared key
201+
if (this.sharedKey == null) before();
202+
203+
return open_after(box, boxoff, boxlen, theNonce);
204+
}
205+
206+
141207
/*
142208
* @description
143209
* Returns a precomputed shared key
@@ -157,13 +223,20 @@ private byte[] generateNonce() {
157223
* Same as nacl.box, but uses a shared key precomputed with nacl.box.before.
158224
* */
159225
public byte [] after(byte [] message, final int moff, final int mlen) {
226+
return after(message, moff, mlen, generateNonce());
227+
}
228+
229+
/*
230+
* @description
231+
* Same as nacl.box, but uses a shared key precomputed with nacl.box.before,
232+
* and passes a nonce explicitly.
233+
* */
234+
public byte [] after(byte [] message, final int moff, final int mlen, byte [] theNonce) {
160235
// check message
161-
if (!(message!=null && message.length>=(moff+mlen)))
236+
if (!(message!=null && message.length>=(moff+mlen) &&
237+
theNonce!=null && theNonce.length==nonceLength))
162238
return null;
163239

164-
// generate nonce
165-
byte [] n = generateNonce();
166-
167240
// message buffer
168241
byte [] m = new byte[mlen + zerobytesLength];
169242

@@ -173,7 +246,7 @@ private byte[] generateNonce() {
173246
for (int i = 0; i < mlen; i ++)
174247
m[i+zerobytesLength] = message[i+moff];
175248

176-
if (0 != crypto_box_afternm(c, m, m.length, n, sharedKey))
249+
if (0 != crypto_box_afternm(c, m, m.length, theNonce, sharedKey))
177250
return null;
178251

179252
// wrap byte_buf_t on c offset@boxzerobytesLength
@@ -192,13 +265,14 @@ private byte[] generateNonce() {
192265
* but uses a shared key pre-computed with nacl.box.before.
193266
* */
194267
public byte [] open_after(byte [] box, final int boxoff, final int boxlen) {
268+
return open_after(box, boxoff, boxlen, generateNonce());
269+
}
270+
271+
public byte [] open_after(byte [] box, final int boxoff, final int boxlen, byte [] theNonce) {
195272
// check message
196273
if (!(box!=null && box.length>=(boxoff+boxlen) && boxlen>=boxzerobytesLength))
197274
return null;
198275

199-
// generate nonce
200-
byte [] n = generateNonce();
201-
202276
// cipher buffer
203277
byte [] c = new byte[boxlen + boxzerobytesLength];
204278

@@ -208,7 +282,7 @@ private byte[] generateNonce() {
208282
for (int i = 0; i < boxlen; i++)
209283
c[i+boxzerobytesLength] = box[i+boxoff];
210284

211-
if (crypto_box_open_afternm(m, c, c.length, n, sharedKey) != 0)
285+
if (crypto_box_open_afternm(m, c, c.length, theNonce, sharedKey) != 0)
212286
return null;
213287

214288
// wrap byte_buf_t on m offset@zerobytesLength
@@ -367,21 +441,36 @@ private byte[] generateNonce() {
367441
* */
368442
public byte [] box(byte [] message) {
369443
if (message==null) return null;
370-
371444
return box(message, 0, message.length);
372445
}
446+
373447
public byte [] box(byte [] message, final int moff) {
374448
if (!(message!=null && message.length>moff)) return null;
375-
376449
return box(message, moff, message.length-moff);
377450
}
451+
378452
public byte [] box(byte [] message, final int moff, final int mlen) {
379453
// check message
380454
if (!(message!=null && message.length>=(moff+mlen)))
381455
return null;
456+
return box(message, moff, message.length-moff, generateNonce());
457+
}
382458

383-
// generate nonce
384-
byte [] n = generateNonce();
459+
public byte [] box(byte [] message, byte [] theNonce) {
460+
if (message==null) return null;
461+
return box(message, 0, message.length, theNonce);
462+
}
463+
464+
public byte [] box(byte [] message, final int moff, byte [] theNonce) {
465+
if (!(message!=null && message.length>moff)) return null;
466+
return box(message, moff, message.length-moff, theNonce);
467+
}
468+
469+
public byte [] box(byte [] message, final int moff, final int mlen, byte [] theNonce) {
470+
// check message
471+
if (!(message!=null && message.length>=(moff+mlen) &&
472+
theNonce!=null && theNonce.length==nonceLength))
473+
return null;
385474

386475
// message buffer
387476
byte [] m = new byte[mlen + zerobytesLength];
@@ -392,7 +481,7 @@ private byte[] generateNonce() {
392481
for (int i = 0; i < mlen; i ++)
393482
m[i+zerobytesLength] = message[i+moff];
394483

395-
if (0 != crypto_secretbox(c, m, m.length, n, key))
484+
if (0 != crypto_secretbox(c, m, m.length, theNonce, key))
396485
return null;
397486

398487
// TBD optimizing ...
@@ -415,21 +504,36 @@ private byte[] generateNonce() {
415504
* */
416505
public byte [] open(byte [] box) {
417506
if (box==null) return null;
418-
419507
return open(box, 0, box.length);
420508
}
509+
421510
public byte [] open(byte [] box, final int boxoff) {
422511
if (!(box!=null && box.length>boxoff)) return null;
423-
424512
return open(box, boxoff, box.length-boxoff);
425513
}
514+
426515
public byte [] open(byte [] box, final int boxoff, final int boxlen) {
427516
// check message
428517
if (!(box!=null && box.length>=(boxoff+boxlen) && boxlen>=boxzerobytesLength))
429518
return null;
430-
431-
// generate nonce
432-
byte [] n = generateNonce();
519+
return open(box, boxoff, box.length-boxoff, generateNonce());
520+
}
521+
522+
public byte [] open(byte [] box, byte [] theNonce) {
523+
if (box==null) return null;
524+
return open(box, 0, box.length, theNonce);
525+
}
526+
527+
public byte [] open(byte [] box, final int boxoff, byte [] theNonce) {
528+
if (!(box!=null && box.length>boxoff)) return null;
529+
return open(box, boxoff, box.length-boxoff, theNonce);
530+
}
531+
532+
public byte [] open(byte [] box, final int boxoff, final int boxlen, byte [] theNonce) {
533+
// check message
534+
if (!(box!=null && box.length>=(boxoff+boxlen) && boxlen>=boxzerobytesLength &&
535+
theNonce!=null && theNonce.length==nonceLength))
536+
return null;
433537

434538
// cipher buffer
435539
byte [] c = new byte[boxlen + boxzerobytesLength];
@@ -440,7 +544,7 @@ private byte[] generateNonce() {
440544
for (int i = 0; i < boxlen; i++)
441545
c[i+boxzerobytesLength] = box[i+boxoff];
442546

443-
if (0 != crypto_secretbox_open(m, c, c.length, n, key))
547+
if (0 != crypto_secretbox_open(m, c, c.length, theNonce, key))
444548
return null;
445549

446550
// wrap byte_buf_t on m offset@zerobytesLength
@@ -3209,7 +3313,7 @@ public static int crypto_sign_open(byte [] m, long dummy /* *mlen not used*/, by
32093313
* */
32103314
private static final SecureRandom jrandom = new SecureRandom();
32113315

3212-
private static void randombytes(byte [] x, int len) {
3316+
public static void randombytes(byte [] x, int len) {
32133317
int ret = len % 8;
32143318
long rnd;
32153319

0 commit comments

Comments
 (0)