Skip to content

Commit 3c68c45

Browse files
authored
Merge pull request #3 from vault12/integration-test
add integration test to ShamirCore tests on native platforms
2 parents 3f2683e + 0d523b4 commit 3c68c45

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

android/src/test/java/com/vault12/plugins/shamir/ShamirCoreUnitTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,71 @@
33

44
import static org.junit.Assert.assertArrayEquals;
55
import static org.junit.Assert.assertEquals;
6+
import static org.junit.Assert.assertFalse;
67
import static org.junit.Assert.assertNotEquals;
78
import static org.junit.Assert.fail;
89

910
import org.junit.Test;
1011

1112
import java.nio.charset.StandardCharsets;
1213
import java.security.SecureRandom;
14+
import java.util.ArrayList;
1315
import java.util.Arrays;
16+
import java.util.Collections;
1417
import java.util.HashMap;
18+
import java.util.List;
1519
import java.util.Map;
1620

1721
public class ShamirCoreUnitTest {
1822

23+
@Test
24+
public void integration() throws SimpleException {
25+
final SecureRandom random = new SecureRandom();
26+
for (int i = 0; i < 100; i++) {
27+
// generate a random secret
28+
int length = random.nextInt(9001) + 1000; // 1000..10000
29+
byte[] secretBytes = new byte[length];
30+
random.nextBytes(secretBytes);
31+
// choose totalShards ∈ [2..10] and threshold ∈ [2..totalShards]
32+
short totalShards = (short) (random.nextInt(9) + 2);
33+
short threshold = (short) (random.nextInt(totalShards - 1) + 2);
34+
// split into shards
35+
Map<Short, byte[]> shards = ShamirCore.split(secretBytes, totalShards, threshold, null);
36+
37+
for (int j = 0; j < 10; j++) {
38+
// incorrect restore check
39+
if (threshold > 2) {
40+
// pick a random subset of shards not enough to restore (size < threshold)
41+
int notEnoughToRestoreCount = random.nextInt(threshold - 2) + 2;
42+
List<Short> keys = new ArrayList<>(shards.keySet());
43+
Collections.shuffle(keys);
44+
List<Short> notEnoughKeys = keys.subList(0, notEnoughToRestoreCount);
45+
Map<Short, byte[]> shardsNotEnough = new HashMap<>();
46+
for (Short k : notEnoughKeys) {
47+
shardsNotEnough.put(k, shards.get(k));
48+
}
49+
// restore and verify
50+
byte[] badRestored = ShamirCore.restore(shardsNotEnough, null);
51+
assertFalse("Incorrectly restored data matched original", Arrays.equals(secretBytes, badRestored));
52+
}
53+
54+
// correct restore check
55+
// pick a random subset of shards to restore (size ∈ [threshold..totalShards])
56+
int enoughToRestoreCount = random.nextInt(totalShards - threshold + 1) + threshold;
57+
List<Short> keysForCorrect = new ArrayList<>(shards.keySet());
58+
Collections.shuffle(keysForCorrect);
59+
List<Short> enoughKeys = keysForCorrect.subList(0, enoughToRestoreCount);
60+
Map<Short, byte[]> shardsEnough = new HashMap<>();
61+
for (Short k : enoughKeys) {
62+
shardsEnough.put(k, shards.get(k));
63+
}
64+
// restore and verify
65+
byte[] goodRestored = ShamirCore.restore(shardsEnough, null);
66+
assertArrayEquals("Correctly restored data does not match original", secretBytes, goodRestored);
67+
}
68+
}
69+
}
70+
1971
@Test
2072
public void wrongShards() {
2173

ios/Tests/ShamirPluginTests/ShamirCoreTests.swift

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,44 @@ import XCTest
33
@testable import ShamirPlugin
44

55
class ShamirCoreTests: XCTestCase {
6-
6+
7+
func testIntegration() throws {
8+
for _ in 1...100 {
9+
// generate a random secret
10+
let length = Int.random(in: 1000...10000)
11+
var secureBytes = [UInt8](repeating: 0, count: length)
12+
let status = SecRandomCopyBytes(kSecRandomDefault, length, &secureBytes)
13+
if status != errSecSuccess { throw SimpleError("ShamirCoreTests: RNG failed") }
14+
let secretData = Data(secureBytes)
15+
// choose totalShards ∈ [2..10] and threshold ∈ [2..totalShards]
16+
let totalShards = UInt8.random(in: 2...10)
17+
let threshold = UInt8.random(in: 2...totalShards)
18+
// split into shards
19+
let shards = try ShamirCore.split(totalShards: UInt8(totalShards), threshold: UInt8(threshold), secret: secretData)
20+
21+
for _ in 1...10 {
22+
// incorrect resore check (only if threshold > 2)
23+
if (threshold > 2) {
24+
// pick a random subset of shards not enough to restore (size < threshold)
25+
let shardsNotEnoughToRestoreCount = Int.random(in: Int(2)..<Int(threshold))
26+
let shardsNotEnoughToRestoreIndexes = Array(0..<totalShards).shuffled().prefix(shardsNotEnoughToRestoreCount)
27+
let shardsNotEnoughToRestore = shardsNotEnoughToRestoreIndexes.map { shards[Int($0)] }
28+
// restore and verify
29+
let incorrectRestoredData = try ShamirCore.restore(shards: shardsNotEnoughToRestore)
30+
XCTAssertNotEqual(incorrectRestoredData, secretData, "Incorrectly restored data does match original")
31+
}
32+
// correct restore check
33+
// pick a random subset of shards to restore (size ∈ [threshold..totalShards])
34+
let shardsEnoughToRestoreCount = Int.random(in: Int(threshold)...Int(totalShards))
35+
let shardsEnoughToRestoreIndexes = Array(0..<totalShards).shuffled().prefix(shardsEnoughToRestoreCount)
36+
let shardsEnoughToRestore = shardsEnoughToRestoreIndexes.map { shards[Int($0)] }
37+
// restore and verify
38+
let correctRestoredData = try ShamirCore.restore(shards: shardsEnoughToRestore)
39+
XCTAssertEqual(correctRestoredData, secretData, "Correctly restored data does not match original")
40+
}
41+
}
42+
}
43+
744
// Testing restricted parameter ranges when creating ShamirSecretSharing
845
func testWrongShards() {
946
XCTAssertThrowsError( try { // T too low

0 commit comments

Comments
 (0)