ShamirSS is a platform-independent Java 17 CLI implementing Shamir’s (k, n) secret-sharing scheme. It can split any binary secret into N JSON shares and re-assemble it with any K of them. Two core tools are provided:
GenerateParts—Splits secrets intoNdistinct JSON shares. The secret can later be reconstructed from any K of them, thanks to Lagrange interpolation over GF(257).CryptFile— encrypts or decrypts any file using AES-256, where the encryption key is derived from the reconstructed secret using SHA-256.
The project was developed as part of the 632-2Mathematics continuous assessment (2023) at HES-SO Valais-Wallis, and focuses on modular arithmetic, applied cryptography, and CLI-based software design in Java.
In many situations, especially in cryptography and secure systems, it's risky to store a secret in a single place or entrust it to a single person. Shamir's Secret Sharing provides a way to divide a secret (e.g., a password, key, or private data) into multiple parts (shares), such that only a chosen number of those parts (threshold K out of N) are needed to reconstruct it. This enables secure collaboration, backup, or distribution of sensitive data.
This project includes two Java 17 command-line tools:
GenerateParts: generates n shares of a secret with a threshold t using Shamir's (k, n) secret sharing.CryptFile: uses shares to AES-encrypt and decrypt files securely.
The secret is a randomly generated byte array. Shares are stored as JSON files. Files can only be encrypted or decrypted with the threshold number of correct shares.
| Type | Name | Version |
|---|---|---|
| Language | Java | 17 |
| Build Tool | Maven | 3.x |
| CLI Library | Picocli (command line) | 4.7.4 |
| JSON | Gson | 2.10.1 |
| Encryption | Javax.crypto | AES |
| Testing | JUnit | 5.x |
- Understand modular arithmetic over finite fields (GF(257))
- Implement Shamir's (k,n) threshold scheme
- Apply Lagrange interpolation in a discrete field
- Practice secure file encryption and secret reconstruction
- Build CLI tools with clean UX (picocli)
- Use Git and Maven in a collaborative project setup
- Modular arithmetic and Lagrange interpolation over GF(257)
- Shamir's secret sharing (generation + reconstruction)
- AES encryption/decryption with share-based key retrieval
- Command-line interface using Picocli
- JSON-based persistent share format
- Environment variable
SHAMIRused as default share directory - Java Maven project with modular code
- ✅ Modular decomposition via OOP
- ✅ CLI abstraction through interfaces
- ✅ Mathematical modeling (field, polynomial, etc.)
- Errors are surfaced to CLI with error messages
- Invalid threshold or incompatible shares are validated before computation
- Missing/invalid input args are handled via Picocli error flow
ch.hesso.s3.math.*– finite field arithmetic, modular operations, inverse, and Lagrange interpolation logicch.hesso.s3.storage.*– reading and writing of share files in JSON format, using Gson for serialization and deserializationGenerateParts.java– CLI app to split a secretCryptFile.java– CLI app to encrypt/decrypt using shares
- Javadoc auto-generated
- Two UML diagrams are provided:
-
JUnit 5 used for:
- Modular arithmetic
- Lagrange interpolation
- Secret splitting and recombination
| Area | Status | Achievements / Functionality | Suggested Improvements |
|---|---|---|---|
| 🔢 Math Library (GF(257), Interpolation) | ✅ OK | Custom GF(257) arithmetic and Lagrange interpolation implemented | Refactor LagrangeInterpolation class to be abstract |
| 🔐 AES Encryption | ✅ OK | AES encryption with SHA-256 key derived from reconstructed secret | - |
| ⚙️ Share Generation & Decryption | ✅ OK | CLI tools for share generation, reconstruction, and decryption fully operational | - |
| 📦 Share Format | ✅ OK | JSON format is clean, consistent, and reusable | - |
| 📋 Input Validation | ✅ OK | CLI args and threshold logic handled with Picocli and validation checks | - |
| ❌ Error Handling | ✅ OK | Clear error messages via CLI, invalid inputs blocked | - |
| 🧪 Testing | ✅ OK | Unit tests cover mathematical logic and functionality | Create exhaustive test cases to make future maintenance easier |
| 🧩 Modularity / Structure | ✅ OK | Codebase organized by responsibility (math, CLI, storage) | - |
| 📝 Documentation | ✅ OK | Well-commented code and UML diagrams provided | - |
- Elias Borrajo
- Milena Lonfat
- Jonathan Bourquin
- Emilie Teodoro Do Nascimento
Project realized for the course 632-2 – Mathématiques (Projet contrôle continu)
Instructor: Jean-Luc Beuchat, HES-SO Valais-Wallis
Context: Java, modular arithmetic, secret sharing & cryptography in a math-focused coding project.
This project is the continuous assessment of the 3rd semester in IT at the HES-SO of Sierre.
- Students: Milena Lonfat, Emilie Teodoro Do Nascimento, Jonathan Bourquin and Elias Borrajo.
- Professor: Jean-Luc Beuchat
- Course: 632-2 Mathematics
Inputs: size of the secret, minimum number of shares to reconstruct the secret, total number of shares to generate
Outputs: the secret shares as well as any useful metadata for the reconstruction of the secret
Command line java tool to encrypt and decrypt a document (text file, Word document,...) or an executableInputs: parts of the secret generated by the first tool (and possible metadata), message and operation to perform
Output: encrypted or decrypted message depending on the chosen operation
- Designing a mathematical library in Java
- Develop software based on mathematical libraries
- Apply the knowledge acquired in the first year programming courses
- Create an environment variable called "SHAMIR" specific to the user, with the specific path on your machine to store the files. Store them into a folder for an easier use.
- Java version to use : openJDK 17.0.1
- In the command prompt use the command "cd" to go in the directory where your jar is located
- Then use: java -jar "name".jar and enjoy
- Create a new text file containing "java -jar "name".jar", then register it as a ".bat" file
- Keep the ".bat" file in the same location as your ".jar" app
- Create a shortcut of this ".bat" file, and put it on your desktop
- Run your ".bat" file from the directory or with the shortcut and enjoy !
The purpose of using this tool #1 is to generate shares containing codes in a file per person.
As input to this tool, you must give the number of shares you want to generate, the threshold of shares required to be able to reconstruct the secret with the codes, and a certain number of bytes which will be arbitrary between 16, 24 or 32.
The tool will generate the shares in the folder given via the environment variable when installing the app. For each user, send him only a file of type "User_X.json".
After sending all the files to all the users, you can delete the folder generated by the app. If you want to regenerate shares, make sure that the destination folder is already empty, that it does not contain any old undistributed shares.
Tool #2 encrypts or decrypts a file, using the shares generated by tool #1.
As input it takes :
-
The path where the shares containing the codes to be assembled of each user are located.
-
The path where the file to be encrypted & decrypted is located.
-
You must specify when using the application if you want to encrypt "-e" the file or decrypt "-d" it
Notes:
The paths must be correct. A simple mistake can make the tool not work properly.
Example :
C:\Users\myName\Desktop\ShamirsProjectStorage\User_1.json
The file to be encrypted can have any extension. .pdf .exe .pptx .txt, it does not matter.
Be careful! Any file can be encrypted using shares. But when decrypting the file, if you use a number of shares lower than the threshold you decided when generating the file, it will be impossible to decrypt the file. So it is absolutely necessary to encrypt a file with a number of shares that is at least equal to the threshold. (nparts >= threshold).
In addition, The same number of users is required to encrypt and decrypt the file. Example: ◦ A secret is generated with a single t=3 and a number of shares m =5 ◦ To encrypt, 3 out of 5 shares are needed to reconstruct the key (e.g. users 2, 3 and 4) ◦ To decrypt, one also needs 3 out of 5 shares, but not necessarily the same as for encryption (e.g. users 1, 4 and 5)
The mathematical library is in the "ModularArithmetic.java" class and "LagrangeInterpolation.java" The "ModularArithmetic.java" is the class that will allow us to perform calculations using operations (methods) such as: addition, subtraction, multiplication, division, power, greatest common divisor, isPrime and modular inverse Euclidean algorithm. As we can’t use the class bigInteger we had to initialized a modulo to 257 wich is the first prime number after 256.For the addition, subtraction, and multiplication we use the "Math.floorMod" that returns the floor modulus of the int argument.
We calculate : a * multiplicative inverse of b If the exponent is <= 0 an arithmeticException is throw because the power can not be <= 0 it should be minimum 1 else we use a loop and the multiplication we created to calculate it. If b = 0 it return a. Else it return the greatest common divisor of b and a modulo b. Calculate if a number is prime or not, returns ture if it’s a prime number, false if it’s not. Multiplicative inverse of A modulo M- Greatest common divisor GCD of value(a) & modulo(b). value >= modulo
- Coefficient of bezout set of Z : ax + by = g = gcd
- For modulo prime number & value(a) set of Z modulo base, replace in the equation a by m : mx + by = 1 --> return y = multiplicative inverse.
The « LagrangeInterpolation.java » used to perform a Lagrange interpolation on an array of points.
- Polynomial Interpolation: interpolation of a data set by the polynomial of lowest possible degree.
- Consider a set of k points (x0, y0), (x1, y1), …, (xk-1, yk-1) so that all values xi are distinct.
- There exists only one polynomial f(x) so that degree of f ≤ k - 1 and f(xi) = yi , ∀i ∈{ 0, 1, …, k - 1 }
Our method lagrange has two parameters Point[] f that is our "array of type Point" and "int n" that is our threshold.
With the call of our methods: division, multiplication, subtraction and addition create in our class modularArithmetic.java we can calculate it.
In a first for loop we compute the individual terms: term = f[i].y.
In a second for loop if j is different from i we calculate term= term * f[j].x / (f[i].x - f[j].x)
We calculate result += term and at the end return an int result.
| Works | Improvements | Errors | |
|---|---|---|---|
| Generation parts | OK | None | |
| Encrypt | OK | None | |
| Decrypt | OK | None | |
| Mathematic library | OK | Change the class lagrange interpolation to an abstract class | None |
| Picocli | OK | None | |
| Testing | OK | Create each use case possible & imaginable to help maintaining it easier | None |
| Other | - | create an User interface outside the console to be more user friendly with our customer | - |

