Coba sedikit memahami Ed25519 itu gimana, daftar lengkap teori di str4d/ed25519-java/Literature/, masih pengen penulis cerna dulu, heuheu.

Sementara, biar pembaca bisa ngoprek. Sila pembaca mengunduh berkas eddsa-0.2.0.jar, salin kode sumber berikut ke dalam editor kode sumber kesukaan anda, simpan berkas sesuai nama yang tertera di awal baris.

Pembangkitan pasangan kunci publik dan kunci private

//berkas KeyGenerasi.java
import java.security.KeyPair;
import java.security.SecureRandom;
import java.util.Base64;
import javax.xml.bind.DatatypeConverter;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.Utils;
import net.i2p.crypto.eddsa.math.Curve;
import net.i2p.crypto.eddsa.math.Field;
import net.i2p.crypto.eddsa.math.ed25519.Ed25519LittleEndianEncoding;
import net.i2p.crypto.eddsa.math.ed25519.Ed25519ScalarOps;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;

public class KeyGenerasi {

    public static void main(String[] args) {
        Field ed25519field = new Field(
                256, // b
                DatatypeConverter.parseHexBinary("edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"), // q
                new Ed25519LittleEndianEncoding());

        Curve ed25519curve = new Curve(ed25519field,
                DatatypeConverter.parseHexBinary("a3785913ca4deb75abd841414d0a700098e879777940c78c73fe6f2bee6c0352"), // d
                ed25519field.fromByteArray(Utils.hexToBytes("b0a00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b"))); // I

        EdDSANamedCurveSpec params = new EdDSANamedCurveSpec(
                "Ed25519",
                ed25519curve,
                "SHA-512", // H
                new Ed25519ScalarOps(), // l
                ed25519curve.createPoint( // B
                        DatatypeConverter.parseHexBinary("5866666666666666666666666666666666666666666666666666666666666666"),
                        true)); // Precompute tables for B
        SecureRandom random = new SecureRandom();
        byte[] seed = new byte[params.getCurve().getField().getb() / 8];
        random.nextBytes(seed);

        EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(seed, params);
        EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(privKey.getA(), params);

        KeyPair keyPair = new KeyPair(new EdDSAPublicKey(pubKey), new EdDSAPrivateKey(privKey));
        EdDSAPrivateKey priv = (EdDSAPrivateKey) keyPair.getPrivate();
        EdDSAPublicKey pub = (EdDSAPublicKey) keyPair.getPublic();
        System.out.println("public key: " + Base64.getEncoder().encodeToString(pub.getEncoded()));
        System.out.println("privat key: " + Base64.getEncoder().encodeToString(priv.getEncoded()));
    }
}

luaran

Proses pembuatan dan verifikasi tanda tangan digital

//berkas Ed25519SchnorrSignature.java
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SignatureException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.math.Curve;
import net.i2p.crypto.eddsa.math.GroupElement;
import net.i2p.crypto.eddsa.math.ScalarOps;

public class Ed25519SchnorrSignature {

    public static void main(String[] args) throws Exception {
        byte[] message = ("Content-Type: text/plain; charset=UTF-8\r\n"
                + "Content-Transfer-Encoding: 7bit\r\n\r\n"
                + "Halo Dunia").getBytes(StandardCharsets.UTF_8);
        System.out.println("\r\n--awal pesan--\r\n"+new String(message)+"\r\n--akhir pesan--\r\n");
        //===TANDA TANGAN===//
        EdDSAPrivateKey privKey = new EdDSAPrivateKey(
                new PKCS8EncodedKeySpec(
                        Base64.getDecoder().decode("MC4CAQAwBQYDK2VwBCIEIBNXDO0XvnMXzJHqourNV5TuoC4VTqhHPaeRyQUUO2vD")));

        // Instantiate the digest from the key parameters
        MessageDigest digest = MessageDigest.getInstance(privKey.getParams().getHashAlgorithm());
        // Preparing for hash
        // r = H(h_b,...,h_2b-1,M)
        int b = privKey.getParams().getCurve().getField().getb();
        digest.update(privKey.getH(), b / 8, b / 4 - b / 8);
        int offset = 0;
        int length = message.length;
        Curve curve = privKey.getParams().getCurve();
        ScalarOps sc = privKey.getParams().getScalarOps();
        byte[] a = privKey.geta();
        // r = H(h_b,...,h_2b-1,M)
        digest.update(message, offset, length);
        byte[] r = digest.digest();
        // r mod l
        // Reduces r from 64 bytes to 32 bytes
        r = sc.reduce(r);
        // R = rB
        GroupElement R = privKey.getParams().getB().scalarMultiply(r);
        byte[] Rbyte = R.toByteArray();
        // S = (r + H(Rbar,Abar,M)*a) mod l
        digest.update(Rbyte);
        digest.update(privKey.getAbyte());
        digest.update(message, offset, length);
        byte[] h = digest.digest();
        h = sc.reduce(h);
        byte[] S = sc.multiplyAndAdd(h, a, r);
        // R+S
        int be = curve.getField().getb();
        ByteBuffer out = ByteBuffer.allocate(be / 4);
        out.put(Rbyte).put(S);
        byte[] sigBytes = out.array();
        System.out.println("sigBytes: " + Arrays.toString(sigBytes));
        //===TANDA TANGAN===//
        //===VERIFIKASI===//
        EdDSAPublicKey pub = new EdDSAPublicKey(
                new X509EncodedKeySpec(
                        Base64.getDecoder().decode("MCowBQYDK2VwAyEADMLkg3vwS0OCh0dtpJDQiDkKFYCrIkFBI20Gc8cDXuM=")));

        Curve curva = pub.getParams().getCurve();
        int beh = curva.getField().getb();
        if (sigBytes.length != beh / 4) {
            throw new SignatureException("signature length is wrong");
        }
        digest.reset();
        // R is first b/8 bytes of sigBytes, S is second b/8 bytes
        digest.update(sigBytes, 0, beh / 8);
        digest.update(pub.getAbyte());
        // h = H(Rbar,Abar,M)
        digest.update(message, offset, length);
        byte[] he = digest.digest();
        // h mod l
        he = pub.getParams().getScalarOps().reduce(he);
        byte[] Sbyte = Arrays.copyOfRange(sigBytes, beh / 8, beh / 4);
        // R = SB - H(Rbar,Abar,M)A
        GroupElement Re = pub.getParams().getB().doubleScalarMultiplyVariableTime(
                pub.getNegativeA(), he, Sbyte);
        // Variable time. This should be okay, because there are no secret
        // values used anywhere in verification.
        byte[] Rcalc = Re.toByteArray();
        System.out.println("\r\nRcalc: " + Arrays.toString(Rcalc));
        boolean hasil = true;
        for (int i = 0; i < Rcalc.length; i++) {
            if (Rcalc[i] != sigBytes[i]) {
                hasil = false;
            }
        }
        System.out.println("\r\nhasil: " + hasil);
        //===VERIFIKASI===//
    }
}

luaran

Reactions:

You Might Also Like:

Berikan Komentar Sembunyikan Komentar

Hello, how may we help you? Just send us a message now to get assistance.

Facebook Messenger ×