Skip to content

Commit 91cfaec

Browse files
committed
Handle unsigned part of sc_reduce correctly using BigInteger
The only BigInteger operations used are and(), or() and shift[Left|Right]() (but it is possible that these are not constant time?)
1 parent 0bad277 commit 91cfaec

File tree

1 file changed

+35
-33
lines changed

1 file changed

+35
-33
lines changed

src/net/i2p/crypto/eddsa/math/ed25519/Ed25519ScalarOps.java

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
package net.i2p.crypto.eddsa.math.ed25519;
22

3+
import java.math.BigInteger;
34
import net.i2p.crypto.eddsa.math.ScalarOps;
45

56
public class Ed25519ScalarOps implements ScalarOps {
6-
private long load_3(byte[] in, int offset) {
7-
long result = in[offset];
8-
result |= in[offset + 1] << 8;
9-
result |= in[offset + 2] << 16;
7+
private BigInteger load_3(byte[] in, int offset) {
8+
BigInteger result = new BigInteger(1, new byte[] {in[offset]});
9+
result = result.or(new BigInteger(1, new byte[] {in[offset+1]}).shiftLeft(8));
10+
result = result.or(new BigInteger(1, new byte[] {in[offset+2]}).shiftLeft(16));
1011
return result;
1112
}
1213

13-
private long load_4(byte[] in, int offset) {
14-
long result = in[offset];
15-
result |= in[offset + 1] << 8;
16-
result |= in[offset + 2] << 16;
17-
result |= in[offset + 3] << 24;
14+
private BigInteger load_4(byte[] in, int offset) {
15+
BigInteger result = new BigInteger(1, new byte[] {in[offset]});
16+
result = result.or(new BigInteger(1, new byte[] {in[offset+1]}).shiftLeft(8));
17+
result = result.or(new BigInteger(1, new byte[] {in[offset+2]}).shiftLeft(16));
18+
result = result.or(new BigInteger(1, new byte[] {in[offset+3]}).shiftLeft(24));
1819
return result;
1920
}
2021

@@ -27,30 +28,31 @@ private long load_4(byte[] in, int offset) {
2728
* where l = 2^252 + 27742317777372353535851937790883648493.
2829
*/
2930
public byte[] reduce(byte[] s) {
30-
long s0 = 2097151 & load_3(s, 0);
31-
long s1 = 2097151 & (load_4(s, 2) >> 5);
32-
long s2 = 2097151 & (load_3(s, 5) >> 2);
33-
long s3 = 2097151 & (load_4(s, 7) >> 7);
34-
long s4 = 2097151 & (load_4(s, 10) >> 4);
35-
long s5 = 2097151 & (load_3(s, 13) >> 1);
36-
long s6 = 2097151 & (load_4(s, 15) >> 6);
37-
long s7 = 2097151 & (load_3(s, 18) >> 3);
38-
long s8 = 2097151 & load_3(s, 21);
39-
long s9 = 2097151 & (load_4(s, 23) >> 5);
40-
long s10 = 2097151 & (load_3(s, 26) >> 2);
41-
long s11 = 2097151 & (load_4(s, 28) >> 7);
42-
long s12 = 2097151 & (load_4(s, 31) >> 4);
43-
long s13 = 2097151 & (load_3(s, 34) >> 1);
44-
long s14 = 2097151 & (load_4(s, 36) >> 6);
45-
long s15 = 2097151 & (load_3(s, 39) >> 3);
46-
long s16 = 2097151 & load_3(s, 42);
47-
long s17 = 2097151 & (load_4(s, 44) >> 5);
48-
long s18 = 2097151 & (load_3(s, 47) >> 2);
49-
long s19 = 2097151 & (load_4(s, 49) >> 7);
50-
long s20 = 2097151 & (load_4(s, 52) >> 4);
51-
long s21 = 2097151 & (load_3(s, 55) >> 1);
52-
long s22 = 2097151 & (load_4(s, 57) >> 6);
53-
long s23 = (load_4(s, 60) >> 3);
31+
BigInteger num = BigInteger.valueOf(2097151);
32+
long s0 = num.and(load_3(s, 0)).longValue();
33+
long s1 = num.and(load_4(s, 2).shiftRight(5)).longValue();
34+
long s2 = num.and(load_3(s, 5).shiftRight(2)).longValue();
35+
long s3 = num.and(load_4(s, 7).shiftRight(7)).longValue();
36+
long s4 = num.and(load_4(s, 10).shiftRight(4)).longValue();
37+
long s5 = num.and(load_3(s, 13).shiftRight(1)).longValue();
38+
long s6 = num.and(load_4(s, 15).shiftRight(6)).longValue();
39+
long s7 = num.and(load_3(s, 18).shiftRight(3)).longValue();
40+
long s8 = num.and(load_3(s, 21)).longValue();
41+
long s9 = num.and(load_4(s, 23).shiftRight(5)).longValue();
42+
long s10 = num.and(load_3(s, 26).shiftRight(2)).longValue();
43+
long s11 = num.and(load_4(s, 28).shiftRight(7)).longValue();
44+
long s12 = num.and(load_4(s, 31).shiftRight(4)).longValue();
45+
long s13 = num.and(load_3(s, 34).shiftRight(1)).longValue();
46+
long s14 = num.and(load_4(s, 36).shiftRight(6)).longValue();
47+
long s15 = num.and(load_3(s, 39).shiftRight(3)).longValue();
48+
long s16 = num.and(load_3(s, 42)).longValue();
49+
long s17 = num.and(load_4(s, 44).shiftRight(5)).longValue();
50+
long s18 = num.and(load_3(s, 47).shiftRight(2)).longValue();
51+
long s19 = num.and(load_4(s, 49).shiftRight(7)).longValue();
52+
long s20 = num.and(load_4(s, 52).shiftRight(4)).longValue();
53+
long s21 = num.and(load_3(s, 55).shiftRight(1)).longValue();
54+
long s22 = num.and(load_4(s, 57).shiftRight(6)).longValue();
55+
long s23 = (load_4(s, 60).shiftRight(3)).longValue();
5456
long carry0;
5557
long carry1;
5658
long carry2;

0 commit comments

Comments
 (0)