Created
February 6, 2021 18:54
-
-
Save hube12/e307153689390d3fc49495debf0aab67 to your computer and use it in GitHub Desktop.
Example of seed from curves
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package javaECC; | |
| import org.bouncycastle.crypto.generators.ElGamalParametersGenerator; | |
| import org.bouncycastle.crypto.params.DHParameters; | |
| import org.bouncycastle.crypto.params.ElGamalParameters; | |
| import org.bouncycastle.util.BigIntegers; | |
| import java.math.BigInteger; | |
| import java.security.SecureRandom; | |
| import java.util.Objects; | |
| public class App { | |
| // compile group: 'org.bouncycastle', name: 'bcprov-jdk15', version: '1.46' | |
| private static final BigInteger ONE = BigInteger.valueOf(1); | |
| private static final BigInteger TWO = BigInteger.valueOf(2); | |
| private static final SecureRandom SECURE_RANDOM = new SecureRandom(); | |
| public static Pair<BigInteger, BigInteger> getKeyPair() { | |
| /* | |
| * Returns the keys pair (private,public) of a random curve | |
| */ | |
| int strength = 1024; | |
| int certainty = 20; | |
| ElGamalParametersGenerator pGen = new ElGamalParametersGenerator(); | |
| pGen.init(strength, certainty, SECURE_RANDOM); | |
| // generate the Diffie hellman secure parameters | |
| ElGamalParameters egp = pGen.generateParameters(); | |
| // we use a limit of 64 bits instead of 0 as elgamal do | |
| DHParameters dhp = new DHParameters(egp.getP(), egp.getG(), null, 64); | |
| // choose a random private key (short) | |
| BigInteger x = calculatePrivate(dhp, SECURE_RANDOM); | |
| // derive the long public key | |
| BigInteger y = calculatePublic(dhp, x); | |
| return new Pair<>(x, y); | |
| } | |
| public static ElGamalParameters generateFixedDHParameters() { | |
| int strength = 1024; | |
| int certainty = 20; | |
| SecureRandom random = new SecureRandom(); | |
| ElGamalParametersGenerator pGen = new ElGamalParametersGenerator(); | |
| pGen.init(strength, certainty, random); | |
| // generate the Diffie hellman secure parameters | |
| return pGen.generateParameters(); | |
| } | |
| public static Pair<BigInteger, BigInteger> getDHKeyPair(ElGamalParameters egp) { | |
| /* | |
| * Returns the keys pair (private,public) of a fixed curve | |
| */ | |
| DHParameters dhp = new DHParameters(egp.getP(), egp.getG(), null, 64); | |
| // choose a random private key (short) | |
| BigInteger x = calculatePrivate(dhp, SECURE_RANDOM); | |
| // derive the long public key | |
| BigInteger y = calculatePublic(dhp, x); | |
| return new Pair<>(x, y); | |
| } | |
| public static Pair<BigInteger, BigInteger> getKeyPairFromPG(BigInteger P, BigInteger G) { | |
| /* | |
| * Returns the keys pair (private,public) of a fixed curve | |
| */ | |
| DHParameters dhp = new DHParameters(P, G, null, 64); | |
| // choose a random private key (short) | |
| BigInteger x = calculatePrivate(dhp, SECURE_RANDOM); | |
| // derive the long public key | |
| BigInteger y = calculatePublic(dhp, x); | |
| return new Pair<>(x, y); | |
| } | |
| private static BigInteger calculatePrivate(DHParameters dhParams, SecureRandom random) { | |
| BigInteger p = dhParams.getP(); | |
| int limit = dhParams.getL(); | |
| if (limit != 0) { | |
| return new BigInteger(limit, random).setBit(limit - 1); | |
| } | |
| BigInteger min = TWO; | |
| int m = dhParams.getM(); | |
| if (m != 0) { | |
| min = ONE.shiftLeft(m - 1); | |
| } | |
| BigInteger max = p.subtract(TWO); | |
| BigInteger q = dhParams.getQ(); | |
| if (q != null) { | |
| max = q.subtract(TWO); | |
| } | |
| return BigIntegers.createRandomInRange(min, max, random); | |
| } | |
| private static BigInteger calculatePublic(DHParameters dhParams, BigInteger x) { | |
| return dhParams.getG().modPow(x, dhParams.getP()); | |
| } | |
| public static BigInteger getPublicFromPrivate(DHParameters dhParameters, BigInteger x) { | |
| return calculatePublic(dhParameters, x); | |
| } | |
| public static BigInteger getPublicFromPrivate(BigInteger P, BigInteger G, BigInteger x) { | |
| return calculatePublic(new DHParameters(P, G, null, 64), x); | |
| } | |
| public static BigInteger getPublicFromPrivate(ElGamalParameters egp, BigInteger x) { | |
| return calculatePublic(new DHParameters(egp.getP(), egp.getG(), null, 64), x); | |
| } | |
| public static final class Pair<A, B> { | |
| private final A a; | |
| private final B b; | |
| public Pair(A a, B b) { | |
| this.a = a; | |
| this.b = b; | |
| } | |
| public Pair(Pair<? extends A, ? extends B> other) { | |
| this(other.a, other.b); | |
| } | |
| public A getFirst() { | |
| return this.a; | |
| } | |
| public B getSecond() { | |
| return this.b; | |
| } | |
| public int hashCode() { | |
| return Objects.hash(this.a, this.b); | |
| } | |
| public boolean equals(Object other) { | |
| if (other == this) { | |
| return true; | |
| } else if (other != null && other.getClass() == Pair.class) { | |
| Pair<?, ?> that = (Pair<?, ?>) other; | |
| return Objects.equals(this.a, that.a) && Objects.equals(this.b, that.b); | |
| } else { | |
| return false; | |
| } | |
| } | |
| public String toString() { | |
| return "(" + this.a + ", " + this.b + ")"; | |
| } | |
| } | |
| public static void showBasicUsage(){ | |
| Pair<BigInteger, BigInteger> keyPair = getKeyPair(); | |
| BigInteger externalSeed = keyPair.getFirst(); // short key of 64 bits | |
| BigInteger internalSeed = keyPair.getSecond(); // long key of 1024 bits | |
| System.out.printf("You could use seed : %s which would internally map to %s%n", internalSeed, externalSeed); | |
| System.out.printf("External seed of %d bits%n", externalSeed.bitLength()); | |
| System.out.printf("Internal seed of %d bits%n", internalSeed.bitLength()); | |
| } | |
| public static ElGamalParameters showRecommendUsage(){ | |
| // we recommend dumping an instance of egp inside the source code, it's totally secure to have it fixed, plus way faster | |
| ElGamalParameters egp = generateFixedDHParameters(); | |
| // first keys | |
| Pair<BigInteger, BigInteger> keyPair1 = getDHKeyPair(egp); | |
| BigInteger externalSeed = keyPair1.getFirst(); // short key of 64 bits | |
| BigInteger internalSeed = keyPair1.getSecond(); // long key of 1024 bits | |
| System.out.printf("You could use seed : %s which would internally map to %s%n", internalSeed, externalSeed); | |
| System.out.printf("External seed of %d bits%n", externalSeed.bitLength()); | |
| System.out.printf("Internal seed of %d bits%n", internalSeed.bitLength()); | |
| // second keys | |
| Pair<BigInteger, BigInteger> keyPair2 = getDHKeyPair(egp); | |
| externalSeed = keyPair2.getFirst(); // short key of 64 bits | |
| internalSeed = keyPair2.getSecond(); // long key of 1024 bits | |
| System.out.printf("You could use seed : %s which would internally map to %s%n", internalSeed, externalSeed); | |
| System.out.printf("External seed of %d bits%n", externalSeed.bitLength()); | |
| System.out.printf("Internal seed of %d bits%n", internalSeed.bitLength()); | |
| return egp; | |
| } | |
| public static Pair<BigInteger,BigInteger> showEasierExample(){ | |
| // we recommend dumping an instance of egp inside the source code, it's totally secure to have it fixed, plus way faster | |
| ElGamalParameters egp = generateFixedDHParameters(); | |
| BigInteger P = egp.getP(); | |
| BigInteger G = egp.getG(); | |
| Pair<BigInteger, BigInteger> keyPair = getKeyPairFromPG(P, G); | |
| BigInteger externalSeed = keyPair.getFirst(); // short key of 64 bits | |
| BigInteger internalSeed = keyPair.getSecond(); // long key of 1024 bits | |
| System.out.printf("You could use seed : %s which would internally map to %s%n", internalSeed, externalSeed); | |
| System.out.printf("External seed of %d bits%n", externalSeed.bitLength()); | |
| System.out.printf("Internal seed of %d bits%n", internalSeed.bitLength()); | |
| return new Pair<>(P,G); | |
| } | |
| public static void recoverPublicKeyFromPrivate(){ | |
| // generate parameters (done once before the mod release) | |
| ElGamalParameters egp = generateFixedDHParameters(); | |
| BigInteger P = egp.getP(); | |
| BigInteger G = egp.getG(); | |
| // generated when generating the world (or not-> inputted short seed) | |
| Pair<BigInteger, BigInteger> keyPair1 = getDHKeyPair(egp); | |
| BigInteger externalSeed = keyPair1.getFirst(); // short key of 64 bits | |
| BigInteger internalSeed = keyPair1.getSecond(); // long key of 1024 bits | |
| // recover the public long key from the private key (aka the user input short seed) | |
| BigInteger internalSeedFromExternalSeed1 = getPublicFromPrivate(egp,externalSeed); | |
| BigInteger internalSeedFromExternalSeed2 = getPublicFromPrivate(P,G,externalSeed); | |
| BigInteger internalSeedFromExternalSeed3 = getPublicFromPrivate(new DHParameters(P, G, null, 64),externalSeed); | |
| assert internalSeedFromExternalSeed1.equals(internalSeed); | |
| assert internalSeedFromExternalSeed2.equals(internalSeed); | |
| assert internalSeedFromExternalSeed3.equals(internalSeed); | |
| System.out.println("Passed"); | |
| } | |
| public static void main(String[] args) { | |
| showBasicUsage(); | |
| ElGamalParameters egp=showRecommendUsage(); | |
| System.out.printf("P,G=%s,%s%n", egp.getP(),egp.getG()); | |
| Pair<BigInteger,BigInteger> PG=showEasierExample(); | |
| System.out.printf("P,G=%s,%s%n", PG.getFirst(), PG.getSecond()); | |
| recoverPublicKeyFromPrivate(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment