Skip to content

Commit d7a167b

Browse files
committed
conflict resolution
2 parents 309ce4d + cec37aa commit d7a167b

File tree

113 files changed

+10893
-719
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+10893
-719
lines changed

ci/pub.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ source ci/common.sh
1414
export JAVA_HOME=`openjdk_21`
1515
export PATH=$JAVA_HOME/bin:$PATH
1616

17+
./gradlew clean build -x test
18+
./osgi_scan.sh
1719

18-
./gradlew clean build publishAllPublicationsToCwmavenRepository -x test
20+
./gradlew publishAllPublicationsToCwmavenRepository -x test
1921

2022

core/src/main/java/org/bouncycastle/crypto/threshold/Polynomial.java

Lines changed: 287 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.bouncycastle.crypto.threshold;
2+
3+
import org.bouncycastle.util.Encodable;
4+
5+
public interface SecretShare
6+
extends Encodable
7+
{
8+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.bouncycastle.crypto.threshold;
2+
3+
import java.io.IOException;
4+
5+
/**
6+
* Secret sharing (also called secret splitting) refers to methods for distributing a secret among a group.
7+
* In this process, no individual holds any intelligible information about the secret.
8+
* However, when a sufficient number of individuals combine their 'shares', the secret can be reconstructed.
9+
*/
10+
public interface SecretSplitter
11+
{
12+
/**
13+
* Creates secret shares. The secret will be divided into shares, where the secret has a length of L bytes.
14+
* @param m A threshold number of shares
15+
* @param n Total number of shares
16+
* @return An array of {@code byte[][]} representing the generated secret shares for m users with l bytes each.
17+
*/
18+
SplitSecret split(int m, int n);
19+
20+
/**
21+
* Creates secret shares from a given secret share. The secret will be divided into shares, where the secret has a length of L bytes.
22+
* @param m A threshold number of shares
23+
* @param n Total number of shares
24+
* @return An array of {@code byte[][]} representing the generated secret shares for m users with l bytes each.
25+
*/
26+
SplitSecret splitAround(SecretShare s, int m, int n)
27+
throws IOException;
28+
29+
/**
30+
* Creates secret shares from a given secret. The secret will be divided into shares, where the secret has a length of L bytes.
31+
* @param m A threshold number of shares
32+
* @param n Total number of shares
33+
* @return An array of {@code byte[][]} representing the generated secret shares for m users with l bytes each.
34+
*/
35+
SplitSecret resplit(byte[] secret, int m, int n);
36+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package org.bouncycastle.crypto.threshold;
2+
3+
import java.io.IOException;
4+
import java.security.SecureRandom;
5+
6+
import org.bouncycastle.util.Arrays;
7+
8+
9+
public class ShamirSecretSplitter
10+
implements SecretSplitter
11+
{
12+
public enum Algorithm
13+
{
14+
AES,
15+
RSA
16+
}
17+
18+
public enum Mode
19+
{
20+
Native,
21+
Table
22+
}
23+
24+
private final Polynomial poly;
25+
/**
26+
* Length of the secret
27+
*/
28+
protected int l;
29+
30+
protected SecureRandom random;
31+
32+
public ShamirSecretSplitter(Algorithm algorithm, Mode mode, int l, SecureRandom random)
33+
{
34+
if (l < 0 || l > 65534)
35+
{
36+
throw new IllegalArgumentException("Invalid input: l ranges from 0 to 65534 (2^16-2) bytes.");
37+
}
38+
39+
poly = Polynomial.newInstance(algorithm, mode);
40+
this.l = l;
41+
this.random = random;
42+
}
43+
44+
45+
public ShamirSplitSecret split(int m, int n)
46+
{
47+
byte[][] p = initP(m, n);
48+
byte[][] sr = new byte[m][l];
49+
ShamirSplitSecretShare[] secretShares = new ShamirSplitSecretShare[l];
50+
int i;
51+
for (i = 0; i < m; i++)
52+
{
53+
random.nextBytes(sr[i]);
54+
}
55+
for (i = 0; i < p.length; i++)
56+
{
57+
secretShares[i] = new ShamirSplitSecretShare(poly.gfVecMul(p[i], sr), i + 1);
58+
}
59+
return new ShamirSplitSecret(poly, secretShares);
60+
}
61+
62+
@Override
63+
public ShamirSplitSecret splitAround(SecretShare s, int m, int n)
64+
throws IOException
65+
{
66+
byte[][] p = initP(m, n);
67+
byte[][] sr = new byte[m][l];
68+
ShamirSplitSecretShare[] secretShares = new ShamirSplitSecretShare[l];
69+
byte[] ss0 = s.getEncoded();
70+
secretShares[0] = new ShamirSplitSecretShare(ss0, 1);
71+
int i, j;
72+
byte tmp;
73+
for (i = 0; i < m; i++)
74+
{
75+
random.nextBytes(sr[i]);
76+
}
77+
for (i = 0; i < l; i++)
78+
{
79+
tmp = sr[1][i];
80+
for (j = 2; j < m; j++)
81+
{
82+
tmp ^= sr[j][i];
83+
}
84+
sr[0][i] = (byte)(tmp ^ ss0[i]);
85+
}
86+
for (i = 1; i < p.length; i++)
87+
{
88+
secretShares[i] = new ShamirSplitSecretShare(poly.gfVecMul(p[i], sr), i + 1);
89+
}
90+
91+
return new ShamirSplitSecret(poly, secretShares);
92+
}
93+
94+
@Override
95+
public ShamirSplitSecret resplit(byte[] secret, int m, int n)
96+
{
97+
byte[][] p = initP(m, n);
98+
byte[][] sr = new byte[m][l];
99+
ShamirSplitSecretShare[] secretShares = new ShamirSplitSecretShare[l];
100+
sr[0] = Arrays.clone(secret);
101+
int i;
102+
for (i = 1; i < m; i++)
103+
{
104+
random.nextBytes(sr[i]);
105+
}
106+
for (i = 0; i < p.length; i++)
107+
{
108+
secretShares[i] = new ShamirSplitSecretShare(poly.gfVecMul(p[i], sr), i + 1);
109+
}
110+
return new ShamirSplitSecret(poly, secretShares);
111+
}
112+
113+
private byte[][] initP(int m, int n)
114+
{
115+
if (m < 1 || m > 255)
116+
{
117+
throw new IllegalArgumentException("Invalid input: m must be less than 256 and positive.");
118+
}
119+
if (n < m || n > 255)
120+
{
121+
throw new IllegalArgumentException("Invalid input: n must be less than 256 and greater than or equal to n.");
122+
}
123+
byte[][] p = new byte[n][m];
124+
for (int i = 0; i < n; i++)
125+
{
126+
for (int j = 0; j < m; j++)
127+
{
128+
p[i][j] = poly.gfPow((byte)(i + 1), (byte)j);
129+
}
130+
}
131+
return p;
132+
}
133+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package org.bouncycastle.crypto.threshold;
2+
3+
import java.io.IOException;
4+
5+
public class ShamirSplitSecret
6+
implements SplitSecret
7+
{
8+
private final ShamirSplitSecretShare[] secretShares;
9+
private final Polynomial poly;
10+
11+
public ShamirSplitSecret(ShamirSecretSplitter.Algorithm algorithm, ShamirSecretSplitter.Mode mode, ShamirSplitSecretShare[] secretShares)
12+
{
13+
this.secretShares = secretShares;
14+
this.poly = Polynomial.newInstance(algorithm, mode);
15+
}
16+
17+
ShamirSplitSecret(Polynomial poly, ShamirSplitSecretShare[] secretShares)
18+
{
19+
this.secretShares = secretShares;
20+
this.poly = poly;
21+
}
22+
23+
public ShamirSplitSecretShare[] getSecretShares()
24+
{
25+
return secretShares;
26+
}
27+
28+
public ShamirSplitSecret multiple(int mul)
29+
throws IOException
30+
{
31+
byte[] ss;
32+
for (int i = 0; i < secretShares.length; ++i)
33+
{
34+
ss = secretShares[i].getEncoded();
35+
for (int j = 0; j < ss.length; ++j)
36+
{
37+
ss[j] = poly.gfMul(ss[j] & 0xFF, mul);
38+
}
39+
secretShares[i] = new ShamirSplitSecretShare(ss, i + 1);
40+
}
41+
return this;
42+
}
43+
44+
public ShamirSplitSecret divide(int div)
45+
throws IOException
46+
{
47+
byte[] ss;
48+
for (int i = 0; i < secretShares.length; ++i)
49+
{
50+
ss = secretShares[i].getEncoded();
51+
for (int j = 0; j < ss.length; ++j)
52+
{
53+
ss[j] = poly.gfDiv(ss[j] & 0xFF, div);
54+
}
55+
secretShares[i] = new ShamirSplitSecretShare(ss, i + 1);
56+
}
57+
return this;
58+
}
59+
60+
@Override
61+
public byte[] getSecret()
62+
throws IOException
63+
{
64+
int n = secretShares.length;
65+
byte[] r = new byte[n];
66+
byte tmp;
67+
byte[] products = new byte[n - 1];
68+
byte[][] splits = new byte[n][secretShares[0].getEncoded().length];
69+
for (int i = 0; i < n; i++)
70+
{
71+
splits[i] = secretShares[i].getEncoded();
72+
tmp = 0;
73+
for (int j = 0; j < n; j++)
74+
{
75+
if (j != i)
76+
{
77+
products[tmp++] = poly.gfDiv(secretShares[j].r, secretShares[i].r ^ secretShares[j].r);
78+
}
79+
}
80+
81+
tmp = 1;
82+
for (byte p : products)
83+
{
84+
tmp = poly.gfMul(tmp & 0xff, p & 0xff);
85+
}
86+
r[i] = tmp;
87+
}
88+
89+
return poly.gfVecMul(r, splits);
90+
}
91+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.bouncycastle.crypto.threshold;
2+
3+
import java.io.IOException;
4+
5+
import org.bouncycastle.util.Arrays;
6+
7+
public class ShamirSplitSecretShare
8+
implements SecretShare
9+
{
10+
private final byte[] secretShare;
11+
final int r; // index of secretShare
12+
13+
public ShamirSplitSecretShare(byte[] secretShare, int r)
14+
{
15+
this.secretShare = Arrays.clone(secretShare);
16+
this.r = r;
17+
}
18+
19+
public ShamirSplitSecretShare(byte[] secretShare)
20+
{
21+
this.secretShare = Arrays.clone(secretShare);
22+
this.r = 1;
23+
}
24+
25+
@Override
26+
public byte[] getEncoded()
27+
throws IOException
28+
{
29+
return Arrays.clone(secretShare);
30+
}
31+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.bouncycastle.crypto.threshold;
2+
3+
import java.io.IOException;
4+
5+
public interface SplitSecret
6+
{
7+
SecretShare[] getSecretShares();
8+
9+
/**
10+
* Recombines secret shares to reconstruct the original secret.
11+
*
12+
* @return A byte array containing the reconstructed secret.
13+
*/
14+
byte[] getSecret()
15+
throws IOException;
16+
}

0 commit comments

Comments
 (0)