diff options
author | Moxie Marlinspike <moxie@thoughtcrime.org> | 2014-11-24 12:54:30 -0800 |
---|---|---|
committer | Moxie Marlinspike <moxie@thoughtcrime.org> | 2014-11-24 12:54:30 -0800 |
commit | 60800e155612bea797eed93c67046a23d26054cc (patch) | |
tree | d88368c1c26162e27e790195133ca2b526597afe /src/main/java/org/whispersystems/libaxolotl/ecc/Curve25519.java |
Break out into separate repo.
Diffstat (limited to 'src/main/java/org/whispersystems/libaxolotl/ecc/Curve25519.java')
-rw-r--r-- | src/main/java/org/whispersystems/libaxolotl/ecc/Curve25519.java | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/main/java/org/whispersystems/libaxolotl/ecc/Curve25519.java b/src/main/java/org/whispersystems/libaxolotl/ecc/Curve25519.java new file mode 100644 index 00000000..685a4a11 --- /dev/null +++ b/src/main/java/org/whispersystems/libaxolotl/ecc/Curve25519.java @@ -0,0 +1,98 @@ +/** + * Copyright (C) 2013 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.libaxolotl.ecc; + +import org.whispersystems.libaxolotl.InvalidKeyException; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +public class Curve25519 { + + static { + System.loadLibrary("curve25519"); + + try { + random = SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + throw new AssertionError(e); + } + } + + private static final SecureRandom random; + + private static native byte[] calculateAgreement(byte[] ourPrivate, byte[] theirPublic); + private static native byte[] generatePublicKey(byte[] privateKey); + private static native byte[] generatePrivateKey(byte[] random); + + private static native byte[] calculateSignature(byte[] random, byte[] privateKey, byte[] message); + private static native boolean verifySignature(byte[] publicKey, byte[] message, byte[] signature); + + public static ECKeyPair generateKeyPair() { + byte[] privateKey = generatePrivateKey(); + byte[] publicKey = generatePublicKey(privateKey); + + return new ECKeyPair(new DjbECPublicKey(publicKey), new DjbECPrivateKey(privateKey)); + } + + static byte[] calculateAgreement(ECPublicKey publicKey, ECPrivateKey privateKey) { + return calculateAgreement(((DjbECPrivateKey)privateKey).getPrivateKey(), + ((DjbECPublicKey)publicKey).getPublicKey()); + } + + static byte[] calculateSignature(ECPrivateKey privateKey, byte[] message) { + byte[] random = getRandom(64); + return calculateSignature(random, ((DjbECPrivateKey)privateKey).getPrivateKey(), message); + } + + static boolean verifySignature(ECPublicKey publicKey, byte[] message, byte[] signature) { + return verifySignature(((DjbECPublicKey)publicKey).getPublicKey(), message, signature); + } + + static ECPublicKey decodePoint(byte[] encoded, int offset) + throws InvalidKeyException + { + int type = encoded[offset] & 0xFF; + byte[] keyBytes = new byte[32]; + System.arraycopy(encoded, offset+1, keyBytes, 0, keyBytes.length); + + if (type != Curve.DJB_TYPE) { + throw new InvalidKeyException("Bad key type: " + type); + } + + return new DjbECPublicKey(keyBytes); + } + + private static byte[] generatePrivateKey() { + byte[] privateKey = new byte[32]; + random.nextBytes(privateKey); + + return generatePrivateKey(privateKey); + } + + private static byte[] getRandom(int size) { + try { + byte[] random = new byte[size]; + SecureRandom.getInstance("SHA1PRNG").nextBytes(random); + + return random; + } catch (NoSuchAlgorithmException e) { + throw new AssertionError(e); + } + } + +} |