This repository has been archived by the owner on Apr 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactored into provider model for initial support of J2ME.
- Loading branch information
Showing
74 changed files
with
528 additions
and
215 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
apply plugin: 'java' | ||
|
||
sourceCompatibility = 1.2 |
83 changes: 83 additions & 0 deletions
83
common/src/main/java/org/whispersystems/curve25519/BaseJavaCurve25519Provider.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/** | ||
* Copyright (C) 2015 Open Whisper Systems | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.whispersystems.curve25519; | ||
|
||
import org.whispersystems.curve25519.java.Sha512; | ||
import org.whispersystems.curve25519.java.curve_sigs; | ||
import org.whispersystems.curve25519.java.scalarmult; | ||
|
||
abstract class BaseJavaCurve25519Provider implements Curve25519Provider { | ||
|
||
// @Override | ||
public boolean isNative() { | ||
return false; | ||
} | ||
|
||
// @Override | ||
public byte[] calculateAgreement(byte[] ourPrivate, byte[] theirPublic) { | ||
byte[] agreement = new byte[32]; | ||
scalarmult.crypto_scalarmult(agreement, ourPrivate, theirPublic); | ||
|
||
return agreement; | ||
} | ||
|
||
// @Override | ||
public byte[] generatePublicKey(byte[] privateKey) { | ||
byte[] publicKey = new byte[32]; | ||
curve_sigs.curve25519_keygen(publicKey, privateKey); | ||
|
||
return publicKey; | ||
} | ||
|
||
// @Override | ||
public byte[] generatePrivateKey() { | ||
byte[] random = getRandom(PRIVATE_KEY_LEN); | ||
return generatePrivateKey(random); | ||
} | ||
|
||
// @Override | ||
public byte[] generatePrivateKey(byte[] random) { | ||
byte[] privateKey = new byte[32]; | ||
|
||
System.arraycopy(random, 0, privateKey, 0, 32); | ||
|
||
privateKey[0] &= 248; | ||
privateKey[31] &= 127; | ||
privateKey[31] |= 64; | ||
|
||
return privateKey; | ||
} | ||
|
||
// @Override | ||
public byte[] calculateSignature(byte[] random, byte[] privateKey, byte[] message) { | ||
byte[] result = new byte[64]; | ||
|
||
if (curve_sigs.curve25519_sign(getSha512(), result, privateKey, message, message.length, random) != 0) { | ||
throw new IllegalArgumentException("Message exceeds max length!"); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
// @Override | ||
public boolean verifySignature(byte[] publicKey, byte[] message, byte[] signature) { | ||
return curve_sigs.curve25519_verify(getSha512(), signature, publicKey, message, message.length) == 0; | ||
} | ||
|
||
protected abstract Sha512 getSha512(); | ||
|
||
} |
155 changes: 155 additions & 0 deletions
155
common/src/main/java/org/whispersystems/curve25519/Curve25519.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/** | ||
* Copyright (C) 2015 Open Whisper Systems | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.whispersystems.curve25519; | ||
|
||
/** | ||
* A Curve25519 interface for generating keys, calculating agreements, creating signatures, | ||
* and verifying signatures. | ||
* | ||
* @author Moxie Marlinspike | ||
*/ | ||
public class Curve25519 { | ||
|
||
public static final String NATIVE = "native"; | ||
public static final String JAVA = "java"; | ||
public static final String J2ME = "j2me"; | ||
public static final String BEST = "best"; | ||
|
||
public static Curve25519 getInstance(String type) throws NoSuchProviderException { | ||
if (NATIVE.equals(type)) return new Curve25519(constructNativeProvider()); | ||
else if (JAVA.equals(type)) return new Curve25519(constructJavaProvider()); | ||
else if (J2ME.equals(type)) return new Curve25519(constructJ2meProvider()); | ||
else if (BEST.equals(type)) return new Curve25519(constructOpportunisticProvider()); | ||
else throw new NoSuchProviderException(type); | ||
} | ||
|
||
private final Curve25519Provider provider; | ||
|
||
private Curve25519(Curve25519Provider provider) { | ||
this.provider = provider; | ||
} | ||
|
||
|
||
// static { | ||
// try { | ||
// provider = new NativeCurve25519Provider(); | ||
// } catch (UnsatisfiedLinkError ule) { | ||
// provider = new JavaCurve25519Provider(); | ||
// } | ||
// } | ||
|
||
/** | ||
* {@link Curve25519} is backed by either a native (via JNI) | ||
* or pure-Java provider. By default it prefers the native provider, and falls back to the | ||
* pure-Java provider if the native library fails to load. | ||
* | ||
* @return true if backed by a native provider, false otherwise. | ||
*/ | ||
public boolean isNative() { | ||
return provider.isNative(); | ||
} | ||
|
||
/** | ||
* Generates a Curve25519 keypair. | ||
* | ||
* @return A randomly generated Curve25519 keypair. | ||
*/ | ||
public Curve25519KeyPair generateKeyPair() { | ||
byte[] privateKey = provider.generatePrivateKey(); | ||
byte[] publicKey = provider.generatePublicKey(privateKey); | ||
|
||
return new Curve25519KeyPair(publicKey, privateKey); | ||
} | ||
|
||
/** | ||
* Calculates an ECDH agreement. | ||
* | ||
* @param publicKey The Curve25519 (typically remote party's) public key. | ||
* @param privateKey The Curve25519 (typically yours) private key. | ||
* @return A 32-byte shared secret. | ||
*/ | ||
public byte[] calculateAgreement(byte[] publicKey, byte[] privateKey) { | ||
return provider.calculateAgreement(privateKey, publicKey); | ||
} | ||
|
||
/** | ||
* Calculates a Curve25519 signature. | ||
* | ||
* @param privateKey The private Curve25519 key to create the signature with. | ||
* @param message The message to sign. | ||
* @return A 64-byte signature. | ||
*/ | ||
public byte[] calculateSignature(byte[] privateKey, byte[] message) { | ||
byte[] random = provider.getRandom(64); | ||
return provider.calculateSignature(random, privateKey, message); | ||
} | ||
|
||
/** | ||
* Verify a Curve25519 signature. | ||
* | ||
* @param publicKey The Curve25519 public key the signature belongs to. | ||
* @param message The message that was signed. | ||
* @param signature The signature to verify. | ||
* @return true if valid, false if not. | ||
*/ | ||
public boolean verifySignature(byte[] publicKey, byte[] message, byte[] signature) { | ||
return provider.verifySignature(publicKey, message, signature); | ||
} | ||
|
||
// private byte[] generatePrivateKey() { | ||
// byte[] privateKey = new byte[32]; | ||
// random.nextBytes(privateKey); | ||
// | ||
// return provider.generatePrivateKey(privateKey); | ||
// } | ||
|
||
// private byte[] getRandom(SecureRandom secureRandom, int size) { | ||
// byte[] output = new byte[size]; | ||
// secureRandom.nextBytes(output); | ||
// | ||
// return output; | ||
// } | ||
|
||
private static Curve25519Provider constructNativeProvider() throws NoSuchProviderException { | ||
return constructClass("NativeCurve25519Provider"); | ||
} | ||
|
||
private static Curve25519Provider constructJavaProvider() throws NoSuchProviderException { | ||
return constructClass("JavaCurve25519Provider"); | ||
} | ||
|
||
private static Curve25519Provider constructJ2meProvider() throws NoSuchProviderException { | ||
return constructClass("J2meCurve25519Provider"); | ||
} | ||
|
||
private static Curve25519Provider constructOpportunisticProvider() throws NoSuchProviderException { | ||
return constructClass("OpportunisticCurve25519Provider"); | ||
} | ||
|
||
private static Curve25519Provider constructClass(String name) throws NoSuchProviderException { | ||
try { | ||
return (Curve25519Provider)Class.forName("org.whispersystems.curve25519." + name).newInstance(); | ||
} catch (InstantiationException e) { | ||
throw new NoSuchProviderException(e); | ||
} catch (IllegalAccessException e) { | ||
throw new NoSuchProviderException(e); | ||
} catch (ClassNotFoundException e) { | ||
throw new NoSuchProviderException(e); | ||
} | ||
} | ||
|
||
} |
File renamed without changes.
This file contains 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
11 changes: 11 additions & 0 deletions
11
common/src/main/java/org/whispersystems/curve25519/NoSuchProviderException.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.whispersystems.curve25519; | ||
|
||
public class NoSuchProviderException extends Exception { | ||
public NoSuchProviderException(Throwable e) { | ||
super(e); | ||
} | ||
|
||
public NoSuchProviderException(String type) { | ||
super(type); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
common/src/main/java/org/whispersystems/curve25519/java/Arrays.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package org.whispersystems.curve25519.java; | ||
|
||
public class Arrays { | ||
/** | ||
* Assigns the specified byte value to each element of the specified array | ||
* of bytes. | ||
* | ||
* @param a the array to be filled | ||
* @param val the value to be stored in all elements of the array | ||
*/ | ||
public static void fill(byte[] a, byte val) { | ||
for (int i = 0, len = a.length; i < len; i++) | ||
a[i] = val; | ||
} | ||
|
||
} |
7 changes: 7 additions & 0 deletions
7
common/src/main/java/org/whispersystems/curve25519/java/Sha512.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.whispersystems.curve25519.java; | ||
|
||
public interface Sha512 { | ||
|
||
public void calculateDigest(byte[] out, byte[] in, long length); | ||
|
||
} |
File renamed without changes.
File renamed without changes.
This file contains 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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains 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
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.