/** * GenerateKey generates a public/private key pair using randomness from rand. * * @param publicKey empty byte array size 32 * @param privateKey random byte array size 64 */ public static void generateKey(byte[] publicKey, byte[] privateKey) throws NoSuchAlgorithmException { MessageDigest h = MessageDigest.getInstance("SHA-512"); byte[] digest = h.digest(Arrays.copyOfRange(privateKey, 0, 32)); digest[0] &= 248; digest[31] &= 127; digest[31] |= 64; ge_p3 A = new ge_p3(); ge_scalarmult_base(A, digest.clone()); ge_p3_tobytes(publicKey, A); System.arraycopy(publicKey, 0, privateKey, 32, 32); }
static void select(ge_precomp t,int pos,byte b) { ge_precomp base[][] = (pos <= 7 ? ge_precomp_base_0_7.base : (pos <= 15 ? ge_precomp_base_8_15.base : (pos <= 23 ? ge_precomp_base_16_23.base : ge_precomp_base_24_31.base))); ge_precomp minust = new ge_precomp(); int bnegative = negative(b); int babs = b - (((-bnegative) & b) << 1); ge_precomp_0.ge_precomp_0(t); cmov(t,base[pos][0],equal((byte)babs,(byte)1)); cmov(t,base[pos][1],equal((byte)babs,(byte)2)); cmov(t,base[pos][2],equal((byte)babs,(byte)3)); cmov(t,base[pos][3],equal((byte)babs,(byte)4)); cmov(t,base[pos][4],equal((byte)babs,(byte)5)); cmov(t,base[pos][5],equal((byte)babs,(byte)6)); cmov(t,base[pos][6],equal((byte)babs,(byte)7)); cmov(t,base[pos][7],equal((byte)babs,(byte)8)); fe_copy.fe_copy(minust.yplusx,t.yminusx); fe_copy.fe_copy(minust.yminusx,t.yplusx); fe_neg.fe_neg(minust.xy2d,t.xy2d); cmov(t,minust,bnegative); }
ge_scalarmult_base(R, messageDigest);
public static int curve25519_sign(Sha512 sha512provider, byte[] signature_out, byte[] curve25519_privkey, byte[] msg, int msg_len, byte[] random) { ge_p3 ed_pubkey_point = new ge_p3(); /* Ed25519 pubkey point */ byte[] ed_pubkey = new byte[32]; /* Ed25519 encoded pubkey */ byte[] sigbuf = new byte[msg_len + 128]; /* working buffer */ byte sign_bit = 0; /* Convert the Curve25519 privkey to an Ed25519 public key */ ge_scalarmult_base.ge_scalarmult_base(ed_pubkey_point, curve25519_privkey); ge_p3_tobytes.ge_p3_tobytes(ed_pubkey, ed_pubkey_point); sign_bit = (byte)(ed_pubkey[31] & 0x80); /* Perform an Ed25519 signature with explicit private key */ sign_modified.crypto_sign_modified(sha512provider, sigbuf, msg, msg_len, curve25519_privkey, ed_pubkey, random); System.arraycopy(sigbuf, 0, signature_out, 0, 64); /* Encode the sign bit into signature (in unused high bit of S) */ signature_out[63] &= 0x7F; /* bit should be zero already, but just in case */ signature_out[63] |= sign_bit; return 0; }
ge_scalarmult_base.ge_scalarmult_base(R,nonce); ge_p3_tobytes.ge_p3_tobytes(sm,R);
public static void curve25519_keygen(byte[] curve25519_pubkey_out, byte[] curve25519_privkey_in) { ge_p3 ed = new ge_p3(); /* Ed25519 pubkey point */ int[] ed_y_plus_one = new int[10]; int[] one_minus_ed_y = new int[10]; int[] inv_one_minus_ed_y = new int[10]; int[] mont_x = new int[10]; /* Perform a fixed-base multiplication of the Edwards base point, (which is efficient due to precalculated tables), then convert to the Curve25519 montgomery-format public key. In particular, convert Curve25519's "montgomery" x-coordinate into an Ed25519 "edwards" y-coordinate: mont_x = (ed_y + 1) / (1 - ed_y) with projective coordinates: mont_x = (ed_y + ed_z) / (ed_z - ed_y) NOTE: ed_y=1 is converted to mont_x=0 since fe_invert is mod-exp */ ge_scalarmult_base.ge_scalarmult_base(ed, curve25519_privkey_in); fe_add.fe_add(ed_y_plus_one, ed.Y, ed.Z); fe_sub.fe_sub(one_minus_ed_y, ed.Z, ed.Y); fe_invert.fe_invert(inv_one_minus_ed_y, one_minus_ed_y); fe_mul.fe_mul(mont_x, ed_y_plus_one, inv_one_minus_ed_y); fe_tobytes.fe_tobytes(curve25519_pubkey_out, mont_x); }