public static void ge_tobytes(byte[] s,ge_p2 h) { int[] recip = new int[10]; int[] x = new int[10]; int[] y = new int[10]; fe_invert.fe_invert(recip,h.Z); fe_mul.fe_mul(x,h.X,recip); fe_mul.fe_mul(y,h.Y,recip); fe_tobytes.fe_tobytes(s,y); s[31] ^= fe_isnegative.fe_isnegative(x) << 7; }
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); }
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); }
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; }
public static void ge_p3_dbl(ge_p1p1 r,ge_p3 p) { ge_p2 q = new ge_p2(); ge_p3_to_p2.ge_p3_to_p2(q,p); ge_p2_dbl.ge_p2_dbl(r,q); }
public byte[] generatePublicKey(byte[] privateKey) { byte[] publicKey = new byte[32]; curve_sigs.curve25519_keygen(publicKey, privateKey); return publicKey; }
public static int fe_isnonzero(int[] f) { byte[] s = new byte[32]; fe_tobytes.fe_tobytes(s,f); return crypto_verify_32.crypto_verify_32(s,zero); }
public static int fe_isnegative(int[] f) { byte[] s = new byte[32]; fe_tobytes.fe_tobytes(s,f); return s[0] & 1; }
public byte[] calculateAgreement(byte[] ourPrivate, byte[] theirPublic) { byte[] agreement = new byte[32]; scalarmult.crypto_scalarmult(agreement, ourPrivate, theirPublic); return agreement; }
public boolean verifySignature(byte[] publicKey, byte[] message, byte[] signature) { return curve_sigs.curve25519_verify(sha512provider, signature, publicKey, message, message.length) == 0; }
public static void ge_p3_tobytes(byte[] s,ge_p3 h) { int[] recip = new int[10]; int[] x = new int[10]; int[] y = new int[10]; fe_invert.fe_invert(recip,h.Z); fe_mul.fe_mul(x,h.X,recip); fe_mul.fe_mul(y,h.Y,recip); fe_tobytes.fe_tobytes(s,y); s[31] ^= fe_isnegative.fe_isnegative(x) << 7; }
private static byte[] publicKey(byte[] privateKey) { byte[] publicKey = new byte[32]; curve_sigs.curve25519_keygen(publicKey, privateKey); return publicKey; }