From 2ed8d333d9b90cb34bef7e3262f4c054f6f91eda Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Tue, 24 Jun 2014 12:59:22 -0700 Subject: [PATCH] Add ed25519 --- libaxolotl/jni/Android.mk | 18 +- ...urve25519-donna-jni.c => curve25519-jni.c} | 38 +- libaxolotl/jni/ed25519/additions/compare.c | 44 + libaxolotl/jni/ed25519/additions/compare.h | 6 + libaxolotl/jni/ed25519/additions/curve_sigs.c | 97 + libaxolotl/jni/ed25519/additions/curve_sigs.h | 25 + libaxolotl/jni/ed25519/additions/sha512.c | 13 + libaxolotl/jni/ed25519/additions/sha512.h | 10 + .../jni/ed25519/additions/sign_modified.c | 40 + libaxolotl/jni/ed25519/api.h | 4 + libaxolotl/jni/ed25519/base.h | 1344 +++++++++++ libaxolotl/jni/ed25519/base2.h | 40 + libaxolotl/jni/ed25519/d.h | 1 + libaxolotl/jni/ed25519/d2.h | 1 + libaxolotl/jni/ed25519/fe.h | 56 + libaxolotl/jni/ed25519/fe_0.c | 19 + libaxolotl/jni/ed25519/fe_1.c | 19 + libaxolotl/jni/ed25519/fe_add.c | 57 + libaxolotl/jni/ed25519/fe_cmov.c | 63 + libaxolotl/jni/ed25519/fe_copy.c | 29 + libaxolotl/jni/ed25519/fe_frombytes.c | 73 + libaxolotl/jni/ed25519/fe_invert.c | 14 + libaxolotl/jni/ed25519/fe_isnegative.c | 16 + libaxolotl/jni/ed25519/fe_isnonzero.c | 19 + libaxolotl/jni/ed25519/fe_mul.c | 253 +++ libaxolotl/jni/ed25519/fe_neg.c | 45 + libaxolotl/jni/ed25519/fe_pow22523.c | 13 + libaxolotl/jni/ed25519/fe_sq.c | 149 ++ libaxolotl/jni/ed25519/fe_sq2.c | 160 ++ libaxolotl/jni/ed25519/fe_sub.c | 57 + libaxolotl/jni/ed25519/fe_tobytes.c | 119 + libaxolotl/jni/ed25519/ge.h | 95 + libaxolotl/jni/ed25519/ge_add.c | 11 + libaxolotl/jni/ed25519/ge_add.h | 97 + libaxolotl/jni/ed25519/ge_double_scalarmult.c | 96 + libaxolotl/jni/ed25519/ge_frombytes.c | 50 + libaxolotl/jni/ed25519/ge_madd.c | 11 + libaxolotl/jni/ed25519/ge_madd.h | 88 + libaxolotl/jni/ed25519/ge_msub.c | 11 + libaxolotl/jni/ed25519/ge_msub.h | 88 + libaxolotl/jni/ed25519/ge_p1p1_to_p2.c | 12 + libaxolotl/jni/ed25519/ge_p1p1_to_p3.c | 13 + libaxolotl/jni/ed25519/ge_p2_0.c | 8 + libaxolotl/jni/ed25519/ge_p2_dbl.c | 11 + libaxolotl/jni/ed25519/ge_p2_dbl.h | 73 + libaxolotl/jni/ed25519/ge_p3_0.c | 9 + libaxolotl/jni/ed25519/ge_p3_dbl.c | 12 + libaxolotl/jni/ed25519/ge_p3_to_cached.c | 17 + libaxolotl/jni/ed25519/ge_p3_to_p2.c | 12 + libaxolotl/jni/ed25519/ge_p3_tobytes.c | 14 + libaxolotl/jni/ed25519/ge_precomp_0.c | 8 + libaxolotl/jni/ed25519/ge_scalarmult_base.c | 105 + libaxolotl/jni/ed25519/ge_sub.c | 11 + libaxolotl/jni/ed25519/ge_sub.h | 97 + libaxolotl/jni/ed25519/ge_tobytes.c | 14 + libaxolotl/jni/ed25519/main/main.c | 41 + .../nacl_includes/crypto_hash_sha512.h | 23 + .../jni/ed25519/nacl_includes/crypto_int32.h | 6 + .../jni/ed25519/nacl_includes/crypto_int64.h | 6 + .../jni/ed25519/nacl_includes/crypto_sign.h | 16 + .../crypto_sign_edwards25519sha512batch.h | 33 + .../jni/ed25519/nacl_includes/crypto_uint32.h | 6 + .../jni/ed25519/nacl_includes/crypto_uint64.h | 6 + .../ed25519/nacl_includes/crypto_verify_32.h | 22 + libaxolotl/jni/ed25519/open.c | 48 + libaxolotl/jni/ed25519/pow22523.h | 160 ++ libaxolotl/jni/ed25519/pow225521.h | 160 ++ libaxolotl/jni/ed25519/sc.h | 15 + libaxolotl/jni/ed25519/sc_muladd.c | 368 +++ libaxolotl/jni/ed25519/sc_reduce.c | 275 +++ libaxolotl/jni/ed25519/sha512/LICENSE.txt | 20 + libaxolotl/jni/ed25519/sha512/md_helper.c | 346 +++ libaxolotl/jni/ed25519/sha512/sha2big.c | 247 +++ libaxolotl/jni/ed25519/sha512/sph_sha2.h | 370 +++ libaxolotl/jni/ed25519/sha512/sph_types.h | 1976 +++++++++++++++++ libaxolotl/jni/ed25519/sign.c | 41 + libaxolotl/jni/ed25519/sqrtm1.h | 1 + libaxolotl/libs/armeabi-v7a/libcurve25519.so | Bin 17532 -> 90172 bytes libaxolotl/libs/armeabi/libcurve25519.so | Bin 21624 -> 90168 bytes libaxolotl/libs/x86/libcurve25519.so | Bin 17488 -> 114752 bytes .../libaxolotl/ecc/Curve25519.java | 11 + 81 files changed, 7997 insertions(+), 5 deletions(-) rename libaxolotl/jni/{curve25519-donna-jni.c => curve25519-jni.c} (59%) create mode 100644 libaxolotl/jni/ed25519/additions/compare.c create mode 100644 libaxolotl/jni/ed25519/additions/compare.h create mode 100644 libaxolotl/jni/ed25519/additions/curve_sigs.c create mode 100644 libaxolotl/jni/ed25519/additions/curve_sigs.h create mode 100644 libaxolotl/jni/ed25519/additions/sha512.c create mode 100644 libaxolotl/jni/ed25519/additions/sha512.h create mode 100644 libaxolotl/jni/ed25519/additions/sign_modified.c create mode 100644 libaxolotl/jni/ed25519/api.h create mode 100644 libaxolotl/jni/ed25519/base.h create mode 100644 libaxolotl/jni/ed25519/base2.h create mode 100644 libaxolotl/jni/ed25519/d.h create mode 100644 libaxolotl/jni/ed25519/d2.h create mode 100644 libaxolotl/jni/ed25519/fe.h create mode 100644 libaxolotl/jni/ed25519/fe_0.c create mode 100644 libaxolotl/jni/ed25519/fe_1.c create mode 100644 libaxolotl/jni/ed25519/fe_add.c create mode 100644 libaxolotl/jni/ed25519/fe_cmov.c create mode 100644 libaxolotl/jni/ed25519/fe_copy.c create mode 100644 libaxolotl/jni/ed25519/fe_frombytes.c create mode 100644 libaxolotl/jni/ed25519/fe_invert.c create mode 100644 libaxolotl/jni/ed25519/fe_isnegative.c create mode 100644 libaxolotl/jni/ed25519/fe_isnonzero.c create mode 100644 libaxolotl/jni/ed25519/fe_mul.c create mode 100644 libaxolotl/jni/ed25519/fe_neg.c create mode 100644 libaxolotl/jni/ed25519/fe_pow22523.c create mode 100644 libaxolotl/jni/ed25519/fe_sq.c create mode 100644 libaxolotl/jni/ed25519/fe_sq2.c create mode 100644 libaxolotl/jni/ed25519/fe_sub.c create mode 100644 libaxolotl/jni/ed25519/fe_tobytes.c create mode 100644 libaxolotl/jni/ed25519/ge.h create mode 100644 libaxolotl/jni/ed25519/ge_add.c create mode 100644 libaxolotl/jni/ed25519/ge_add.h create mode 100644 libaxolotl/jni/ed25519/ge_double_scalarmult.c create mode 100644 libaxolotl/jni/ed25519/ge_frombytes.c create mode 100644 libaxolotl/jni/ed25519/ge_madd.c create mode 100644 libaxolotl/jni/ed25519/ge_madd.h create mode 100644 libaxolotl/jni/ed25519/ge_msub.c create mode 100644 libaxolotl/jni/ed25519/ge_msub.h create mode 100644 libaxolotl/jni/ed25519/ge_p1p1_to_p2.c create mode 100644 libaxolotl/jni/ed25519/ge_p1p1_to_p3.c create mode 100644 libaxolotl/jni/ed25519/ge_p2_0.c create mode 100644 libaxolotl/jni/ed25519/ge_p2_dbl.c create mode 100644 libaxolotl/jni/ed25519/ge_p2_dbl.h create mode 100644 libaxolotl/jni/ed25519/ge_p3_0.c create mode 100644 libaxolotl/jni/ed25519/ge_p3_dbl.c create mode 100644 libaxolotl/jni/ed25519/ge_p3_to_cached.c create mode 100644 libaxolotl/jni/ed25519/ge_p3_to_p2.c create mode 100644 libaxolotl/jni/ed25519/ge_p3_tobytes.c create mode 100644 libaxolotl/jni/ed25519/ge_precomp_0.c create mode 100644 libaxolotl/jni/ed25519/ge_scalarmult_base.c create mode 100644 libaxolotl/jni/ed25519/ge_sub.c create mode 100644 libaxolotl/jni/ed25519/ge_sub.h create mode 100644 libaxolotl/jni/ed25519/ge_tobytes.c create mode 100644 libaxolotl/jni/ed25519/main/main.c create mode 100644 libaxolotl/jni/ed25519/nacl_includes/crypto_hash_sha512.h create mode 100644 libaxolotl/jni/ed25519/nacl_includes/crypto_int32.h create mode 100644 libaxolotl/jni/ed25519/nacl_includes/crypto_int64.h create mode 100644 libaxolotl/jni/ed25519/nacl_includes/crypto_sign.h create mode 100644 libaxolotl/jni/ed25519/nacl_includes/crypto_sign_edwards25519sha512batch.h create mode 100644 libaxolotl/jni/ed25519/nacl_includes/crypto_uint32.h create mode 100644 libaxolotl/jni/ed25519/nacl_includes/crypto_uint64.h create mode 100644 libaxolotl/jni/ed25519/nacl_includes/crypto_verify_32.h create mode 100644 libaxolotl/jni/ed25519/open.c create mode 100644 libaxolotl/jni/ed25519/pow22523.h create mode 100644 libaxolotl/jni/ed25519/pow225521.h create mode 100644 libaxolotl/jni/ed25519/sc.h create mode 100644 libaxolotl/jni/ed25519/sc_muladd.c create mode 100644 libaxolotl/jni/ed25519/sc_reduce.c create mode 100644 libaxolotl/jni/ed25519/sha512/LICENSE.txt create mode 100644 libaxolotl/jni/ed25519/sha512/md_helper.c create mode 100644 libaxolotl/jni/ed25519/sha512/sha2big.c create mode 100644 libaxolotl/jni/ed25519/sha512/sph_sha2.h create mode 100644 libaxolotl/jni/ed25519/sha512/sph_types.h create mode 100644 libaxolotl/jni/ed25519/sign.c create mode 100644 libaxolotl/jni/ed25519/sqrtm1.h diff --git a/libaxolotl/jni/Android.mk b/libaxolotl/jni/Android.mk index 20211e82e..0baf53adb 100644 --- a/libaxolotl/jni/Android.mk +++ b/libaxolotl/jni/Android.mk @@ -9,9 +9,19 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) -LOCAL_MODULE := libcurve25519 -LOCAL_SRC_FILES := curve25519-donna-jni.c +LOCAL_MODULE := libcurve25519-ref10 +LOCAL_SRC_FILES := $(wildcard ed25519/*.c) $(wildcard ed25519/additions/*.c) ed25519/sha512/sha2big.c +LOCAL_C_INCLUDES := ed25519/nacl_includes ed25519/additions ed25519/sha512 ed25519 -LOCAL_STATIC_LIBRARIES := libcurve25519-donna +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libcurve25519 +LOCAL_SRC_FILES := curve25519-jni.c +LOCAL_C_INCLUDES := ed25519/additions + +LOCAL_STATIC_LIBRARIES := libcurve25519-donna libcurve25519-ref10 + +include $(BUILD_SHARED_LIBRARY) -include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/libaxolotl/jni/curve25519-donna-jni.c b/libaxolotl/jni/curve25519-jni.c similarity index 59% rename from libaxolotl/jni/curve25519-donna-jni.c rename to libaxolotl/jni/curve25519-jni.c index 71862ce22..305370ac6 100644 --- a/libaxolotl/jni/curve25519-donna-jni.c +++ b/libaxolotl/jni/curve25519-jni.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2013 Open Whisper Systems + * Copyright (C) 2013-2014 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 @@ -20,6 +20,7 @@ #include #include "curve25519-donna.h" +#include "curve_sigs.h" JNIEXPORT jbyteArray JNICALL Java_org_whispersystems_libaxolotl_ecc_Curve25519_generatePrivateKey (JNIEnv *env, jclass clazz, jbyteArray random, jboolean ephemeral) @@ -73,3 +74,38 @@ JNIEXPORT jbyteArray JNICALL Java_org_whispersystems_libaxolotl_ecc_Curve25519_c return sharedKey; } + +JNIEXPORT jbyteArray JNICALL Java_org_whispersystems_libaxolotl_ecc_Curve25519_calculateSignature + (JNIEnv *env, jclass clazz, jbyteArray privateKey, jbyteArray message) +{ + jbyteArray signature = (*env)->NewByteArray(env, 64); + uint8_t* signatureBytes = (uint8_t*)(*env)->GetByteArrayElements(env, signature, 0); + uint8_t* privateKeyBytes = (uint8_t*)(*env)->GetByteArrayElements(env, privateKey, 0); + uint8_t* messageBytes = (uint8_t*)(*env)->GetByteArrayElements(env, message, 0); + jsize messageLength = (*env)->GetArrayLength(env, message); + + curve25519_sign(signatureBytes, privateKeyBytes, messageBytes, messageLength); + + (*env)->ReleaseByteArrayElements(env, signature, signatureBytes, 0); + (*env)->ReleaseByteArrayElements(env, privateKey, privateKeyBytes, 0); + (*env)->ReleaseByteArrayElements(env, message, messageBytes, 0); + + return signature; +} + +JNIEXPORT jboolean JNICALL Java_org_whispersystems_libaxolotl_ecc_Curve25519_verifySignature + (JNIEnv *env, jclass clazz, jbyteArray publicKey, jbyteArray message, jbyteArray signature) +{ + uint8_t* signatureBytes = (uint8_t*)(*env)->GetByteArrayElements(env, signature, 0); + uint8_t* publicKeyBytes = (uint8_t*)(*env)->GetByteArrayElements(env, publicKey, 0); + uint8_t* messageBytes = (uint8_t*)(*env)->GetByteArrayElements(env, message, 0); + jsize messageLength = (*env)->GetArrayLength(env, message); + + jboolean result = (curve25519_verify(signatureBytes, publicKeyBytes, messageBytes, messageLength) == 0); + + (*env)->ReleaseByteArrayElements(env, signature, signatureBytes, 0); + (*env)->ReleaseByteArrayElements(env, publicKey, publicKeyBytes, 0); + (*env)->ReleaseByteArrayElements(env, message, messageBytes, 0); + + return result; +} diff --git a/libaxolotl/jni/ed25519/additions/compare.c b/libaxolotl/jni/ed25519/additions/compare.c new file mode 100644 index 000000000..8b1e31389 --- /dev/null +++ b/libaxolotl/jni/ed25519/additions/compare.c @@ -0,0 +1,44 @@ +#include +#include "compare.h" + +/* Const-time comparison from SUPERCOP, but here it's only used for + signature verification, so doesn't need to be const-time. But + copied the nacl version anyways. */ +int crypto_verify_32_ref(const unsigned char *x, const unsigned char *y) +{ + unsigned int differentbits = 0; +#define F(i) differentbits |= x[i] ^ y[i]; + F(0) + F(1) + F(2) + F(3) + F(4) + F(5) + F(6) + F(7) + F(8) + F(9) + F(10) + F(11) + F(12) + F(13) + F(14) + F(15) + F(16) + F(17) + F(18) + F(19) + F(20) + F(21) + F(22) + F(23) + F(24) + F(25) + F(26) + F(27) + F(28) + F(29) + F(30) + F(31) + return (1 & ((differentbits - 1) >> 8)) - 1; +} diff --git a/libaxolotl/jni/ed25519/additions/compare.h b/libaxolotl/jni/ed25519/additions/compare.h new file mode 100644 index 000000000..5a2fa910d --- /dev/null +++ b/libaxolotl/jni/ed25519/additions/compare.h @@ -0,0 +1,6 @@ +#ifndef __COMPARE_H__ +#define __COMPARE_H__ + +int crypto_verify_32_ref(const unsigned char *b1, const unsigned char *b2); + +#endif diff --git a/libaxolotl/jni/ed25519/additions/curve_sigs.c b/libaxolotl/jni/ed25519/additions/curve_sigs.c new file mode 100644 index 000000000..b002dc874 --- /dev/null +++ b/libaxolotl/jni/ed25519/additions/curve_sigs.c @@ -0,0 +1,97 @@ +#include +#include "ge.h" +#include "curve_sigs.h" +#include "crypto_sign.h" + +void curve25519_keygen(unsigned char* curve25519_pubkey_out, + unsigned char* curve25519_privkey_in) +{ + ge_p3 ed_pubkey_point; /* Ed25519 pubkey point */ + unsigned char ed_pubkey[32]; /* privkey followed by pubkey */ + fe ed_y, one, ed_y_plus_one, one_minus_ed_y, inv_one_minus_ed_y; + fe mont_x; + + /* 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) / (1 - ed_y) + */ + + ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey_in); + ge_p3_tobytes(ed_pubkey, &ed_pubkey_point); + ed_pubkey[31] = ed_pubkey[31] & 0x7F; /* Mask off sign bit */ + fe_frombytes(ed_y, ed_pubkey); + + fe_1(one); + fe_add(ed_y_plus_one, ed_y, one); + fe_sub(one_minus_ed_y, one, ed_y); + fe_invert(inv_one_minus_ed_y, one_minus_ed_y); + fe_mul(mont_x, ed_y_plus_one, inv_one_minus_ed_y); + fe_tobytes(curve25519_pubkey_out, mont_x); +} + +void curve25519_sign(unsigned char* signature_out, + unsigned char* curve25519_privkey, + unsigned char* msg, unsigned long msg_len) +{ + ge_p3 ed_pubkey_point; /* Ed25519 pubkey point */ + unsigned char ed_keypair[64]; /* privkey followed by pubkey */ + unsigned char sigbuf[msg_len + 64]; /* working buffer */ + unsigned long long sigbuf_out_len = 0; + unsigned char sign_bit = 0; + + /* Convert the Curve25519 privkey to an Ed25519 keypair */ + memmove(ed_keypair, curve25519_privkey, 32); + ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); + ge_p3_tobytes(ed_keypair + 32, &ed_pubkey_point); + sign_bit = ed_keypair[63] & 0x80; + + /* Perform an Ed25519 signature with explicit private key */ + crypto_sign_modified(sigbuf, &sigbuf_out_len, msg, msg_len, ed_keypair); + memmove(signature_out, sigbuf, 64); + + /* Encode the sign bit into signature (in unused high bit of S) */ + signature_out[63] |= sign_bit; +} + +int curve25519_verify(unsigned char* signature, + unsigned char* curve25519_pubkey, + unsigned char* msg, unsigned long msg_len) +{ + fe mont_x, mont_x_minus_one, mont_x_plus_one, inv_mont_x_plus_one; + fe one; + fe ed_y; + unsigned char ed_pubkey[32]; + unsigned long long some_retval; + unsigned char verifybuf[msg_len + 64]; /* working buffer */ + unsigned char verifybuf2[msg_len + 64]; /* working buffer #2 */ + + /* Convert the Curve25519 public key into an Ed25519 public key. In + particular, convert Curve25519's "montgomery" x-coordinate into an + Ed25519 "edwards" y-coordinate: + + ed_y = (mont_x - 1) / (mont_x + 1) + + Then move the sign bit into the pubkey from the signature. + */ + fe_frombytes(mont_x, curve25519_pubkey); + fe_1(one); + fe_sub(mont_x_minus_one, mont_x, one); + fe_add(mont_x_plus_one, mont_x, one); + fe_invert(inv_mont_x_plus_one, mont_x_plus_one); + fe_mul(ed_y, mont_x_minus_one, inv_mont_x_plus_one); + fe_tobytes(ed_pubkey, ed_y); + + /* Copy the sign bit, and remove it from signature */ + ed_pubkey[31] |= (signature[63] & 0x80); + signature[63] &= 0x7F; + + memmove(verifybuf, signature, 64); + memmove(verifybuf+64, msg, msg_len); + + /* Then perform a normal Ed25519 verification, return 0 on success */ + return crypto_sign_open(verifybuf2, &some_retval, verifybuf, 64 + msg_len, ed_pubkey); +} diff --git a/libaxolotl/jni/ed25519/additions/curve_sigs.h b/libaxolotl/jni/ed25519/additions/curve_sigs.h new file mode 100644 index 000000000..706f7db64 --- /dev/null +++ b/libaxolotl/jni/ed25519/additions/curve_sigs.h @@ -0,0 +1,25 @@ + +#ifndef __CURVE_SIGS_H__ +#define __CURVE_SIGS_H__ + +void curve25519_keygen(unsigned char* curve25519_pubkey_out, + unsigned char* curve25519_privkey_in); + +void curve25519_sign(unsigned char* signature_out, + unsigned char* curve25519_privkey, + unsigned char* msg, unsigned long msg_len); + +/* returns 0 on success */ +int curve25519_verify(unsigned char* signature, + unsigned char* curve25519_pubkey, + unsigned char* msg, unsigned long msg_len); + +/* helper function - modified version of crypto_sign() to use + explicit private key */ +int crypto_sign_modified( + unsigned char *sm,unsigned long long *smlen, + const unsigned char *m,unsigned long long mlen, + const unsigned char *sk + ); + +#endif diff --git a/libaxolotl/jni/ed25519/additions/sha512.c b/libaxolotl/jni/ed25519/additions/sha512.c new file mode 100644 index 000000000..9540ef467 --- /dev/null +++ b/libaxolotl/jni/ed25519/additions/sha512.c @@ -0,0 +1,13 @@ +#include "sha512.h" +#include "sph_sha2.h" + +int crypto_hash_sha512_ref(unsigned char *output ,const unsigned char *input, + unsigned long long len) +{ + sph_sha512_context ctx; + sph_sha512_init(&ctx); + sph_sha512(&ctx, input, len); + sph_sha512_close(&ctx, output); + return 0; +} + diff --git a/libaxolotl/jni/ed25519/additions/sha512.h b/libaxolotl/jni/ed25519/additions/sha512.h new file mode 100644 index 000000000..51f817c88 --- /dev/null +++ b/libaxolotl/jni/ed25519/additions/sha512.h @@ -0,0 +1,10 @@ +#ifndef __SHA512_H__ +#define __SHA512_H__ + +#include "sha512.h" +#include "sph_sha2.h" + +int crypto_hash_sha512_ref(unsigned char *output ,const unsigned char *input, + unsigned long long len); + +#endif diff --git a/libaxolotl/jni/ed25519/additions/sign_modified.c b/libaxolotl/jni/ed25519/additions/sign_modified.c new file mode 100644 index 000000000..c4b2d6f23 --- /dev/null +++ b/libaxolotl/jni/ed25519/additions/sign_modified.c @@ -0,0 +1,40 @@ +#include +#include "crypto_sign.h" +#include "crypto_hash_sha512.h" +#include "ge.h" +#include "sc.h" + +/* NEW: Compare to pristine crypto_sign() + Uses explicit private key for nonce derivation and as scalar, + instead of deriving both from a master key. +*/ +int crypto_sign_modified( + unsigned char *sm,unsigned long long *smlen, + const unsigned char *m,unsigned long long mlen, + const unsigned char *sk +) +{ + unsigned char pk[32]; + unsigned char az[64]; + unsigned char nonce[64]; + unsigned char hram[64]; + ge_p3 R; + + memmove(pk,sk + 32,32); + + *smlen = mlen + 64; + memmove(sm + 64,m,mlen); + memmove(sm + 32,sk,32); /* NEW: Use privkey directly for nonce derivation */ + crypto_hash_sha512(nonce,sm + 32,mlen + 32); + memmove(sm + 32,pk,32); + + sc_reduce(nonce); + ge_scalarmult_base(&R,nonce); + ge_p3_tobytes(sm,&R); + + crypto_hash_sha512(hram,sm,mlen + 64); + sc_reduce(hram); + sc_muladd(sm + 32,hram,sk,nonce); /* NEW: Use privkey directly */ + + return 0; +} diff --git a/libaxolotl/jni/ed25519/api.h b/libaxolotl/jni/ed25519/api.h new file mode 100644 index 000000000..d88dae0c3 --- /dev/null +++ b/libaxolotl/jni/ed25519/api.h @@ -0,0 +1,4 @@ +#define CRYPTO_SECRETKEYBYTES 64 +#define CRYPTO_PUBLICKEYBYTES 32 +#define CRYPTO_BYTES 64 +#define CRYPTO_DETERMINISTIC 1 diff --git a/libaxolotl/jni/ed25519/base.h b/libaxolotl/jni/ed25519/base.h new file mode 100644 index 000000000..573bd8a05 --- /dev/null +++ b/libaxolotl/jni/ed25519/base.h @@ -0,0 +1,1344 @@ +{ + { + { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, + { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, + { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, + }, + { + { -12815894,-12976347,-21581243,11784320,-25355658,-2750717,-11717903,-3814571,-358445,-10211303 }, + { -21703237,6903825,27185491,6451973,-29577724,-9554005,-15616551,11189268,-26829678,-5319081 }, + { 26966642,11152617,32442495,15396054,14353839,-12752335,-3128826,-9541118,-15472047,-4166697 }, + }, + { + { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, + { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, + { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, + }, + { + { -17036878,13921892,10945806,-6033431,27105052,-16084379,-28926210,15006023,3284568,-6276540 }, + { 23599295,-8306047,-11193664,-7687416,13236774,10506355,7464579,9656445,13059162,10374397 }, + { 7798556,16710257,3033922,2874086,28997861,2835604,32406664,-3839045,-641708,-101325 }, + }, + { + { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, + { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, + { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, + }, + { + { -15371964,-12862754,32573250,4720197,-26436522,5875511,-19188627,-15224819,-9818940,-12085777 }, + { -8549212,109983,15149363,2178705,22900618,4543417,3044240,-15689887,1762328,14866737 }, + { -18199695,-15951423,-10473290,1707278,-17185920,3916101,-28236412,3959421,27914454,4383652 }, + }, + { + { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, + { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, + { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, + }, + { + { 14499471,-2729599,-33191113,-4254652,28494862,14271267,30290735,10876454,-33154098,2381726 }, + { -7195431,-2655363,-14730155,462251,-27724326,3941372,-6236617,3696005,-32300832,15351955 }, + { 27431194,8222322,16448760,-3907995,-18707002,11938355,-32961401,-2970515,29551813,10109425 }, + }, +}, +{ + { + { -13657040,-13155431,-31283750,11777098,21447386,6519384,-2378284,-1627556,10092783,-4764171 }, + { 27939166,14210322,4677035,16277044,-22964462,-12398139,-32508754,12005538,-17810127,12803510 }, + { 17228999,-15661624,-1233527,300140,-1224870,-11714777,30364213,-9038194,18016357,4397660 }, + }, + { + { -10958843,-7690207,4776341,-14954238,27850028,-15602212,-26619106,14544525,-17477504,982639 }, + { 29253598,15796703,-2863982,-9908884,10057023,3163536,7332899,-4120128,-21047696,9934963 }, + { 5793303,16271923,-24131614,-10116404,29188560,1206517,-14747930,4559895,-30123922,-10897950 }, + }, + { + { -27643952,-11493006,16282657,-11036493,28414021,-15012264,24191034,4541697,-13338309,5500568 }, + { 12650548,-1497113,9052871,11355358,-17680037,-8400164,-17430592,12264343,10874051,13524335 }, + { 25556948,-3045990,714651,2510400,23394682,-10415330,33119038,5080568,-22528059,5376628 }, + }, + { + { -26088264,-4011052,-17013699,-3537628,-6726793,1920897,-22321305,-9447443,4535768,1569007 }, + { -2255422,14606630,-21692440,-8039818,28430649,8775819,-30494562,3044290,31848280,12543772 }, + { -22028579,2943893,-31857513,6777306,13784462,-4292203,-27377195,-2062731,7718482,14474653 }, + }, + { + { 2385315,2454213,-22631320,46603,-4437935,-15680415,656965,-7236665,24316168,-5253567 }, + { 13741529,10911568,-33233417,-8603737,-20177830,-1033297,33040651,-13424532,-20729456,8321686 }, + { 21060490,-2212744,15712757,-4336099,1639040,10656336,23845965,-11874838,-9984458,608372 }, + }, + { + { -13672732,-15087586,-10889693,-7557059,-6036909,11305547,1123968,-6780577,27229399,23887 }, + { -23244140,-294205,-11744728,14712571,-29465699,-2029617,12797024,-6440308,-1633405,16678954 }, + { -29500620,4770662,-16054387,14001338,7830047,9564805,-1508144,-4795045,-17169265,4904953 }, + }, + { + { 24059557,14617003,19037157,-15039908,19766093,-14906429,5169211,16191880,2128236,-4326833 }, + { -16981152,4124966,-8540610,-10653797,30336522,-14105247,-29806336,916033,-6882542,-2986532 }, + { -22630907,12419372,-7134229,-7473371,-16478904,16739175,285431,2763829,15736322,4143876 }, + }, + { + { 2379352,11839345,-4110402,-5988665,11274298,794957,212801,-14594663,23527084,-16458268 }, + { 33431127,-11130478,-17838966,-15626900,8909499,8376530,-32625340,4087881,-15188911,-14416214 }, + { 1767683,7197987,-13205226,-2022635,-13091350,448826,5799055,4357868,-4774191,-16323038 }, + }, +}, +{ + { + { 6721966,13833823,-23523388,-1551314,26354293,-11863321,23365147,-3949732,7390890,2759800 }, + { 4409041,2052381,23373853,10530217,7676779,-12885954,21302353,-4264057,1244380,-12919645 }, + { -4421239,7169619,4982368,-2957590,30256825,-2777540,14086413,9208236,15886429,16489664 }, + }, + { + { 1996075,10375649,14346367,13311202,-6874135,-16438411,-13693198,398369,-30606455,-712933 }, + { -25307465,9795880,-2777414,14878809,-33531835,14780363,13348553,12076947,-30836462,5113182 }, + { -17770784,11797796,31950843,13929123,-25888302,12288344,-30341101,-7336386,13847711,5387222 }, + }, + { + { -18582163,-3416217,17824843,-2340966,22744343,-10442611,8763061,3617786,-19600662,10370991 }, + { 20246567,-14369378,22358229,-543712,18507283,-10413996,14554437,-8746092,32232924,16763880 }, + { 9648505,10094563,26416693,14745928,-30374318,-6472621,11094161,15689506,3140038,-16510092 }, + }, + { + { -16160072,5472695,31895588,4744994,8823515,10365685,-27224800,9448613,-28774454,366295 }, + { 19153450,11523972,-11096490,-6503142,-24647631,5420647,28344573,8041113,719605,11671788 }, + { 8678025,2694440,-6808014,2517372,4964326,11152271,-15432916,-15266516,27000813,-10195553 }, + }, + { + { -15157904,7134312,8639287,-2814877,-7235688,10421742,564065,5336097,6750977,-14521026 }, + { 11836410,-3979488,26297894,16080799,23455045,15735944,1695823,-8819122,8169720,16220347 }, + { -18115838,8653647,17578566,-6092619,-8025777,-16012763,-11144307,-2627664,-5990708,-14166033 }, + }, + { + { -23308498,-10968312,15213228,-10081214,-30853605,-11050004,27884329,2847284,2655861,1738395 }, + { -27537433,-14253021,-25336301,-8002780,-9370762,8129821,21651608,-3239336,-19087449,-11005278 }, + { 1533110,3437855,23735889,459276,29970501,11335377,26030092,5821408,10478196,8544890 }, + }, + { + { 32173121,-16129311,24896207,3921497,22579056,-3410854,19270449,12217473,17789017,-3395995 }, + { -30552961,-2228401,-15578829,-10147201,13243889,517024,15479401,-3853233,30460520,1052596 }, + { -11614875,13323618,32618793,8175907,-15230173,12596687,27491595,-4612359,3179268,-9478891 }, + }, + { + { 31947069,-14366651,-4640583,-15339921,-15125977,-6039709,-14756777,-16411740,19072640,-9511060 }, + { 11685058,11822410,3158003,-13952594,33402194,-4165066,5977896,-5215017,473099,5040608 }, + { -20290863,8198642,-27410132,11602123,1290375,-2799760,28326862,1721092,-19558642,-3131606 }, + }, +}, +{ + { + { 7881532,10687937,7578723,7738378,-18951012,-2553952,21820786,8076149,-27868496,11538389 }, + { -19935666,3899861,18283497,-6801568,-15728660,-11249211,8754525,7446702,-5676054,5797016 }, + { -11295600,-3793569,-15782110,-7964573,12708869,-8456199,2014099,-9050574,-2369172,-5877341 }, + }, + { + { -22472376,-11568741,-27682020,1146375,18956691,16640559,1192730,-3714199,15123619,10811505 }, + { 14352098,-3419715,-18942044,10822655,32750596,4699007,-70363,15776356,-28886779,-11974553 }, + { -28241164,-8072475,-4978962,-5315317,29416931,1847569,-20654173,-16484855,4714547,-9600655 }, + }, + { + { 15200332,8368572,19679101,15970074,-31872674,1959451,24611599,-4543832,-11745876,12340220 }, + { 12876937,-10480056,33134381,6590940,-6307776,14872440,9613953,8241152,15370987,9608631 }, + { -4143277,-12014408,8446281,-391603,4407738,13629032,-7724868,15866074,-28210621,-8814099 }, + }, + { + { 26660628,-15677655,8393734,358047,-7401291,992988,-23904233,858697,20571223,8420556 }, + { 14620715,13067227,-15447274,8264467,14106269,15080814,33531827,12516406,-21574435,-12476749 }, + { 236881,10476226,57258,-14677024,6472998,2466984,17258519,7256740,8791136,15069930 }, + }, + { + { 1276410,-9371918,22949635,-16322807,-23493039,-5702186,14711875,4874229,-30663140,-2331391 }, + { 5855666,4990204,-13711848,7294284,-7804282,1924647,-1423175,-7912378,-33069337,9234253 }, + { 20590503,-9018988,31529744,-7352666,-2706834,10650548,31559055,-11609587,18979186,13396066 }, + }, + { + { 24474287,4968103,22267082,4407354,24063882,-8325180,-18816887,13594782,33514650,7021958 }, + { -11566906,-6565505,-21365085,15928892,-26158305,4315421,-25948728,-3916677,-21480480,12868082 }, + { -28635013,13504661,19988037,-2132761,21078225,6443208,-21446107,2244500,-12455797,-8089383 }, + }, + { + { -30595528,13793479,-5852820,319136,-25723172,-6263899,33086546,8957937,-15233648,5540521 }, + { -11630176,-11503902,-8119500,-7643073,2620056,1022908,-23710744,-1568984,-16128528,-14962807 }, + { 23152971,775386,27395463,14006635,-9701118,4649512,1689819,892185,-11513277,-15205948 }, + }, + { + { 9770129,9586738,26496094,4324120,1556511,-3550024,27453819,4763127,-19179614,5867134 }, + { -32765025,1927590,31726409,-4753295,23962434,-16019500,27846559,5931263,-29749703,-16108455 }, + { 27461885,-2977536,22380810,1815854,-23033753,-3031938,7283490,-15148073,-19526700,7734629 }, + }, +}, +{ + { + { -8010264,-9590817,-11120403,6196038,29344158,-13430885,7585295,-3176626,18549497,15302069 }, + { -32658337,-6171222,-7672793,-11051681,6258878,13504381,10458790,-6418461,-8872242,8424746 }, + { 24687205,8613276,-30667046,-3233545,1863892,-1830544,19206234,7134917,-11284482,-828919 }, + }, + { + { 11334899,-9218022,8025293,12707519,17523892,-10476071,10243738,-14685461,-5066034,16498837 }, + { 8911542,6887158,-9584260,-6958590,11145641,-9543680,17303925,-14124238,6536641,10543906 }, + { -28946384,15479763,-17466835,568876,-1497683,11223454,-2669190,-16625574,-27235709,8876771 }, + }, + { + { -25742899,-12566864,-15649966,-846607,-33026686,-796288,-33481822,15824474,-604426,-9039817 }, + { 10330056,70051,7957388,-9002667,9764902,15609756,27698697,-4890037,1657394,3084098 }, + { 10477963,-7470260,12119566,-13250805,29016247,-5365589,31280319,14396151,-30233575,15272409 }, + }, + { + { -12288309,3169463,28813183,16658753,25116432,-5630466,-25173957,-12636138,-25014757,1950504 }, + { -26180358,9489187,11053416,-14746161,-31053720,5825630,-8384306,-8767532,15341279,8373727 }, + { 28685821,7759505,-14378516,-12002860,-31971820,4079242,298136,-10232602,-2878207,15190420 }, + }, + { + { -32932876,13806336,-14337485,-15794431,-24004620,10940928,8669718,2742393,-26033313,-6875003 }, + { -1580388,-11729417,-25979658,-11445023,-17411874,-10912854,9291594,-16247779,-12154742,6048605 }, + { -30305315,14843444,1539301,11864366,20201677,1900163,13934231,5128323,11213262,9168384 }, + }, + { + { -26280513,11007847,19408960,-940758,-18592965,-4328580,-5088060,-11105150,20470157,-16398701 }, + { -23136053,9282192,14855179,-15390078,-7362815,-14408560,-22783952,14461608,14042978,5230683 }, + { 29969567,-2741594,-16711867,-8552442,9175486,-2468974,21556951,3506042,-5933891,-12449708 }, + }, + { + { -3144746,8744661,19704003,4581278,-20430686,6830683,-21284170,8971513,-28539189,15326563 }, + { -19464629,10110288,-17262528,-3503892,-23500387,1355669,-15523050,15300988,-20514118,9168260 }, + { -5353335,4488613,-23803248,16314347,7780487,-15638939,-28948358,9601605,33087103,-9011387 }, + }, + { + { -19443170,-15512900,-20797467,-12445323,-29824447,10229461,-27444329,-15000531,-5996870,15664672 }, + { 23294591,-16632613,-22650781,-8470978,27844204,11461195,13099750,-2460356,18151676,13417686 }, + { -24722913,-4176517,-31150679,5988919,-26858785,6685065,1661597,-12551441,15271676,-15452665 }, + }, +}, +{ + { + { 11433042,-13228665,8239631,-5279517,-1985436,-725718,-18698764,2167544,-6921301,-13440182 }, + { -31436171,15575146,30436815,12192228,-22463353,9395379,-9917708,-8638997,12215110,12028277 }, + { 14098400,6555944,23007258,5757252,-15427832,-12950502,30123440,4617780,-16900089,-655628 }, + }, + { + { -4026201,-15240835,11893168,13718664,-14809462,1847385,-15819999,10154009,23973261,-12684474 }, + { -26531820,-3695990,-1908898,2534301,-31870557,-16550355,18341390,-11419951,32013174,-10103539 }, + { -25479301,10876443,-11771086,-14625140,-12369567,1838104,21911214,6354752,4425632,-837822 }, + }, + { + { -10433389,-14612966,22229858,-3091047,-13191166,776729,-17415375,-12020462,4725005,14044970 }, + { 19268650,-7304421,1555349,8692754,-21474059,-9910664,6347390,-1411784,-19522291,-16109756 }, + { -24864089,12986008,-10898878,-5558584,-11312371,-148526,19541418,8180106,9282262,10282508 }, + }, + { + { -26205082,4428547,-8661196,-13194263,4098402,-14165257,15522535,8372215,5542595,-10702683 }, + { -10562541,14895633,26814552,-16673850,-17480754,-2489360,-2781891,6993761,-18093885,10114655 }, + { -20107055,-929418,31422704,10427861,-7110749,6150669,-29091755,-11529146,25953725,-106158 }, + }, + { + { -4234397,-8039292,-9119125,3046000,2101609,-12607294,19390020,6094296,-3315279,12831125 }, + { -15998678,7578152,5310217,14408357,-33548620,-224739,31575954,6326196,7381791,-2421839 }, + { -20902779,3296811,24736065,-16328389,18374254,7318640,6295303,8082724,-15362489,12339664 }, + }, + { + { 27724736,2291157,6088201,-14184798,1792727,5857634,13848414,15768922,25091167,14856294 }, + { -18866652,8331043,24373479,8541013,-701998,-9269457,12927300,-12695493,-22182473,-9012899 }, + { -11423429,-5421590,11632845,3405020,30536730,-11674039,-27260765,13866390,30146206,9142070 }, + }, + { + { 3924129,-15307516,-13817122,-10054960,12291820,-668366,-27702774,9326384,-8237858,4171294 }, + { -15921940,16037937,6713787,16606682,-21612135,2790944,26396185,3731949,345228,-5462949 }, + { -21327538,13448259,25284571,1143661,20614966,-8849387,2031539,-12391231,-16253183,-13582083 }, + }, + { + { 31016211,-16722429,26371392,-14451233,-5027349,14854137,17477601,3842657,28012650,-16405420 }, + { -5075835,9368966,-8562079,-4600902,-15249953,6970560,-9189873,16292057,-8867157,3507940 }, + { 29439664,3537914,23333589,6997794,-17555561,-11018068,-15209202,-15051267,-9164929,6580396 }, + }, +}, +{ + { + { -12185861,-7679788,16438269,10826160,-8696817,-6235611,17860444,-9273846,-2095802,9304567 }, + { 20714564,-4336911,29088195,7406487,11426967,-5095705,14792667,-14608617,5289421,-477127 }, + { -16665533,-10650790,-6160345,-13305760,9192020,-1802462,17271490,12349094,26939669,-3752294 }, + }, + { + { -12889898,9373458,31595848,16374215,21471720,13221525,-27283495,-12348559,-3698806,117887 }, + { 22263325,-6560050,3984570,-11174646,-15114008,-566785,28311253,5358056,-23319780,541964 }, + { 16259219,3261970,2309254,-15534474,-16885711,-4581916,24134070,-16705829,-13337066,-13552195 }, + }, + { + { 9378160,-13140186,-22845982,-12745264,28198281,-7244098,-2399684,-717351,690426,14876244 }, + { 24977353,-314384,-8223969,-13465086,28432343,-1176353,-13068804,-12297348,-22380984,6618999 }, + { -1538174,11685646,12944378,13682314,-24389511,-14413193,8044829,-13817328,32239829,-5652762 }, + }, + { + { -18603066,4762990,-926250,8885304,-28412480,-3187315,9781647,-10350059,32779359,5095274 }, + { -33008130,-5214506,-32264887,-3685216,9460461,-9327423,-24601656,14506724,21639561,-2630236 }, + { -16400943,-13112215,25239338,15531969,3987758,-4499318,-1289502,-6863535,17874574,558605 }, + }, + { + { -13600129,10240081,9171883,16131053,-20869254,9599700,33499487,5080151,2085892,5119761 }, + { -22205145,-2519528,-16381601,414691,-25019550,2170430,30634760,-8363614,-31999993,-5759884 }, + { -6845704,15791202,8550074,-1312654,29928809,-12092256,27534430,-7192145,-22351378,12961482 }, + }, + { + { -24492060,-9570771,10368194,11582341,-23397293,-2245287,16533930,8206996,-30194652,-5159638 }, + { -11121496,-3382234,2307366,6362031,-135455,8868177,-16835630,7031275,7589640,8945490 }, + { -32152748,8917967,6661220,-11677616,-1192060,-15793393,7251489,-11182180,24099109,-14456170 }, + }, + { + { 5019558,-7907470,4244127,-14714356,-26933272,6453165,-19118182,-13289025,-6231896,-10280736 }, + { 10853594,10721687,26480089,5861829,-22995819,1972175,-1866647,-10557898,-3363451,-6441124 }, + { -17002408,5906790,221599,-6563147,7828208,-13248918,24362661,-2008168,-13866408,7421392 }, + }, + { + { 8139927,-6546497,32257646,-5890546,30375719,1886181,-21175108,15441252,28826358,-4123029 }, + { 6267086,9695052,7709135,-16603597,-32869068,-1886135,14795160,-7840124,13746021,-1742048 }, + { 28584902,7787108,-6732942,-15050729,22846041,-7571236,-3181936,-363524,4771362,-8419958 }, + }, +}, +{ + { + { 24949256,6376279,-27466481,-8174608,-18646154,-9930606,33543569,-12141695,3569627,11342593 }, + { 26514989,4740088,27912651,3697550,19331575,-11472339,6809886,4608608,7325975,-14801071 }, + { -11618399,-14554430,-24321212,7655128,-1369274,5214312,-27400540,10258390,-17646694,-8186692 }, + }, + { + { 11431204,15823007,26570245,14329124,18029990,4796082,-31446179,15580664,9280358,-3973687 }, + { -160783,-10326257,-22855316,-4304997,-20861367,-13621002,-32810901,-11181622,-15545091,4387441 }, + { -20799378,12194512,3937617,-5805892,-27154820,9340370,-24513992,8548137,20617071,-7482001 }, + }, + { + { -938825,-3930586,-8714311,16124718,24603125,-6225393,-13775352,-11875822,24345683,10325460 }, + { -19855277,-1568885,-22202708,8714034,14007766,6928528,16318175,-1010689,4766743,3552007 }, + { -21751364,-16730916,1351763,-803421,-4009670,3950935,3217514,14481909,10988822,-3994762 }, + }, + { + { 15564307,-14311570,3101243,5684148,30446780,-8051356,12677127,-6505343,-8295852,13296005 }, + { -9442290,6624296,-30298964,-11913677,-4670981,-2057379,31521204,9614054,-30000824,12074674 }, + { 4771191,-135239,14290749,-13089852,27992298,14998318,-1413936,-1556716,29832613,-16391035 }, + }, + { + { 7064884,-7541174,-19161962,-5067537,-18891269,-2912736,25825242,5293297,-27122660,13101590 }, + { -2298563,2439670,-7466610,1719965,-27267541,-16328445,32512469,-5317593,-30356070,-4190957 }, + { -30006540,10162316,-33180176,3981723,-16482138,-13070044,14413974,9515896,19568978,9628812 }, + }, + { + { 33053803,199357,15894591,1583059,27380243,-4580435,-17838894,-6106839,-6291786,3437740 }, + { -18978877,3884493,19469877,12726490,15913552,13614290,-22961733,70104,7463304,4176122 }, + { -27124001,10659917,11482427,-16070381,12771467,-6635117,-32719404,-5322751,24216882,5944158 }, + }, + { + { 8894125,7450974,-2664149,-9765752,-28080517,-12389115,19345746,14680796,11632993,5847885 }, + { 26942781,-2315317,9129564,-4906607,26024105,11769399,-11518837,6367194,-9727230,4782140 }, + { 19916461,-4828410,-22910704,-11414391,25606324,-5972441,33253853,8220911,6358847,-1873857 }, + }, + { + { 801428,-2081702,16569428,11065167,29875704,96627,7908388,-4480480,-13538503,1387155 }, + { 19646058,5720633,-11416706,12814209,11607948,12749789,14147075,15156355,-21866831,11835260 }, + { 19299512,1155910,28703737,14890794,2925026,7269399,26121523,15467869,-26560550,5052483 }, + }, +}, +{ + { + { -3017432,10058206,1980837,3964243,22160966,12322533,-6431123,-12618185,12228557,-7003677 }, + { 32944382,14922211,-22844894,5188528,21913450,-8719943,4001465,13238564,-6114803,8653815 }, + { 22865569,-4652735,27603668,-12545395,14348958,8234005,24808405,5719875,28483275,2841751 }, + }, + { + { -16420968,-1113305,-327719,-12107856,21886282,-15552774,-1887966,-315658,19932058,-12739203 }, + { -11656086,10087521,-8864888,-5536143,-19278573,-3055912,3999228,13239134,-4777469,-13910208 }, + { 1382174,-11694719,17266790,9194690,-13324356,9720081,20403944,11284705,-14013818,3093230 }, + }, + { + { 16650921,-11037932,-1064178,1570629,-8329746,7352753,-302424,16271225,-24049421,-6691850 }, + { -21911077,-5927941,-4611316,-5560156,-31744103,-10785293,24123614,15193618,-21652117,-16739389 }, + { -9935934,-4289447,-25279823,4372842,2087473,10399484,31870908,14690798,17361620,11864968 }, + }, + { + { -11307610,6210372,13206574,5806320,-29017692,-13967200,-12331205,-7486601,-25578460,-16240689 }, + { 14668462,-12270235,26039039,15305210,25515617,4542480,10453892,6577524,9145645,-6443880 }, + { 5974874,3053895,-9433049,-10385191,-31865124,3225009,-7972642,3936128,-5652273,-3050304 }, + }, + { + { 30625386,-4729400,-25555961,-12792866,-20484575,7695099,17097188,-16303496,-27999779,1803632 }, + { -3553091,9865099,-5228566,4272701,-5673832,-16689700,14911344,12196514,-21405489,7047412 }, + { 20093277,9920966,-11138194,-5343857,13161587,12044805,-32856851,4124601,-32343828,-10257566 }, + }, + { + { -20788824,14084654,-13531713,7842147,19119038,-13822605,4752377,-8714640,-21679658,2288038 }, + { -26819236,-3283715,29965059,3039786,-14473765,2540457,29457502,14625692,-24819617,12570232 }, + { -1063558,-11551823,16920318,12494842,1278292,-5869109,-21159943,-3498680,-11974704,4724943 }, + }, + { + { 17960970,-11775534,-4140968,-9702530,-8876562,-1410617,-12907383,-8659932,-29576300,1903856 }, + { 23134274,-14279132,-10681997,-1611936,20684485,15770816,-12989750,3190296,26955097,14109738 }, + { 15308788,5320727,-30113809,-14318877,22902008,7767164,29425325,-11277562,31960942,11934971 }, + }, + { + { -27395711,8435796,4109644,12222639,-24627868,14818669,20638173,4875028,10491392,1379718 }, + { -13159415,9197841,3875503,-8936108,-1383712,-5879801,33518459,16176658,21432314,12180697 }, + { -11787308,11500838,13787581,-13832590,-22430679,10140205,1465425,12689540,-10301319,-13872883 }, + }, +}, +{ + { + { 5414091,-15386041,-21007664,9643570,12834970,1186149,-2622916,-1342231,26128231,6032912 }, + { -26337395,-13766162,32496025,-13653919,17847801,-12669156,3604025,8316894,-25875034,-10437358 }, + { 3296484,6223048,24680646,-12246460,-23052020,5903205,-8862297,-4639164,12376617,3188849 }, + }, + { + { 29190488,-14659046,27549113,-1183516,3520066,-10697301,32049515,-7309113,-16109234,-9852307 }, + { -14744486,-9309156,735818,-598978,-20407687,-5057904,25246078,-15795669,18640741,-960977 }, + { -6928835,-16430795,10361374,5642961,4910474,12345252,-31638386,-494430,10530747,1053335 }, + }, + { + { -29265967,-14186805,-13538216,-12117373,-19457059,-10655384,-31462369,-2948985,24018831,15026644 }, + { -22592535,-3145277,-2289276,5953843,-13440189,9425631,25310643,13003497,-2314791,-15145616 }, + { -27419985,-603321,-8043984,-1669117,-26092265,13987819,-27297622,187899,-23166419,-2531735 }, + }, + { + { -21744398,-13810475,1844840,5021428,-10434399,-15911473,9716667,16266922,-5070217,726099 }, + { 29370922,-6053998,7334071,-15342259,9385287,2247707,-13661962,-4839461,30007388,-15823341 }, + { -936379,16086691,23751945,-543318,-1167538,-5189036,9137109,730663,9835848,4555336 }, + }, + { + { -23376435,1410446,-22253753,-12899614,30867635,15826977,17693930,544696,-11985298,12422646 }, + { 31117226,-12215734,-13502838,6561947,-9876867,-12757670,-5118685,-4096706,29120153,13924425 }, + { -17400879,-14233209,19675799,-2734756,-11006962,-5858820,-9383939,-11317700,7240931,-237388 }, + }, + { + { -31361739,-11346780,-15007447,-5856218,-22453340,-12152771,1222336,4389483,3293637,-15551743 }, + { -16684801,-14444245,11038544,11054958,-13801175,-3338533,-24319580,7733547,12796905,-6335822 }, + { -8759414,-10817836,-25418864,10783769,-30615557,-9746811,-28253339,3647836,3222231,-11160462 }, + }, + { + { 18606113,1693100,-25448386,-15170272,4112353,10045021,23603893,-2048234,-7550776,2484985 }, + { 9255317,-3131197,-12156162,-1004256,13098013,-9214866,16377220,-2102812,-19802075,-3034702 }, + { -22729289,7496160,-5742199,11329249,19991973,-3347502,-31718148,9936966,-30097688,-10618797 }, + }, + { + { 21878590,-5001297,4338336,13643897,-3036865,13160960,19708896,5415497,-7360503,-4109293 }, + { 27736861,10103576,12500508,8502413,-3413016,-9633558,10436918,-1550276,-23659143,-8132100 }, + { 19492550,-12104365,-29681976,-852630,-3208171,12403437,30066266,8367329,13243957,8709688 }, + }, +}, +{ + { + { 12015105,2801261,28198131,10151021,24818120,-4743133,-11194191,-5645734,5150968,7274186 }, + { 2831366,-12492146,1478975,6122054,23825128,-12733586,31097299,6083058,31021603,-9793610 }, + { -2529932,-2229646,445613,10720828,-13849527,-11505937,-23507731,16354465,15067285,-14147707 }, + }, + { + { 7840942,14037873,-33364863,15934016,-728213,-3642706,21403988,1057586,-19379462,-12403220 }, + { 915865,-16469274,15608285,-8789130,-24357026,6060030,-17371319,8410997,-7220461,16527025 }, + { 32922597,-556987,20336074,-16184568,10903705,-5384487,16957574,52992,23834301,6588044 }, + }, + { + { 32752030,11232950,3381995,-8714866,22652988,-10744103,17159699,16689107,-20314580,-1305992 }, + { -4689649,9166776,-25710296,-10847306,11576752,12733943,7924251,-2752281,1976123,-7249027 }, + { 21251222,16309901,-2983015,-6783122,30810597,12967303,156041,-3371252,12331345,-8237197 }, + }, + { + { 8651614,-4477032,-16085636,-4996994,13002507,2950805,29054427,-5106970,10008136,-4667901 }, + { 31486080,15114593,-14261250,12951354,14369431,-7387845,16347321,-13662089,8684155,-10532952 }, + { 19443825,11385320,24468943,-9659068,-23919258,2187569,-26263207,-6086921,31316348,14219878 }, + }, + { + { -28594490,1193785,32245219,11392485,31092169,15722801,27146014,6992409,29126555,9207390 }, + { 32382935,1110093,18477781,11028262,-27411763,-7548111,-4980517,10843782,-7957600,-14435730 }, + { 2814918,7836403,27519878,-7868156,-20894015,-11553689,-21494559,8550130,28346258,1994730 }, + }, + { + { -19578299,8085545,-14000519,-3948622,2785838,-16231307,-19516951,7174894,22628102,8115180 }, + { -30405132,955511,-11133838,-15078069,-32447087,-13278079,-25651578,3317160,-9943017,930272 }, + { -15303681,-6833769,28856490,1357446,23421993,1057177,24091212,-1388970,-22765376,-10650715 }, + }, + { + { -22751231,-5303997,-12907607,-12768866,-15811511,-7797053,-14839018,-16554220,-1867018,8398970 }, + { -31969310,2106403,-4736360,1362501,12813763,16200670,22981545,-6291273,18009408,-15772772 }, + { -17220923,-9545221,-27784654,14166835,29815394,7444469,29551787,-3727419,19288549,1325865 }, + }, + { + { 15100157,-15835752,-23923978,-1005098,-26450192,15509408,12376730,-3479146,33166107,-8042750 }, + { 20909231,13023121,-9209752,16251778,-5778415,-8094914,12412151,10018715,2213263,-13878373 }, + { 32529814,-11074689,30361439,-16689753,-9135940,1513226,22922121,6382134,-5766928,8371348 }, + }, +}, +{ + { + { 9923462,11271500,12616794,3544722,-29998368,-1721626,12891687,-8193132,-26442943,10486144 }, + { -22597207,-7012665,8587003,-8257861,4084309,-12970062,361726,2610596,-23921530,-11455195 }, + { 5408411,-1136691,-4969122,10561668,24145918,14240566,31319731,-4235541,19985175,-3436086 }, + }, + { + { -13994457,16616821,14549246,3341099,32155958,13648976,-17577068,8849297,65030,8370684 }, + { -8320926,-12049626,31204563,5839400,-20627288,-1057277,-19442942,6922164,12743482,-9800518 }, + { -2361371,12678785,28815050,4759974,-23893047,4884717,23783145,11038569,18800704,255233 }, + }, + { + { -5269658,-1773886,13957886,7990715,23132995,728773,13393847,9066957,19258688,-14753793 }, + { -2936654,-10827535,-10432089,14516793,-3640786,4372541,-31934921,2209390,-1524053,2055794 }, + { 580882,16705327,5468415,-2683018,-30926419,-14696000,-7203346,-8994389,-30021019,7394435 }, + }, + { + { 23838809,1822728,-15738443,15242727,8318092,-3733104,-21672180,-3492205,-4821741,14799921 }, + { 13345610,9759151,3371034,-16137791,16353039,8577942,31129804,13496856,-9056018,7402518 }, + { 2286874,-4435931,-20042458,-2008336,-13696227,5038122,11006906,-15760352,8205061,1607563 }, + }, + { + { 14414086,-8002132,3331830,-3208217,22249151,-5594188,18364661,-2906958,30019587,-9029278 }, + { -27688051,1585953,-10775053,931069,-29120221,-11002319,-14410829,12029093,9944378,8024 }, + { 4368715,-3709630,29874200,-15022983,-20230386,-11410704,-16114594,-999085,-8142388,5640030 }, + }, + { + { 10299610,13746483,11661824,16234854,7630238,5998374,9809887,-16694564,15219798,-14327783 }, + { 27425505,-5719081,3055006,10660664,23458024,595578,-15398605,-1173195,-18342183,9742717 }, + { 6744077,2427284,26042789,2720740,-847906,1118974,32324614,7406442,12420155,1994844 }, + }, + { + { 14012521,-5024720,-18384453,-9578469,-26485342,-3936439,-13033478,-10909803,24319929,-6446333 }, + { 16412690,-4507367,10772641,15929391,-17068788,-4658621,10555945,-10484049,-30102368,-4739048 }, + { 22397382,-7767684,-9293161,-12792868,17166287,-9755136,-27333065,6199366,21880021,-12250760 }, + }, + { + { -4283307,5368523,-31117018,8163389,-30323063,3209128,16557151,8890729,8840445,4957760 }, + { -15447727,709327,-6919446,-10870178,-29777922,6522332,-21720181,12130072,-14796503,5005757 }, + { -2114751,-14308128,23019042,15765735,-25269683,6002752,10183197,-13239326,-16395286,-2176112 }, + }, +}, +{ + { + { -19025756,1632005,13466291,-7995100,-23640451,16573537,-32013908,-3057104,22208662,2000468 }, + { 3065073,-1412761,-25598674,-361432,-17683065,-5703415,-8164212,11248527,-3691214,-7414184 }, + { 10379208,-6045554,8877319,1473647,-29291284,-12507580,16690915,2553332,-3132688,16400289 }, + }, + { + { 15716668,1254266,-18472690,7446274,-8448918,6344164,-22097271,-7285580,26894937,9132066 }, + { 24158887,12938817,11085297,-8177598,-28063478,-4457083,-30576463,64452,-6817084,-2692882 }, + { 13488534,7794716,22236231,5989356,25426474,-12578208,2350710,-3418511,-4688006,2364226 }, + }, + { + { 16335052,9132434,25640582,6678888,1725628,8517937,-11807024,-11697457,15445875,-7798101 }, + { 29004207,-7867081,28661402,-640412,-12794003,-7943086,31863255,-4135540,-278050,-15759279 }, + { -6122061,-14866665,-28614905,14569919,-10857999,-3591829,10343412,-6976290,-29828287,-10815811 }, + }, + { + { 27081650,3463984,14099042,-4517604,1616303,-6205604,29542636,15372179,17293797,960709 }, + { 20263915,11434237,-5765435,11236810,13505955,-10857102,-16111345,6493122,-19384511,7639714 }, + { -2830798,-14839232,25403038,-8215196,-8317012,-16173699,18006287,-16043750,29994677,-15808121 }, + }, + { + { 9769828,5202651,-24157398,-13631392,-28051003,-11561624,-24613141,-13860782,-31184575,709464 }, + { 12286395,13076066,-21775189,-1176622,-25003198,4057652,-32018128,-8890874,16102007,13205847 }, + { 13733362,5599946,10557076,3195751,-5557991,8536970,-25540170,8525972,10151379,10394400 }, + }, + { + { 4024660,-16137551,22436262,12276534,-9099015,-2686099,19698229,11743039,-33302334,8934414 }, + { -15879800,-4525240,-8580747,-2934061,14634845,-698278,-9449077,3137094,-11536886,11721158 }, + { 17555939,-5013938,8268606,2331751,-22738815,9761013,9319229,8835153,-9205489,-1280045 }, + }, + { + { -461409,-7830014,20614118,16688288,-7514766,-4807119,22300304,505429,6108462,-6183415 }, + { -5070281,12367917,-30663534,3234473,32617080,-8422642,29880583,-13483331,-26898490,-7867459 }, + { -31975283,5726539,26934134,10237677,-3173717,-605053,24199304,3795095,7592688,-14992079 }, + }, + { + { 21594432,-14964228,17466408,-4077222,32537084,2739898,6407723,12018833,-28256052,4298412 }, + { -20650503,-11961496,-27236275,570498,3767144,-1717540,13891942,-1569194,13717174,10805743 }, + { -14676630,-15644296,15287174,11927123,24177847,-8175568,-796431,14860609,-26938930,-5863836 }, + }, +}, +{ + { + { 12962541,5311799,-10060768,11658280,18855286,-7954201,13286263,-12808704,-4381056,9882022 }, + { 18512079,11319350,-20123124,15090309,18818594,5271736,-22727904,3666879,-23967430,-3299429 }, + { -6789020,-3146043,16192429,13241070,15898607,-14206114,-10084880,-6661110,-2403099,5276065 }, + }, + { + { 30169808,-5317648,26306206,-11750859,27814964,7069267,7152851,3684982,1449224,13082861 }, + { 10342826,3098505,2119311,193222,25702612,12233820,23697382,15056736,-21016438,-8202000 }, + { -33150110,3261608,22745853,7948688,19370557,-15177665,-26171976,6482814,-10300080,-11060101 }, + }, + { + { 32869458,-5408545,25609743,15678670,-10687769,-15471071,26112421,2521008,-22664288,6904815 }, + { 29506923,4457497,3377935,-9796444,-30510046,12935080,1561737,3841096,-29003639,-6657642 }, + { 10340844,-6630377,-18656632,-2278430,12621151,-13339055,30878497,-11824370,-25584551,5181966 }, + }, + { + { 25940115,-12658025,17324188,-10307374,-8671468,15029094,24396252,-16450922,-2322852,-12388574 }, + { -21765684,9916823,-1300409,4079498,-1028346,11909559,1782390,12641087,20603771,-6561742 }, + { -18882287,-11673380,24849422,11501709,13161720,-4768874,1925523,11914390,4662781,7820689 }, + }, + { + { 12241050,-425982,8132691,9393934,32846760,-1599620,29749456,12172924,16136752,15264020 }, + { -10349955,-14680563,-8211979,2330220,-17662549,-14545780,10658213,6671822,19012087,3772772 }, + { 3753511,-3421066,10617074,2028709,14841030,-6721664,28718732,-15762884,20527771,12988982 }, + }, + { + { -14822485,-5797269,-3707987,12689773,-898983,-10914866,-24183046,-10564943,3299665,-12424953 }, + { -16777703,-15253301,-9642417,4978983,3308785,8755439,6943197,6461331,-25583147,8991218 }, + { -17226263,1816362,-1673288,-6086439,31783888,-8175991,-32948145,7417950,-30242287,1507265 }, + }, + { + { 29692663,6829891,-10498800,4334896,20945975,-11906496,-28887608,8209391,14606362,-10647073 }, + { -3481570,8707081,32188102,5672294,22096700,1711240,-33020695,9761487,4170404,-2085325 }, + { -11587470,14855945,-4127778,-1531857,-26649089,15084046,22186522,16002000,-14276837,-8400798 }, + }, + { + { -4811456,13761029,-31703877,-2483919,-3312471,7869047,-7113572,-9620092,13240845,10965870 }, + { -7742563,-8256762,-14768334,-13656260,-23232383,12387166,4498947,14147411,29514390,4302863 }, + { -13413405,-12407859,20757302,-13801832,14785143,8976368,-5061276,-2144373,17846988,-13971927 }, + }, +}, +{ + { + { -2244452,-754728,-4597030,-1066309,-6247172,1455299,-21647728,-9214789,-5222701,12650267 }, + { -9906797,-16070310,21134160,12198166,-27064575,708126,387813,13770293,-19134326,10958663 }, + { 22470984,12369526,23446014,-5441109,-21520802,-9698723,-11772496,-11574455,-25083830,4271862 }, + }, + { + { -25169565,-10053642,-19909332,15361595,-5984358,2159192,75375,-4278529,-32526221,8469673 }, + { 15854970,4148314,-8893890,7259002,11666551,13824734,-30531198,2697372,24154791,-9460943 }, + { 15446137,-15806644,29759747,14019369,30811221,-9610191,-31582008,12840104,24913809,9815020 }, + }, + { + { -4709286,-5614269,-31841498,-12288893,-14443537,10799414,-9103676,13438769,18735128,9466238 }, + { 11933045,9281483,5081055,-5183824,-2628162,-4905629,-7727821,-10896103,-22728655,16199064 }, + { 14576810,379472,-26786533,-8317236,-29426508,-10812974,-102766,1876699,30801119,2164795 }, + }, + { + { 15995086,3199873,13672555,13712240,-19378835,-4647646,-13081610,-15496269,-13492807,1268052 }, + { -10290614,-3659039,-3286592,10948818,23037027,3794475,-3470338,-12600221,-17055369,3565904 }, + { 29210088,-9419337,-5919792,-4952785,10834811,-13327726,-16512102,-10820713,-27162222,-14030531 }, + }, + { + { -13161890,15508588,16663704,-8156150,-28349942,9019123,-29183421,-3769423,2244111,-14001979 }, + { -5152875,-3800936,-9306475,-6071583,16243069,14684434,-25673088,-16180800,13491506,4641841 }, + { 10813417,643330,-19188515,-728916,30292062,-16600078,27548447,-7721242,14476989,-12767431 }, + }, + { + { 10292079,9984945,6481436,8279905,-7251514,7032743,27282937,-1644259,-27912810,12651324 }, + { -31185513,-813383,22271204,11835308,10201545,15351028,17099662,3988035,21721536,-3148940 }, + { 10202177,-6545839,-31373232,-9574638,-32150642,-8119683,-12906320,3852694,13216206,14842320 }, + }, + { + { -15815640,-10601066,-6538952,-7258995,-6984659,-6581778,-31500847,13765824,-27434397,9900184 }, + { 14465505,-13833331,-32133984,-14738873,-27443187,12990492,33046193,15796406,-7051866,-8040114 }, + { 30924417,-8279620,6359016,-12816335,16508377,9071735,-25488601,15413635,9524356,-7018878 }, + }, + { + { 12274201,-13175547,32627641,-1785326,6736625,13267305,5237659,-5109483,15663516,4035784 }, + { -2951309,8903985,17349946,601635,-16432815,-4612556,-13732739,-15889334,-22258478,4659091 }, + { -16916263,-4952973,-30393711,-15158821,20774812,15897498,5736189,15026997,-2178256,-13455585 }, + }, +}, +{ + { + { -8858980,-2219056,28571666,-10155518,-474467,-10105698,-3801496,278095,23440562,-290208 }, + { 10226241,-5928702,15139956,120818,-14867693,5218603,32937275,11551483,-16571960,-7442864 }, + { 17932739,-12437276,-24039557,10749060,11316803,7535897,22503767,5561594,-3646624,3898661 }, + }, + { + { 7749907,-969567,-16339731,-16464,-25018111,15122143,-1573531,7152530,21831162,1245233 }, + { 26958459,-14658026,4314586,8346991,-5677764,11960072,-32589295,-620035,-30402091,-16716212 }, + { -12165896,9166947,33491384,13673479,29787085,13096535,6280834,14587357,-22338025,13987525 }, + }, + { + { -24349909,7778775,21116000,15572597,-4833266,-5357778,-4300898,-5124639,-7469781,-2858068 }, + { 9681908,-6737123,-31951644,13591838,-6883821,386950,31622781,6439245,-14581012,4091397 }, + { -8426427,1470727,-28109679,-1596990,3978627,-5123623,-19622683,12092163,29077877,-14741988 }, + }, + { + { 5269168,-6859726,-13230211,-8020715,25932563,1763552,-5606110,-5505881,-20017847,2357889 }, + { 32264008,-15407652,-5387735,-1160093,-2091322,-3946900,23104804,-12869908,5727338,189038 }, + { 14609123,-8954470,-6000566,-16622781,-14577387,-7743898,-26745169,10942115,-25888931,-14884697 }, + }, + { + { 20513500,5557931,-15604613,7829531,26413943,-2019404,-21378968,7471781,13913677,-5137875 }, + { -25574376,11967826,29233242,12948236,-6754465,4713227,-8940970,14059180,12878652,8511905 }, + { -25656801,3393631,-2955415,-7075526,-2250709,9366908,-30223418,6812974,5568676,-3127656 }, + }, + { + { 11630004,12144454,2116339,13606037,27378885,15676917,-17408753,-13504373,-14395196,8070818 }, + { 27117696,-10007378,-31282771,-5570088,1127282,12772488,-29845906,10483306,-11552749,-1028714 }, + { 10637467,-5688064,5674781,1072708,-26343588,-6982302,-1683975,9177853,-27493162,15431203 }, + }, + { + { 20525145,10892566,-12742472,12779443,-29493034,16150075,-28240519,14943142,-15056790,-7935931 }, + { -30024462,5626926,-551567,-9981087,753598,11981191,25244767,-3239766,-3356550,9594024 }, + { -23752644,2636870,-5163910,-10103818,585134,7877383,11345683,-6492290,13352335,-10977084 }, + }, + { + { -1931799,-5407458,3304649,-12884869,17015806,-4877091,-29783850,-7752482,-13215537,-319204 }, + { 20239939,6607058,6203985,3483793,-18386976,-779229,-20723742,15077870,-22750759,14523817 }, + { 27406042,-6041657,27423596,-4497394,4996214,10002360,-28842031,-4545494,-30172742,-4805667 }, + }, +}, +{ + { + { 11374242,12660715,17861383,-12540833,10935568,1099227,-13886076,-9091740,-27727044,11358504 }, + { -12730809,10311867,1510375,10778093,-2119455,-9145702,32676003,11149336,-26123651,4985768 }, + { -19096303,341147,-6197485,-239033,15756973,-8796662,-983043,13794114,-19414307,-15621255 }, + }, + { + { 6490081,11940286,25495923,-7726360,8668373,-8751316,3367603,6970005,-1691065,-9004790 }, + { 1656497,13457317,15370807,6364910,13605745,8362338,-19174622,-5475723,-16796596,-5031438 }, + { -22273315,-13524424,-64685,-4334223,-18605636,-10921968,-20571065,-7007978,-99853,-10237333 }, + }, + { + { 17747465,10039260,19368299,-4050591,-20630635,-16041286,31992683,-15857976,-29260363,-5511971 }, + { 31932027,-4986141,-19612382,16366580,22023614,88450,11371999,-3744247,4882242,-10626905 }, + { 29796507,37186,19818052,10115756,-11829032,3352736,18551198,3272828,-5190932,-4162409 }, + }, + { + { 12501286,4044383,-8612957,-13392385,-32430052,5136599,-19230378,-3529697,330070,-3659409 }, + { 6384877,2899513,17807477,7663917,-2358888,12363165,25366522,-8573892,-271295,12071499 }, + { -8365515,-4042521,25133448,-4517355,-6211027,2265927,-32769618,1936675,-5159697,3829363 }, + }, + { + { 28425966,-5835433,-577090,-4697198,-14217555,6870930,7921550,-6567787,26333140,14267664 }, + { -11067219,11871231,27385719,-10559544,-4585914,-11189312,10004786,-8709488,-21761224,8930324 }, + { -21197785,-16396035,25654216,-1725397,12282012,11008919,1541940,4757911,-26491501,-16408940 }, + }, + { + { 13537262,-7759490,-20604840,10961927,-5922820,-13218065,-13156584,6217254,-15943699,13814990 }, + { -17422573,15157790,18705543,29619,24409717,-260476,27361681,9257833,-1956526,-1776914 }, + { -25045300,-10191966,15366585,15166509,-13105086,8423556,-29171540,12361135,-18685978,4578290 }, + }, + { + { 24579768,3711570,1342322,-11180126,-27005135,14124956,-22544529,14074919,21964432,8235257 }, + { -6528613,-2411497,9442966,-5925588,12025640,-1487420,-2981514,-1669206,13006806,2355433 }, + { -16304899,-13605259,-6632427,-5142349,16974359,-10911083,27202044,1719366,1141648,-12796236 }, + }, + { + { -12863944,-13219986,-8318266,-11018091,-6810145,-4843894,13475066,-3133972,32674895,13715045 }, + { 11423335,-5468059,32344216,8962751,24989809,9241752,-13265253,16086212,-28740881,-15642093 }, + { -1409668,12530728,-6368726,10847387,19531186,-14132160,-11709148,7791794,-27245943,4383347 }, + }, +}, +{ + { + { -28970898,5271447,-1266009,-9736989,-12455236,16732599,-4862407,-4906449,27193557,6245191 }, + { -15193956,5362278,-1783893,2695834,4960227,12840725,23061898,3260492,22510453,8577507 }, + { -12632451,11257346,-32692994,13548177,-721004,10879011,31168030,13952092,-29571492,-3635906 }, + }, + { + { 3877321,-9572739,32416692,5405324,-11004407,-13656635,3759769,11935320,5611860,8164018 }, + { -16275802,14667797,15906460,12155291,-22111149,-9039718,32003002,-8832289,5773085,-8422109 }, + { -23788118,-8254300,1950875,8937633,18686727,16459170,-905725,12376320,31632953,190926 }, + }, + { + { -24593607,-16138885,-8423991,13378746,14162407,6901328,-8288749,4508564,-25341555,-3627528 }, + { 8884438,-5884009,6023974,10104341,-6881569,-4941533,18722941,-14786005,-1672488,827625 }, + { -32720583,-16289296,-32503547,7101210,13354605,2659080,-1800575,-14108036,-24878478,1541286 }, + }, + { + { 2901347,-1117687,3880376,-10059388,-17620940,-3612781,-21802117,-3567481,20456845,-1885033 }, + { 27019610,12299467,-13658288,-1603234,-12861660,-4861471,-19540150,-5016058,29439641,15138866 }, + { 21536104,-6626420,-32447818,-10690208,-22408077,5175814,-5420040,-16361163,7779328,109896 }, + }, + { + { 30279744,14648750,-8044871,6425558,13639621,-743509,28698390,12180118,23177719,-554075 }, + { 26572847,3405927,-31701700,12890905,-19265668,5335866,-6493768,2378492,4439158,-13279347 }, + { -22716706,3489070,-9225266,-332753,18875722,-1140095,14819434,-12731527,-17717757,-5461437 }, + }, + { + { -5056483,16566551,15953661,3767752,-10436499,15627060,-820954,2177225,8550082,-15114165 }, + { -18473302,16596775,-381660,15663611,22860960,15585581,-27844109,-3582739,-23260460,-8428588 }, + { -32480551,15707275,-8205912,-5652081,29464558,2713815,-22725137,15860482,-21902570,1494193 }, + }, + { + { -19562091,-14087393,-25583872,-9299552,13127842,759709,21923482,16529112,8742704,12967017 }, + { -28464899,1553205,32536856,-10473729,-24691605,-406174,-8914625,-2933896,-29903758,15553883 }, + { 21877909,3230008,9881174,10539357,-4797115,2841332,11543572,14513274,19375923,-12647961 }, + }, + { + { 8832269,-14495485,13253511,5137575,5037871,4078777,24880818,-6222716,2862653,9455043 }, + { 29306751,5123106,20245049,-14149889,9592566,8447059,-2077124,-2990080,15511449,4789663 }, + { -20679756,7004547,8824831,-9434977,-4045704,-3750736,-5754762,108893,23513200,16652362 }, + }, +}, +{ + { + { -33256173,4144782,-4476029,-6579123,10770039,-7155542,-6650416,-12936300,-18319198,10212860 }, + { 2756081,8598110,7383731,-6859892,22312759,-1105012,21179801,2600940,-9988298,-12506466 }, + { -24645692,13317462,-30449259,-15653928,21365574,-10869657,11344424,864440,-2499677,-16710063 }, + }, + { + { -26432803,6148329,-17184412,-14474154,18782929,-275997,-22561534,211300,2719757,4940997 }, + { -1323882,3911313,-6948744,14759765,-30027150,7851207,21690126,8518463,26699843,5276295 }, + { -13149873,-6429067,9396249,365013,24703301,-10488939,1321586,149635,-15452774,7159369 }, + }, + { + { 9987780,-3404759,17507962,9505530,9731535,-2165514,22356009,8312176,22477218,-8403385 }, + { 18155857,-16504990,19744716,9006923,15154154,-10538976,24256460,-4864995,-22548173,9334109 }, + { 2986088,-4911893,10776628,-3473844,10620590,-7083203,-21413845,14253545,-22587149,536906 }, + }, + { + { 4377756,8115836,24567078,15495314,11625074,13064599,7390551,10589625,10838060,-15420424 }, + { -19342404,867880,9277171,-3218459,-14431572,-1986443,19295826,-15796950,6378260,699185 }, + { 7895026,4057113,-7081772,-13077756,-17886831,-323126,-716039,15693155,-5045064,-13373962 }, + }, + { + { -7737563,-5869402,-14566319,-7406919,11385654,13201616,31730678,-10962840,-3918636,-9669325 }, + { 10188286,-15770834,-7336361,13427543,22223443,14896287,30743455,7116568,-21786507,5427593 }, + { 696102,13206899,27047647,-10632082,15285305,-9853179,10798490,-4578720,19236243,12477404 }, + }, + { + { -11229439,11243796,-17054270,-8040865,-788228,-8167967,-3897669,11180504,-23169516,7733644 }, + { 17800790,-14036179,-27000429,-11766671,23887827,3149671,23466177,-10538171,10322027,15313801 }, + { 26246234,11968874,32263343,-5468728,6830755,-13323031,-15794704,-101982,-24449242,10890804 }, + }, + { + { -31365647,10271363,-12660625,-6267268,16690207,-13062544,-14982212,16484931,25180797,-5334884 }, + { -586574,10376444,-32586414,-11286356,19801893,10997610,2276632,9482883,316878,13820577 }, + { -9882808,-4510367,-2115506,16457136,-11100081,11674996,30756178,-7515054,30696930,-3712849 }, + }, + { + { 32988917,-9603412,12499366,7910787,-10617257,-11931514,-7342816,-9985397,-32349517,7392473 }, + { -8855661,15927861,9866406,-3649411,-2396914,-16655781,-30409476,-9134995,25112947,-2926644 }, + { -2504044,-436966,25621774,-5678772,15085042,-5479877,-24884878,-13526194,5537438,-13914319 }, + }, +}, +{ + { + { -11225584,2320285,-9584280,10149187,-33444663,5808648,-14876251,-1729667,31234590,6090599 }, + { -9633316,116426,26083934,2897444,-6364437,-2688086,609721,15878753,-6970405,-9034768 }, + { -27757857,247744,-15194774,-9002551,23288161,-10011936,-23869595,6503646,20650474,1804084 }, + }, + { + { -27589786,15456424,8972517,8469608,15640622,4439847,3121995,-10329713,27842616,-202328 }, + { -15306973,2839644,22530074,10026331,4602058,5048462,28248656,5031932,-11375082,12714369 }, + { 20807691,-7270825,29286141,11421711,-27876523,-13868230,-21227475,1035546,-19733229,12796920 }, + }, + { + { 12076899,-14301286,-8785001,-11848922,-25012791,16400684,-17591495,-12899438,3480665,-15182815 }, + { -32361549,5457597,28548107,7833186,7303070,-11953545,-24363064,-15921875,-33374054,2771025 }, + { -21389266,421932,26597266,6860826,22486084,-6737172,-17137485,-4210226,-24552282,15673397 }, + }, + { + { -20184622,2338216,19788685,-9620956,-4001265,-8740893,-20271184,4733254,3727144,-12934448 }, + { 6120119,814863,-11794402,-622716,6812205,-15747771,2019594,7975683,31123697,-10958981 }, + { 30069250,-11435332,30434654,2958439,18399564,-976289,12296869,9204260,-16432438,9648165 }, + }, + { + { 32705432,-1550977,30705658,7451065,-11805606,9631813,3305266,5248604,-26008332,-11377501 }, + { 17219865,2375039,-31570947,-5575615,-19459679,9219903,294711,15298639,2662509,-16297073 }, + { -1172927,-7558695,-4366770,-4287744,-21346413,-8434326,32087529,-1222777,32247248,-14389861 }, + }, + { + { 14312628,1221556,17395390,-8700143,-4945741,-8684635,-28197744,-9637817,-16027623,-13378845 }, + { -1428825,-9678990,-9235681,6549687,-7383069,-468664,23046502,9803137,17597934,2346211 }, + { 18510800,15337574,26171504,981392,-22241552,7827556,-23491134,-11323352,3059833,-11782870 }, + }, + { + { 10141598,6082907,17829293,-1947643,9830092,13613136,-25556636,-5544586,-33502212,3592096 }, + { 33114168,-15889352,-26525686,-13343397,33076705,8716171,1151462,1521897,-982665,-6837803 }, + { -32939165,-4255815,23947181,-324178,-33072974,-12305637,-16637686,3891704,26353178,693168 }, + }, + { + { 30374239,1595580,-16884039,13186931,4600344,406904,9585294,-400668,31375464,14369965 }, + { -14370654,-7772529,1510301,6434173,-18784789,-6262728,32732230,-13108839,17901441,16011505 }, + { 18171223,-11934626,-12500402,15197122,-11038147,-15230035,-19172240,-16046376,8764035,12309598 }, + }, +}, +{ + { + { 5975908,-5243188,-19459362,-9681747,-11541277,14015782,-23665757,1228319,17544096,-10593782 }, + { 5811932,-1715293,3442887,-2269310,-18367348,-8359541,-18044043,-15410127,-5565381,12348900 }, + { -31399660,11407555,25755363,6891399,-3256938,14872274,-24849353,8141295,-10632534,-585479 }, + }, + { + { -12675304,694026,-5076145,13300344,14015258,-14451394,-9698672,-11329050,30944593,1130208 }, + { 8247766,-6710942,-26562381,-7709309,-14401939,-14648910,4652152,2488540,23550156,-271232 }, + { 17294316,-3788438,7026748,15626851,22990044,113481,2267737,-5908146,-408818,-137719 }, + }, + { + { 16091085,-16253926,18599252,7340678,2137637,-1221657,-3364161,14550936,3260525,-7166271 }, + { -4910104,-13332887,18550887,10864893,-16459325,-7291596,-23028869,-13204905,-12748722,2701326 }, + { -8574695,16099415,4629974,-16340524,-20786213,-6005432,-10018363,9276971,11329923,1862132 }, + }, + { + { 14763076,-15903608,-30918270,3689867,3511892,10313526,-21951088,12219231,-9037963,-940300 }, + { 8894987,-3446094,6150753,3013931,301220,15693451,-31981216,-2909717,-15438168,11595570 }, + { 15214962,3537601,-26238722,-14058872,4418657,-15230761,13947276,10730794,-13489462,-4363670 }, + }, + { + { -2538306,7682793,32759013,263109,-29984731,-7955452,-22332124,-10188635,977108,699994 }, + { -12466472,4195084,-9211532,550904,-15565337,12917920,19118110,-439841,-30534533,-14337913 }, + { 31788461,-14507657,4799989,7372237,8808585,-14747943,9408237,-10051775,12493932,-5409317 }, + }, + { + { -25680606,5260744,-19235809,-6284470,-3695942,16566087,27218280,2607121,29375955,6024730 }, + { 842132,-2794693,-4763381,-8722815,26332018,-12405641,11831880,6985184,-9940361,2854096 }, + { -4847262,-7969331,2516242,-5847713,9695691,-7221186,16512645,960770,12121869,16648078 }, + }, + { + { -15218652,14667096,-13336229,2013717,30598287,-464137,-31504922,-7882064,20237806,2838411 }, + { -19288047,4453152,15298546,-16178388,22115043,-15972604,12544294,-13470457,1068881,-12499905 }, + { -9558883,-16518835,33238498,13506958,30505848,-1114596,-8486907,-2630053,12521378,4845654 }, + }, + { + { -28198521,10744108,-2958380,10199664,7759311,-13088600,3409348,-873400,-6482306,-12885870 }, + { -23561822,6230156,-20382013,10655314,-24040585,-11621172,10477734,-1240216,-3113227,13974498 }, + { 12966261,15550616,-32038948,-1615346,21025980,-629444,5642325,7188737,18895762,12629579 }, + }, +}, +{ + { + { 14741879,-14946887,22177208,-11721237,1279741,8058600,11758140,789443,32195181,3895677 }, + { 10758205,15755439,-4509950,9243698,-4879422,6879879,-2204575,-3566119,-8982069,4429647 }, + { -2453894,15725973,-20436342,-10410672,-5803908,-11040220,-7135870,-11642895,18047436,-15281743 }, + }, + { + { -25173001,-11307165,29759956,11776784,-22262383,-15820455,10993114,-12850837,-17620701,-9408468 }, + { 21987233,700364,-24505048,14972008,-7774265,-5718395,32155026,2581431,-29958985,8773375 }, + { -25568350,454463,-13211935,16126715,25240068,8594567,20656846,12017935,-7874389,-13920155 }, + }, + { + { 6028182,6263078,-31011806,-11301710,-818919,2461772,-31841174,-5468042,-1721788,-2776725 }, + { -12278994,16624277,987579,-5922598,32908203,1248608,7719845,-4166698,28408820,6816612 }, + { -10358094,-8237829,19549651,-12169222,22082623,16147817,20613181,13982702,-10339570,5067943 }, + }, + { + { -30505967,-3821767,12074681,13582412,-19877972,2443951,-19719286,12746132,5331210,-10105944 }, + { 30528811,3601899,-1957090,4619785,-27361822,-15436388,24180793,-12570394,27679908,-1648928 }, + { 9402404,-13957065,32834043,10838634,-26580150,-13237195,26653274,-8685565,22611444,-12715406 }, + }, + { + { 22190590,1118029,22736441,15130463,-30460692,-5991321,19189625,-4648942,4854859,6622139 }, + { -8310738,-2953450,-8262579,-3388049,-10401731,-271929,13424426,-3567227,26404409,13001963 }, + { -31241838,-15415700,-2994250,8939346,11562230,-12840670,-26064365,-11621720,-15405155,11020693 }, + }, + { + { 1866042,-7949489,-7898649,-10301010,12483315,13477547,3175636,-12424163,28761762,1406734 }, + { -448555,-1777666,13018551,3194501,-9580420,-11161737,24760585,-4347088,25577411,-13378680 }, + { -24290378,4759345,-690653,-1852816,2066747,10693769,-29595790,9884936,-9368926,4745410 }, + }, + { + { -9141284,6049714,-19531061,-4341411,-31260798,9944276,-15462008,-11311852,10931924,-11931931 }, + { -16561513,14112680,-8012645,4817318,-8040464,-11414606,-22853429,10856641,-20470770,13434654 }, + { 22759489,-10073434,-16766264,-1871422,13637442,-10168091,1765144,-12654326,28445307,-5364710 }, + }, + { + { 29875063,12493613,2795536,-3786330,1710620,15181182,-10195717,-8788675,9074234,1167180 }, + { -26205683,11014233,-9842651,-2635485,-26908120,7532294,-18716888,-9535498,3843903,9367684 }, + { -10969595,-6403711,9591134,9582310,11349256,108879,16235123,8601684,-139197,4242895 }, + }, +}, +{ + { + { 22092954,-13191123,-2042793,-11968512,32186753,-11517388,-6574341,2470660,-27417366,16625501 }, + { -11057722,3042016,13770083,-9257922,584236,-544855,-7770857,2602725,-27351616,14247413 }, + { 6314175,-10264892,-32772502,15957557,-10157730,168750,-8618807,14290061,27108877,-1180880 }, + }, + { + { -8586597,-7170966,13241782,10960156,-32991015,-13794596,33547976,-11058889,-27148451,981874 }, + { 22833440,9293594,-32649448,-13618667,-9136966,14756819,-22928859,-13970780,-10479804,-16197962 }, + { -7768587,3326786,-28111797,10783824,19178761,14905060,22680049,13906969,-15933690,3797899 }, + }, + { + { 21721356,-4212746,-12206123,9310182,-3882239,-13653110,23740224,-2709232,20491983,-8042152 }, + { 9209270,-15135055,-13256557,-6167798,-731016,15289673,25947805,15286587,30997318,-6703063 }, + { 7392032,16618386,23946583,-8039892,-13265164,-1533858,-14197445,-2321576,17649998,-250080 }, + }, + { + { -9301088,-14193827,30609526,-3049543,-25175069,-1283752,-15241566,-9525724,-2233253,7662146 }, + { -17558673,1763594,-33114336,15908610,-30040870,-12174295,7335080,-8472199,-3174674,3440183 }, + { -19889700,-5977008,-24111293,-9688870,10799743,-16571957,40450,-4431835,4862400,1133 }, + }, + { + { -32856209,-7873957,-5422389,14860950,-16319031,7956142,7258061,311861,-30594991,-7379421 }, + { -3773428,-1565936,28985340,7499440,24445838,9325937,29727763,16527196,18278453,15405622 }, + { -4381906,8508652,-19898366,-3674424,-5984453,15149970,-13313598,843523,-21875062,13626197 }, + }, + { + { 2281448,-13487055,-10915418,-2609910,1879358,16164207,-10783882,3953792,13340839,15928663 }, + { 31727126,-7179855,-18437503,-8283652,2875793,-16390330,-25269894,-7014826,-23452306,5964753 }, + { 4100420,-5959452,-17179337,6017714,-18705837,12227141,-26684835,11344144,2538215,-7570755 }, + }, + { + { -9433605,6123113,11159803,-2156608,30016280,14966241,-20474983,1485421,-629256,-15958862 }, + { -26804558,4260919,11851389,9658551,-32017107,16367492,-20205425,-13191288,11659922,-11115118 }, + { 26180396,10015009,-30844224,-8581293,5418197,9480663,2231568,-10170080,33100372,-1306171 }, + }, + { + { 15121113,-5201871,-10389905,15427821,-27509937,-15992507,21670947,4486675,-5931810,-14466380 }, + { 16166486,-9483733,-11104130,6023908,-31926798,-1364923,2340060,-16254968,-10735770,-10039824 }, + { 28042865,-3557089,-12126526,12259706,-3717498,-6945899,6766453,-8689599,18036436,5803270 }, + }, +}, +{ + { + { -817581,6763912,11803561,1585585,10958447,-2671165,23855391,4598332,-6159431,-14117438 }, + { -31031306,-14256194,17332029,-2383520,31312682,-5967183,696309,50292,-20095739,11763584 }, + { -594563,-2514283,-32234153,12643980,12650761,14811489,665117,-12613632,-19773211,-10713562 }, + }, + { + { 30464590,-11262872,-4127476,-12734478,19835327,-7105613,-24396175,2075773,-17020157,992471 }, + { 18357185,-6994433,7766382,16342475,-29324918,411174,14578841,8080033,-11574335,-10601610 }, + { 19598397,10334610,12555054,2555664,18821899,-10339780,21873263,16014234,26224780,16452269 }, + }, + { + { -30223925,5145196,5944548,16385966,3976735,2009897,-11377804,-7618186,-20533829,3698650 }, + { 14187449,3448569,-10636236,-10810935,-22663880,-3433596,7268410,-10890444,27394301,12015369 }, + { 19695761,16087646,28032085,12999827,6817792,11427614,20244189,-1312777,-13259127,-3402461 }, + }, + { + { 30860103,12735208,-1888245,-4699734,-16974906,2256940,-8166013,12298312,-8550524,-10393462 }, + { -5719826,-11245325,-1910649,15569035,26642876,-7587760,-5789354,-15118654,-4976164,12651793 }, + { -2848395,9953421,11531313,-5282879,26895123,-12697089,-13118820,-16517902,9768698,-2533218 }, + }, + { + { -24719459,1894651,-287698,-4704085,15348719,-8156530,32767513,12765450,4940095,10678226 }, + { 18860224,15980149,-18987240,-1562570,-26233012,-11071856,-7843882,13944024,-24372348,16582019 }, + { -15504260,4970268,-29893044,4175593,-20993212,-2199756,-11704054,15444560,-11003761,7989037 }, + }, + { + { 31490452,5568061,-2412803,2182383,-32336847,4531686,-32078269,6200206,-19686113,-14800171 }, + { -17308668,-15879940,-31522777,-2831,-32887382,16375549,8680158,-16371713,28550068,-6857132 }, + { -28126887,-5688091,16837845,-1820458,-6850681,12700016,-30039981,4364038,1155602,5988841 }, + }, + { + { 21890435,-13272907,-12624011,12154349,-7831873,15300496,23148983,-4470481,24618407,8283181 }, + { -33136107,-10512751,9975416,6841041,-31559793,16356536,3070187,-7025928,1466169,10740210 }, + { -1509399,-15488185,-13503385,-10655916,32799044,909394,-13938903,-5779719,-32164649,-15327040 }, + }, + { + { 3960823,-14267803,-28026090,-15918051,-19404858,13146868,15567327,951507,-3260321,-573935 }, + { 24740841,5052253,-30094131,8961361,25877428,6165135,-24368180,14397372,-7380369,-6144105 }, + { -28888365,3510803,-28103278,-1158478,-11238128,-10631454,-15441463,-14453128,-1625486,-6494814 }, + }, +}, +{ + { + { 793299,-9230478,8836302,-6235707,-27360908,-2369593,33152843,-4885251,-9906200,-621852 }, + { 5666233,525582,20782575,-8038419,-24538499,14657740,16099374,1468826,-6171428,-15186581 }, + { -4859255,-3779343,-2917758,-6748019,7778750,11688288,-30404353,-9871238,-1558923,-9863646 }, + }, + { + { 10896332,-7719704,824275,472601,-19460308,3009587,25248958,14783338,-30581476,-15757844 }, + { 10566929,12612572,-31944212,11118703,-12633376,12362879,21752402,8822496,24003793,14264025 }, + { 27713862,-7355973,-11008240,9227530,27050101,2504721,23886875,-13117525,13958495,-5732453 }, + }, + { + { -23481610,4867226,-27247128,3900521,29838369,-8212291,-31889399,-10041781,7340521,-15410068 }, + { 4646514,-8011124,-22766023,-11532654,23184553,8566613,31366726,-1381061,-15066784,-10375192 }, + { -17270517,12723032,-16993061,14878794,21619651,-6197576,27584817,3093888,-8843694,3849921 }, + }, + { + { -9064912,2103172,25561640,-15125738,-5239824,9582958,32477045,-9017955,5002294,-15550259 }, + { -12057553,-11177906,21115585,-13365155,8808712,-12030708,16489530,13378448,-25845716,12741426 }, + { -5946367,10645103,-30911586,15390284,-3286982,-7118677,24306472,15852464,28834118,-7646072 }, + }, + { + { -17335748,-9107057,-24531279,9434953,-8472084,-583362,-13090771,455841,20461858,5491305 }, + { 13669248,-16095482,-12481974,-10203039,-14569770,-11893198,-24995986,11293807,-28588204,-9421832 }, + { 28497928,6272777,-33022994,14470570,8906179,-1225630,18504674,-14165166,29867745,-8795943 }, + }, + { + { -16207023,13517196,-27799630,-13697798,24009064,-6373891,-6367600,-13175392,22853429,-4012011 }, + { 24191378,16712145,-13931797,15217831,14542237,1646131,18603514,-11037887,12876623,-2112447 }, + { 17902668,4518229,-411702,-2829247,26878217,5258055,-12860753,608397,16031844,3723494 }, + }, + { + { -28632773,12763728,-20446446,7577504,33001348,-13017745,17558842,-7872890,23896954,-4314245 }, + { -20005381,-12011952,31520464,605201,2543521,5991821,-2945064,7229064,-9919646,-8826859 }, + { 28816045,298879,-28165016,-15920938,19000928,-1665890,-12680833,-2949325,-18051778,-2082915 }, + }, + { + { 16000882,-344896,3493092,-11447198,-29504595,-13159789,12577740,16041268,-19715240,7847707 }, + { 10151868,10572098,27312476,7922682,14825339,4723128,-32855931,-6519018,-10020567,3852848 }, + { -11430470,15697596,-21121557,-4420647,5386314,15063598,16514493,-15932110,29330899,-15076224 }, + }, +}, +{ + { + { -25499735,-4378794,-15222908,-6901211,16615731,2051784,3303702,15490,-27548796,12314391 }, + { 15683520,-6003043,18109120,-9980648,15337968,-5997823,-16717435,15921866,16103996,-3731215 }, + { -23169824,-10781249,13588192,-1628807,-3798557,-1074929,-19273607,5402699,-29815713,-9841101 }, + }, + { + { 23190676,2384583,-32714340,3462154,-29903655,-1529132,-11266856,8911517,-25205859,2739713 }, + { 21374101,-3554250,-33524649,9874411,15377179,11831242,-33529904,6134907,4931255,11987849 }, + { -7732,-2978858,-16223486,7277597,105524,-322051,-31480539,13861388,-30076310,10117930 }, + }, + { + { -29501170,-10744872,-26163768,13051539,-25625564,5089643,-6325503,6704079,12890019,15728940 }, + { -21972360,-11771379,-951059,-4418840,14704840,2695116,903376,-10428139,12885167,8311031 }, + { -17516482,5352194,10384213,-13811658,7506451,13453191,26423267,4384730,1888765,-5435404 }, + }, + { + { -25817338,-3107312,-13494599,-3182506,30896459,-13921729,-32251644,-12707869,-19464434,-3340243 }, + { -23607977,-2665774,-526091,4651136,5765089,4618330,6092245,14845197,17151279,-9854116 }, + { -24830458,-12733720,-15165978,10367250,-29530908,-265356,22825805,-7087279,-16866484,16176525 }, + }, + { + { -23583256,6564961,20063689,3798228,-4740178,7359225,2006182,-10363426,-28746253,-10197509 }, + { -10626600,-4486402,-13320562,-5125317,3432136,-6393229,23632037,-1940610,32808310,1099883 }, + { 15030977,5768825,-27451236,-2887299,-6427378,-15361371,-15277896,-6809350,2051441,-15225865 }, + }, + { + { -3362323,-7239372,7517890,9824992,23555850,295369,5148398,-14154188,-22686354,16633660 }, + { 4577086,-16752288,13249841,-15304328,19958763,-14537274,18559670,-10759549,8402478,-9864273 }, + { -28406330,-1051581,-26790155,-907698,-17212414,-11030789,9453451,-14980072,17983010,9967138 }, + }, + { + { -25762494,6524722,26585488,9969270,24709298,1220360,-1677990,7806337,17507396,3651560 }, + { -10420457,-4118111,14584639,15971087,-15768321,8861010,26556809,-5574557,-18553322,-11357135 }, + { 2839101,14284142,4029895,3472686,14402957,12689363,-26642121,8459447,-5605463,-7621941 }, + }, + { + { -4839289,-3535444,9744961,2871048,25113978,3187018,-25110813,-849066,17258084,-7977739 }, + { 18164541,-10595176,-17154882,-1542417,19237078,-9745295,23357533,-15217008,26908270,12150756 }, + { -30264870,-7647865,5112249,-7036672,-1499807,-6974257,43168,-5537701,-32302074,16215819 }, + }, +}, +{ + { + { -6898905,9824394,-12304779,-4401089,-31397141,-6276835,32574489,12532905,-7503072,-8675347 }, + { -27343522,-16515468,-27151524,-10722951,946346,16291093,254968,7168080,21676107,-1943028 }, + { 21260961,-8424752,-16831886,-11920822,-23677961,3968121,-3651949,-6215466,-3556191,-7913075 }, + }, + { + { 16544754,13250366,-16804428,15546242,-4583003,12757258,-2462308,-8680336,-18907032,-9662799 }, + { -2415239,-15577728,18312303,4964443,-15272530,-12653564,26820651,16690659,25459437,-4564609 }, + { -25144690,11425020,28423002,-11020557,-6144921,-15826224,9142795,-2391602,-6432418,-1644817 }, + }, + { + { -23104652,6253476,16964147,-3768872,-25113972,-12296437,-27457225,-16344658,6335692,7249989 }, + { -30333227,13979675,7503222,-12368314,-11956721,-4621693,-30272269,2682242,25993170,-12478523 }, + { 4364628,5930691,32304656,-10044554,-8054781,15091131,22857016,-10598955,31820368,15075278 }, + }, + { + { 31879134,-8918693,17258761,90626,-8041836,-4917709,24162788,-9650886,-17970238,12833045 }, + { 19073683,14851414,-24403169,-11860168,7625278,11091125,-19619190,2074449,-9413939,14905377 }, + { 24483667,-11935567,-2518866,-11547418,-1553130,15355506,-25282080,9253129,27628530,-7555480 }, + }, + { + { 17597607,8340603,19355617,552187,26198470,-3176583,4593324,-9157582,-14110875,15297016 }, + { 510886,14337390,-31785257,16638632,6328095,2713355,-20217417,-11864220,8683221,2921426 }, + { 18606791,11874196,27155355,-5281482,-24031742,6265446,-25178240,-1278924,4674690,13890525 }, + }, + { + { 13609624,13069022,-27372361,-13055908,24360586,9592974,14977157,9835105,4389687,288396 }, + { 9922506,-519394,13613107,5883594,-18758345,-434263,-12304062,8317628,23388070,16052080 }, + { 12720016,11937594,-31970060,-5028689,26900120,8561328,-20155687,-11632979,-14754271,-10812892 }, + }, + { + { 15961858,14150409,26716931,-665832,-22794328,13603569,11829573,7467844,-28822128,929275 }, + { 11038231,-11582396,-27310482,-7316562,-10498527,-16307831,-23479533,-9371869,-21393143,2465074 }, + { 20017163,-4323226,27915242,1529148,12396362,15675764,13817261,-9658066,2463391,-4622140 }, + }, + { + { -16358878,-12663911,-12065183,4996454,-1256422,1073572,9583558,12851107,4003896,12673717 }, + { -1731589,-15155870,-3262930,16143082,19294135,13385325,14741514,-9103726,7903886,2348101 }, + { 24536016,-16515207,12715592,-3862155,1511293,10047386,-3842346,-7129159,-28377538,10048127 }, + }, +}, +{ + { + { -12622226,-6204820,30718825,2591312,-10617028,12192840,18873298,-7297090,-32297756,15221632 }, + { -26478122,-11103864,11546244,-1852483,9180880,7656409,-21343950,2095755,29769758,6593415 }, + { -31994208,-2907461,4176912,3264766,12538965,-868111,26312345,-6118678,30958054,8292160 }, + }, + { + { 31429822,-13959116,29173532,15632448,12174511,-2760094,32808831,3977186,26143136,-3148876 }, + { 22648901,1402143,-22799984,13746059,7936347,365344,-8668633,-1674433,-3758243,-2304625 }, + { -15491917,8012313,-2514730,-12702462,-23965846,-10254029,-1612713,-1535569,-16664475,8194478 }, + }, + { + { 27338066,-7507420,-7414224,10140405,-19026427,-6589889,27277191,8855376,28572286,3005164 }, + { 26287124,4821776,25476601,-4145903,-3764513,-15788984,-18008582,1182479,-26094821,-13079595 }, + { -7171154,3178080,23970071,6201893,-17195577,-4489192,-21876275,-13982627,32208683,-1198248 }, + }, + { + { -16657702,2817643,-10286362,14811298,6024667,13349505,-27315504,-10497842,-27672585,-11539858 }, + { 15941029,-9405932,-21367050,8062055,31876073,-238629,-15278393,-1444429,15397331,-4130193 }, + { 8934485,-13485467,-23286397,-13423241,-32446090,14047986,31170398,-1441021,-27505566,15087184 }, + }, + { + { -18357243,-2156491,24524913,-16677868,15520427,-6360776,-15502406,11461896,16788528,-5868942 }, + { -1947386,16013773,21750665,3714552,-17401782,-16055433,-3770287,-10323320,31322514,-11615635 }, + { 21426655,-5650218,-13648287,-5347537,-28812189,-4920970,-18275391,-14621414,13040862,-12112948 }, + }, + { + { 11293895,12478086,-27136401,15083750,-29307421,14748872,14555558,-13417103,1613711,4896935 }, + { -25894883,15323294,-8489791,-8057900,25967126,-13425460,2825960,-4897045,-23971776,-11267415 }, + { -15924766,-5229880,-17443532,6410664,3622847,10243618,20615400,12405433,-23753030,-8436416 }, + }, + { + { -7091295,12556208,-20191352,9025187,-17072479,4333801,4378436,2432030,23097949,-566018 }, + { 4565804,-16025654,20084412,-7842817,1724999,189254,24767264,10103221,-18512313,2424778 }, + { 366633,-11976806,8173090,-6890119,30788634,5745705,-7168678,1344109,-3642553,12412659 }, + }, + { + { -24001791,7690286,14929416,-168257,-32210835,-13412986,24162697,-15326504,-3141501,11179385 }, + { 18289522,-14724954,8056945,16430056,-21729724,7842514,-6001441,-1486897,-18684645,-11443503 }, + { 476239,6601091,-6152790,-9723375,17503545,-4863900,27672959,13403813,11052904,5219329 }, + }, +}, +{ + { + { 20678546,-8375738,-32671898,8849123,-5009758,14574752,31186971,-3973730,9014762,-8579056 }, + { -13644050,-10350239,-15962508,5075808,-1514661,-11534600,-33102500,9160280,8473550,-3256838 }, + { 24900749,14435722,17209120,-15292541,-22592275,9878983,-7689309,-16335821,-24568481,11788948 }, + }, + { + { -3118155,-11395194,-13802089,14797441,9652448,-6845904,-20037437,10410733,-24568470,-1458691 }, + { -15659161,16736706,-22467150,10215878,-9097177,7563911,11871841,-12505194,-18513325,8464118 }, + { -23400612,8348507,-14585951,-861714,-3950205,-6373419,14325289,8628612,33313881,-8370517 }, + }, + { + { -20186973,-4967935,22367356,5271547,-1097117,-4788838,-24805667,-10236854,-8940735,-5818269 }, + { -6948785,-1795212,-32625683,-16021179,32635414,-7374245,15989197,-12838188,28358192,-4253904 }, + { -23561781,-2799059,-32351682,-1661963,-9147719,10429267,-16637684,4072016,-5351664,5596589 }, + }, + { + { -28236598,-3390048,12312896,6213178,3117142,16078565,29266239,2557221,1768301,15373193 }, + { -7243358,-3246960,-4593467,-7553353,-127927,-912245,-1090902,-4504991,-24660491,3442910 }, + { -30210571,5124043,14181784,8197961,18964734,-11939093,22597931,7176455,-18585478,13365930 }, + }, + { + { -7877390,-1499958,8324673,4690079,6261860,890446,24538107,-8570186,-9689599,-3031667 }, + { 25008904,-10771599,-4305031,-9638010,16265036,15721635,683793,-11823784,15723479,-15163481 }, + { -9660625,12374379,-27006999,-7026148,-7724114,-12314514,11879682,5400171,519526,-1235876 }, + }, + { + { 22258397,-16332233,-7869817,14613016,-22520255,-2950923,-20353881,7315967,16648397,7605640 }, + { -8081308,-8464597,-8223311,9719710,19259459,-15348212,23994942,-5281555,-9468848,4763278 }, + { -21699244,9220969,-15730624,1084137,-25476107,-2852390,31088447,-7764523,-11356529,728112 }, + }, + { + { 26047220,-11751471,-6900323,-16521798,24092068,9158119,-4273545,-12555558,-29365436,-5498272 }, + { 17510331,-322857,5854289,8403524,17133918,-3112612,-28111007,12327945,10750447,10014012 }, + { -10312768,3936952,9156313,-8897683,16498692,-994647,-27481051,-666732,3424691,7540221 }, + }, + { + { 30322361,-6964110,11361005,-4143317,7433304,4989748,-7071422,-16317219,-9244265,15258046 }, + { 13054562,-2779497,19155474,469045,-12482797,4566042,5631406,2711395,1062915,-5136345 }, + { -19240248,-11254599,-29509029,-7499965,-5835763,13005411,-6066489,12194497,32960380,1459310 }, + }, +}, +{ + { + { 19852034,7027924,23669353,10020366,8586503,-6657907,394197,-6101885,18638003,-11174937 }, + { 31395534,15098109,26581030,8030562,-16527914,-5007134,9012486,-7584354,-6643087,-5442636 }, + { -9192165,-2347377,-1997099,4529534,25766844,607986,-13222,9677543,-32294889,-6456008 }, + }, + { + { -2444496,-149937,29348902,8186665,1873760,12489863,-30934579,-7839692,-7852844,-8138429 }, + { -15236356,-15433509,7766470,746860,26346930,-10221762,-27333451,10754588,-9431476,5203576 }, + { 31834314,14135496,-770007,5159118,20917671,-16768096,-7467973,-7337524,31809243,7347066 }, + }, + { + { -9606723,-11874240,20414459,13033986,13716524,-11691881,19797970,-12211255,15192876,-2087490 }, + { -12663563,-2181719,1168162,-3804809,26747877,-14138091,10609330,12694420,33473243,-13382104 }, + { 33184999,11180355,15832085,-11385430,-1633671,225884,15089336,-11023903,-6135662,14480053 }, + }, + { + { 31308717,-5619998,31030840,-1897099,15674547,-6582883,5496208,13685227,27595050,8737275 }, + { -20318852,-15150239,10933843,-16178022,8335352,-7546022,-31008351,-12610604,26498114,66511 }, + { 22644454,-8761729,-16671776,4884562,-3105614,-13559366,30540766,-4286747,-13327787,-7515095 }, + }, + { + { -28017847,9834845,18617207,-2681312,-3401956,-13307506,8205540,13585437,-17127465,15115439 }, + { 23711543,-672915,31206561,-8362711,6164647,-9709987,-33535882,-1426096,8236921,16492939 }, + { -23910559,-13515526,-26299483,-4503841,25005590,-7687270,19574902,10071562,6708380,-6222424 }, + }, + { + { 2101391,-4930054,19702731,2367575,-15427167,1047675,5301017,9328700,29955601,-11678310 }, + { 3096359,9271816,-21620864,-15521844,-14847996,-7592937,-25892142,-12635595,-9917575,6216608 }, + { -32615849,338663,-25195611,2510422,-29213566,-13820213,24822830,-6146567,-26767480,7525079 }, + }, + { + { -23066649,-13985623,16133487,-7896178,-3389565,778788,-910336,-2782495,-19386633,11994101 }, + { 21691500,-13624626,-641331,-14367021,3285881,-3483596,-25064666,9718258,-7477437,13381418 }, + { 18445390,-4202236,14979846,11622458,-1727110,-3582980,23111648,-6375247,28535282,15779576 }, + }, + { + { 30098053,3089662,-9234387,16662135,-21306940,11308411,-14068454,12021730,9955285,-16303356 }, + { 9734894,-14576830,-7473633,-9138735,2060392,11313496,-18426029,9924399,20194861,13380996 }, + { -26378102,-7965207,-22167821,15789297,-18055342,-6168792,-1984914,15707771,26342023,10146099 }, + }, +}, +{ + { + { -26016874,-219943,21339191,-41388,19745256,-2878700,-29637280,2227040,21612326,-545728 }, + { -13077387,1184228,23562814,-5970442,-20351244,-6348714,25764461,12243797,-20856566,11649658 }, + { -10031494,11262626,27384172,2271902,26947504,-15997771,39944,6114064,33514190,2333242 }, + }, + { + { -21433588,-12421821,8119782,7219913,-21830522,-9016134,-6679750,-12670638,24350578,-13450001 }, + { -4116307,-11271533,-23886186,4843615,-30088339,690623,-31536088,-10406836,8317860,12352766 }, + { 18200138,-14475911,-33087759,-2696619,-23702521,-9102511,-23552096,-2287550,20712163,6719373 }, + }, + { + { 26656208,6075253,-7858556,1886072,-28344043,4262326,11117530,-3763210,26224235,-3297458 }, + { -17168938,-14854097,-3395676,-16369877,-19954045,14050420,21728352,9493610,18620611,-16428628 }, + { -13323321,13325349,11432106,5964811,18609221,6062965,-5269471,-9725556,-30701573,-16479657 }, + }, + { + { -23860538,-11233159,26961357,1640861,-32413112,-16737940,12248509,-5240639,13735342,1934062 }, + { 25089769,6742589,17081145,-13406266,21909293,-16067981,-15136294,-3765346,-21277997,5473616 }, + { 31883677,-7961101,1083432,-11572403,22828471,13290673,-7125085,12469656,29111212,-5451014 }, + }, + { + { 24244947,-15050407,-26262976,2791540,-14997599,16666678,24367466,6388839,-10295587,452383 }, + { -25640782,-3417841,5217916,16224624,19987036,-4082269,-24236251,-5915248,15766062,8407814 }, + { -20406999,13990231,15495425,16395525,5377168,15166495,-8917023,-4388953,-8067909,2276718 }, + }, + { + { 30157918,12924066,-17712050,9245753,19895028,3368142,-23827587,5096219,22740376,-7303417 }, + { 2041139,-14256350,7783687,13876377,-25946985,-13352459,24051124,13742383,-15637599,13295222 }, + { 33338237,-8505733,12532113,7977527,9106186,-1715251,-17720195,-4612972,-4451357,-14669444 }, + }, + { + { -20045281,5454097,-14346548,6447146,28862071,1883651,-2469266,-4141880,7770569,9620597 }, + { 23208068,7979712,33071466,8149229,1758231,-10834995,30945528,-1694323,-33502340,-14767970 }, + { 1439958,-16270480,-1079989,-793782,4625402,10647766,-5043801,1220118,30494170,-11440799 }, + }, + { + { -5037580,-13028295,-2970559,-3061767,15640974,-6701666,-26739026,926050,-1684339,-13333647 }, + { 13908495,-3549272,30919928,-6273825,-21521863,7989039,9021034,9078865,3353509,4033511 }, + { -29663431,-15113610,32259991,-344482,24295849,-12912123,23161163,8839127,27485041,7356032 }, + }, +}, +{ + { + { 9661027,705443,11980065,-5370154,-1628543,14661173,-6346142,2625015,28431036,-16771834 }, + { -23839233,-8311415,-25945511,7480958,-17681669,-8354183,-22545972,14150565,15970762,4099461 }, + { 29262576,16756590,26350592,-8793563,8529671,-11208050,13617293,-9937143,11465739,8317062 }, + }, + { + { -25493081,-6962928,32500200,-9419051,-23038724,-2302222,14898637,3848455,20969334,-5157516 }, + { -20384450,-14347713,-18336405,13884722,-33039454,2842114,-21610826,-3649888,11177095,14989547 }, + { -24496721,-11716016,16959896,2278463,12066309,10137771,13515641,2581286,-28487508,9930240 }, + }, + { + { -17751622,-2097826,16544300,-13009300,-15914807,-14949081,18345767,-13403753,16291481,-5314038 }, + { -33229194,2553288,32678213,9875984,8534129,6889387,-9676774,6957617,4368891,9788741 }, + { 16660756,7281060,-10830758,12911820,20108584,-8101676,-21722536,-8613148,16250552,-11111103 }, + }, + { + { -19765507,2390526,-16551031,14161980,1905286,6414907,4689584,10604807,-30190403,4782747 }, + { -1354539,14736941,-7367442,-13292886,7710542,-14155590,-9981571,4383045,22546403,437323 }, + { 31665577,-12180464,-16186830,1491339,-18368625,3294682,27343084,2786261,-30633590,-14097016 }, + }, + { + { -14467279,-683715,-33374107,7448552,19294360,14334329,-19690631,2355319,-19284671,-6114373 }, + { 15121312,-15796162,6377020,-6031361,-10798111,-12957845,18952177,15496498,-29380133,11754228 }, + { -2637277,-13483075,8488727,-14303896,12728761,-1622493,7141596,11724556,22761615,-10134141 }, + }, + { + { 16918416,11729663,-18083579,3022987,-31015732,-13339659,-28741185,-12227393,32851222,11717399 }, + { 11166634,7338049,-6722523,4531520,-29468672,-7302055,31474879,3483633,-1193175,-4030831 }, + { -185635,9921305,31456609,-13536438,-12013818,13348923,33142652,6546660,-19985279,-3948376 }, + }, + { + { -32460596,11266712,-11197107,-7899103,31703694,3855903,-8537131,-12833048,-30772034,-15486313 }, + { -18006477,12709068,3991746,-6479188,-21491523,-10550425,-31135347,-16049879,10928917,3011958 }, + { -6957757,-15594337,31696059,334240,29576716,14796075,-30831056,-12805180,18008031,10258577 }, + }, + { + { -22448644,15655569,7018479,-4410003,-30314266,-1201591,-1853465,1367120,25127874,6671743 }, + { 29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684 }, + { -20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476 }, + }, +}, diff --git a/libaxolotl/jni/ed25519/base2.h b/libaxolotl/jni/ed25519/base2.h new file mode 100644 index 000000000..8c538440f --- /dev/null +++ b/libaxolotl/jni/ed25519/base2.h @@ -0,0 +1,40 @@ + { + { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, + { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, + { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, + }, + { + { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, + { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, + { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, + }, + { + { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, + { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, + { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, + }, + { + { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, + { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, + { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, + }, + { + { -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 }, + { -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 }, + { 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 }, + }, + { + { -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 }, + { 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 }, + { 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 }, + }, + { + { -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 }, + { -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 }, + { -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 }, + }, + { + { -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 }, + { -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 }, + { -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 }, + }, diff --git a/libaxolotl/jni/ed25519/d.h b/libaxolotl/jni/ed25519/d.h new file mode 100644 index 000000000..e25f57835 --- /dev/null +++ b/libaxolotl/jni/ed25519/d.h @@ -0,0 +1 @@ +-10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116 diff --git a/libaxolotl/jni/ed25519/d2.h b/libaxolotl/jni/ed25519/d2.h new file mode 100644 index 000000000..01aaec751 --- /dev/null +++ b/libaxolotl/jni/ed25519/d2.h @@ -0,0 +1 @@ +-21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199 diff --git a/libaxolotl/jni/ed25519/fe.h b/libaxolotl/jni/ed25519/fe.h new file mode 100644 index 000000000..60c308ba4 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe.h @@ -0,0 +1,56 @@ +#ifndef FE_H +#define FE_H + +#include "crypto_int32.h" + +typedef crypto_int32 fe[10]; + +/* +fe means field element. +Here the field is \Z/(2^255-19). +An element t, entries t[0]...t[9], represents the integer +t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. +Bounds on each t[i] vary depending on context. +*/ + +#define fe_frombytes crypto_sign_ed25519_ref10_fe_frombytes +#define fe_tobytes crypto_sign_ed25519_ref10_fe_tobytes +#define fe_copy crypto_sign_ed25519_ref10_fe_copy +#define fe_isnonzero crypto_sign_ed25519_ref10_fe_isnonzero +#define fe_isnegative crypto_sign_ed25519_ref10_fe_isnegative +#define fe_0 crypto_sign_ed25519_ref10_fe_0 +#define fe_1 crypto_sign_ed25519_ref10_fe_1 +#define fe_cswap crypto_sign_ed25519_ref10_fe_cswap +#define fe_cmov crypto_sign_ed25519_ref10_fe_cmov +#define fe_add crypto_sign_ed25519_ref10_fe_add +#define fe_sub crypto_sign_ed25519_ref10_fe_sub +#define fe_neg crypto_sign_ed25519_ref10_fe_neg +#define fe_mul crypto_sign_ed25519_ref10_fe_mul +#define fe_sq crypto_sign_ed25519_ref10_fe_sq +#define fe_sq2 crypto_sign_ed25519_ref10_fe_sq2 +#define fe_mul121666 crypto_sign_ed25519_ref10_fe_mul121666 +#define fe_invert crypto_sign_ed25519_ref10_fe_invert +#define fe_pow22523 crypto_sign_ed25519_ref10_fe_pow22523 + +extern void fe_frombytes(fe,const unsigned char *); +extern void fe_tobytes(unsigned char *,const fe); + +extern void fe_copy(fe,const fe); +extern int fe_isnonzero(const fe); +extern int fe_isnegative(const fe); +extern void fe_0(fe); +extern void fe_1(fe); +extern void fe_cswap(fe,fe,unsigned int); +extern void fe_cmov(fe,const fe,unsigned int); + +extern void fe_add(fe,const fe,const fe); +extern void fe_sub(fe,const fe,const fe); +extern void fe_neg(fe,const fe); +extern void fe_mul(fe,const fe,const fe); +extern void fe_sq(fe,const fe); +extern void fe_sq2(fe,const fe); +extern void fe_mul121666(fe,const fe); +extern void fe_invert(fe,const fe); +extern void fe_pow22523(fe,const fe); + +#endif diff --git a/libaxolotl/jni/ed25519/fe_0.c b/libaxolotl/jni/ed25519/fe_0.c new file mode 100644 index 000000000..ec879d733 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_0.c @@ -0,0 +1,19 @@ +#include "fe.h" + +/* +h = 0 +*/ + +void fe_0(fe h) +{ + h[0] = 0; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; +} diff --git a/libaxolotl/jni/ed25519/fe_1.c b/libaxolotl/jni/ed25519/fe_1.c new file mode 100644 index 000000000..8cf778484 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_1.c @@ -0,0 +1,19 @@ +#include "fe.h" + +/* +h = 1 +*/ + +void fe_1(fe h) +{ + h[0] = 1; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; +} diff --git a/libaxolotl/jni/ed25519/fe_add.c b/libaxolotl/jni/ed25519/fe_add.c new file mode 100644 index 000000000..e6a81da20 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_add.c @@ -0,0 +1,57 @@ +#include "fe.h" + +/* +h = f + g +Can overlap h with f or g. + +Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + +Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +void fe_add(fe h,const fe f,const fe g) +{ + crypto_int32 f0 = f[0]; + crypto_int32 f1 = f[1]; + crypto_int32 f2 = f[2]; + crypto_int32 f3 = f[3]; + crypto_int32 f4 = f[4]; + crypto_int32 f5 = f[5]; + crypto_int32 f6 = f[6]; + crypto_int32 f7 = f[7]; + crypto_int32 f8 = f[8]; + crypto_int32 f9 = f[9]; + crypto_int32 g0 = g[0]; + crypto_int32 g1 = g[1]; + crypto_int32 g2 = g[2]; + crypto_int32 g3 = g[3]; + crypto_int32 g4 = g[4]; + crypto_int32 g5 = g[5]; + crypto_int32 g6 = g[6]; + crypto_int32 g7 = g[7]; + crypto_int32 g8 = g[8]; + crypto_int32 g9 = g[9]; + crypto_int32 h0 = f0 + g0; + crypto_int32 h1 = f1 + g1; + crypto_int32 h2 = f2 + g2; + crypto_int32 h3 = f3 + g3; + crypto_int32 h4 = f4 + g4; + crypto_int32 h5 = f5 + g5; + crypto_int32 h6 = f6 + g6; + crypto_int32 h7 = f7 + g7; + crypto_int32 h8 = f8 + g8; + crypto_int32 h9 = f9 + g9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} diff --git a/libaxolotl/jni/ed25519/fe_cmov.c b/libaxolotl/jni/ed25519/fe_cmov.c new file mode 100644 index 000000000..8ca584fb1 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_cmov.c @@ -0,0 +1,63 @@ +#include "fe.h" + +/* +Replace (f,g) with (g,g) if b == 1; +replace (f,g) with (f,g) if b == 0. + +Preconditions: b in {0,1}. +*/ + +void fe_cmov(fe f,const fe g,unsigned int b) +{ + crypto_int32 f0 = f[0]; + crypto_int32 f1 = f[1]; + crypto_int32 f2 = f[2]; + crypto_int32 f3 = f[3]; + crypto_int32 f4 = f[4]; + crypto_int32 f5 = f[5]; + crypto_int32 f6 = f[6]; + crypto_int32 f7 = f[7]; + crypto_int32 f8 = f[8]; + crypto_int32 f9 = f[9]; + crypto_int32 g0 = g[0]; + crypto_int32 g1 = g[1]; + crypto_int32 g2 = g[2]; + crypto_int32 g3 = g[3]; + crypto_int32 g4 = g[4]; + crypto_int32 g5 = g[5]; + crypto_int32 g6 = g[6]; + crypto_int32 g7 = g[7]; + crypto_int32 g8 = g[8]; + crypto_int32 g9 = g[9]; + crypto_int32 x0 = f0 ^ g0; + crypto_int32 x1 = f1 ^ g1; + crypto_int32 x2 = f2 ^ g2; + crypto_int32 x3 = f3 ^ g3; + crypto_int32 x4 = f4 ^ g4; + crypto_int32 x5 = f5 ^ g5; + crypto_int32 x6 = f6 ^ g6; + crypto_int32 x7 = f7 ^ g7; + crypto_int32 x8 = f8 ^ g8; + crypto_int32 x9 = f9 ^ g9; + b = -b; + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; +} diff --git a/libaxolotl/jni/ed25519/fe_copy.c b/libaxolotl/jni/ed25519/fe_copy.c new file mode 100644 index 000000000..9c5bf865a --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_copy.c @@ -0,0 +1,29 @@ +#include "fe.h" + +/* +h = f +*/ + +void fe_copy(fe h,const fe f) +{ + crypto_int32 f0 = f[0]; + crypto_int32 f1 = f[1]; + crypto_int32 f2 = f[2]; + crypto_int32 f3 = f[3]; + crypto_int32 f4 = f[4]; + crypto_int32 f5 = f[5]; + crypto_int32 f6 = f[6]; + crypto_int32 f7 = f[7]; + crypto_int32 f8 = f[8]; + crypto_int32 f9 = f[9]; + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; + h[5] = f5; + h[6] = f6; + h[7] = f7; + h[8] = f8; + h[9] = f9; +} diff --git a/libaxolotl/jni/ed25519/fe_frombytes.c b/libaxolotl/jni/ed25519/fe_frombytes.c new file mode 100644 index 000000000..5c1791748 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_frombytes.c @@ -0,0 +1,73 @@ +#include "fe.h" +#include "crypto_int64.h" +#include "crypto_uint64.h" + +static crypto_uint64 load_3(const unsigned char *in) +{ + crypto_uint64 result; + result = (crypto_uint64) in[0]; + result |= ((crypto_uint64) in[1]) << 8; + result |= ((crypto_uint64) in[2]) << 16; + return result; +} + +static crypto_uint64 load_4(const unsigned char *in) +{ + crypto_uint64 result; + result = (crypto_uint64) in[0]; + result |= ((crypto_uint64) in[1]) << 8; + result |= ((crypto_uint64) in[2]) << 16; + result |= ((crypto_uint64) in[3]) << 24; + return result; +} + +/* +Ignores top bit of h. +*/ + +void fe_frombytes(fe h,const unsigned char *s) +{ + crypto_int64 h0 = load_4(s); + crypto_int64 h1 = load_3(s + 4) << 6; + crypto_int64 h2 = load_3(s + 7) << 5; + crypto_int64 h3 = load_3(s + 10) << 3; + crypto_int64 h4 = load_3(s + 13) << 2; + crypto_int64 h5 = load_4(s + 16); + crypto_int64 h6 = load_3(s + 20) << 7; + crypto_int64 h7 = load_3(s + 23) << 5; + crypto_int64 h8 = load_3(s + 26) << 4; + crypto_int64 h9 = (load_3(s + 29) & 8388607) << 2; + crypto_int64 carry0; + crypto_int64 carry1; + crypto_int64 carry2; + crypto_int64 carry3; + crypto_int64 carry4; + crypto_int64 carry5; + crypto_int64 carry6; + crypto_int64 carry7; + crypto_int64 carry8; + crypto_int64 carry9; + + carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} diff --git a/libaxolotl/jni/ed25519/fe_invert.c b/libaxolotl/jni/ed25519/fe_invert.c new file mode 100644 index 000000000..bcfdb8ff8 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_invert.c @@ -0,0 +1,14 @@ +#include "fe.h" + +void fe_invert(fe out,const fe z) +{ + fe t0; + fe t1; + fe t2; + fe t3; + int i; + +#include "pow225521.h" + + return; +} diff --git a/libaxolotl/jni/ed25519/fe_isnegative.c b/libaxolotl/jni/ed25519/fe_isnegative.c new file mode 100644 index 000000000..3b2c8b8d5 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_isnegative.c @@ -0,0 +1,16 @@ +#include "fe.h" + +/* +return 1 if f is in {1,3,5,...,q-2} +return 0 if f is in {0,2,4,...,q-1} + +Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +int fe_isnegative(const fe f) +{ + unsigned char s[32]; + fe_tobytes(s,f); + return s[0] & 1; +} diff --git a/libaxolotl/jni/ed25519/fe_isnonzero.c b/libaxolotl/jni/ed25519/fe_isnonzero.c new file mode 100644 index 000000000..47568001c --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_isnonzero.c @@ -0,0 +1,19 @@ +#include "fe.h" +#include "crypto_verify_32.h" + +/* +return 1 if f == 0 +return 0 if f != 0 + +Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +static const unsigned char zero[32]; + +int fe_isnonzero(const fe f) +{ + unsigned char s[32]; + fe_tobytes(s,f); + return crypto_verify_32(s,zero); +} diff --git a/libaxolotl/jni/ed25519/fe_mul.c b/libaxolotl/jni/ed25519/fe_mul.c new file mode 100644 index 000000000..26ca8b368 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_mul.c @@ -0,0 +1,253 @@ +#include "fe.h" +#include "crypto_int64.h" + +/* +h = f * g +Can overlap h with f or g. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + +/* +Notes on implementation strategy: + +Using schoolbook multiplication. +Karatsuba would save a little in some cost models. + +Most multiplications by 2 and 19 are 32-bit precomputations; +cheaper than 64-bit postcomputations. + +There is one remaining multiplication by 19 in the carry chain; +one *19 precomputation can be merged into this, +but the resulting data flow is considerably less clean. + +There are 12 carries below. +10 of them are 2-way parallelizable and vectorizable. +Can get away with 11 carries, but then data flow is much deeper. + +With tighter constraints on inputs can squeeze carries into int32. +*/ + +void fe_mul(fe h,const fe f,const fe g) +{ + crypto_int32 f0 = f[0]; + crypto_int32 f1 = f[1]; + crypto_int32 f2 = f[2]; + crypto_int32 f3 = f[3]; + crypto_int32 f4 = f[4]; + crypto_int32 f5 = f[5]; + crypto_int32 f6 = f[6]; + crypto_int32 f7 = f[7]; + crypto_int32 f8 = f[8]; + crypto_int32 f9 = f[9]; + crypto_int32 g0 = g[0]; + crypto_int32 g1 = g[1]; + crypto_int32 g2 = g[2]; + crypto_int32 g3 = g[3]; + crypto_int32 g4 = g[4]; + crypto_int32 g5 = g[5]; + crypto_int32 g6 = g[6]; + crypto_int32 g7 = g[7]; + crypto_int32 g8 = g[8]; + crypto_int32 g9 = g[9]; + crypto_int32 g1_19 = 19 * g1; /* 1.959375*2^29 */ + crypto_int32 g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + crypto_int32 g3_19 = 19 * g3; + crypto_int32 g4_19 = 19 * g4; + crypto_int32 g5_19 = 19 * g5; + crypto_int32 g6_19 = 19 * g6; + crypto_int32 g7_19 = 19 * g7; + crypto_int32 g8_19 = 19 * g8; + crypto_int32 g9_19 = 19 * g9; + crypto_int32 f1_2 = 2 * f1; + crypto_int32 f3_2 = 2 * f3; + crypto_int32 f5_2 = 2 * f5; + crypto_int32 f7_2 = 2 * f7; + crypto_int32 f9_2 = 2 * f9; + crypto_int64 f0g0 = f0 * (crypto_int64) g0; + crypto_int64 f0g1 = f0 * (crypto_int64) g1; + crypto_int64 f0g2 = f0 * (crypto_int64) g2; + crypto_int64 f0g3 = f0 * (crypto_int64) g3; + crypto_int64 f0g4 = f0 * (crypto_int64) g4; + crypto_int64 f0g5 = f0 * (crypto_int64) g5; + crypto_int64 f0g6 = f0 * (crypto_int64) g6; + crypto_int64 f0g7 = f0 * (crypto_int64) g7; + crypto_int64 f0g8 = f0 * (crypto_int64) g8; + crypto_int64 f0g9 = f0 * (crypto_int64) g9; + crypto_int64 f1g0 = f1 * (crypto_int64) g0; + crypto_int64 f1g1_2 = f1_2 * (crypto_int64) g1; + crypto_int64 f1g2 = f1 * (crypto_int64) g2; + crypto_int64 f1g3_2 = f1_2 * (crypto_int64) g3; + crypto_int64 f1g4 = f1 * (crypto_int64) g4; + crypto_int64 f1g5_2 = f1_2 * (crypto_int64) g5; + crypto_int64 f1g6 = f1 * (crypto_int64) g6; + crypto_int64 f1g7_2 = f1_2 * (crypto_int64) g7; + crypto_int64 f1g8 = f1 * (crypto_int64) g8; + crypto_int64 f1g9_38 = f1_2 * (crypto_int64) g9_19; + crypto_int64 f2g0 = f2 * (crypto_int64) g0; + crypto_int64 f2g1 = f2 * (crypto_int64) g1; + crypto_int64 f2g2 = f2 * (crypto_int64) g2; + crypto_int64 f2g3 = f2 * (crypto_int64) g3; + crypto_int64 f2g4 = f2 * (crypto_int64) g4; + crypto_int64 f2g5 = f2 * (crypto_int64) g5; + crypto_int64 f2g6 = f2 * (crypto_int64) g6; + crypto_int64 f2g7 = f2 * (crypto_int64) g7; + crypto_int64 f2g8_19 = f2 * (crypto_int64) g8_19; + crypto_int64 f2g9_19 = f2 * (crypto_int64) g9_19; + crypto_int64 f3g0 = f3 * (crypto_int64) g0; + crypto_int64 f3g1_2 = f3_2 * (crypto_int64) g1; + crypto_int64 f3g2 = f3 * (crypto_int64) g2; + crypto_int64 f3g3_2 = f3_2 * (crypto_int64) g3; + crypto_int64 f3g4 = f3 * (crypto_int64) g4; + crypto_int64 f3g5_2 = f3_2 * (crypto_int64) g5; + crypto_int64 f3g6 = f3 * (crypto_int64) g6; + crypto_int64 f3g7_38 = f3_2 * (crypto_int64) g7_19; + crypto_int64 f3g8_19 = f3 * (crypto_int64) g8_19; + crypto_int64 f3g9_38 = f3_2 * (crypto_int64) g9_19; + crypto_int64 f4g0 = f4 * (crypto_int64) g0; + crypto_int64 f4g1 = f4 * (crypto_int64) g1; + crypto_int64 f4g2 = f4 * (crypto_int64) g2; + crypto_int64 f4g3 = f4 * (crypto_int64) g3; + crypto_int64 f4g4 = f4 * (crypto_int64) g4; + crypto_int64 f4g5 = f4 * (crypto_int64) g5; + crypto_int64 f4g6_19 = f4 * (crypto_int64) g6_19; + crypto_int64 f4g7_19 = f4 * (crypto_int64) g7_19; + crypto_int64 f4g8_19 = f4 * (crypto_int64) g8_19; + crypto_int64 f4g9_19 = f4 * (crypto_int64) g9_19; + crypto_int64 f5g0 = f5 * (crypto_int64) g0; + crypto_int64 f5g1_2 = f5_2 * (crypto_int64) g1; + crypto_int64 f5g2 = f5 * (crypto_int64) g2; + crypto_int64 f5g3_2 = f5_2 * (crypto_int64) g3; + crypto_int64 f5g4 = f5 * (crypto_int64) g4; + crypto_int64 f5g5_38 = f5_2 * (crypto_int64) g5_19; + crypto_int64 f5g6_19 = f5 * (crypto_int64) g6_19; + crypto_int64 f5g7_38 = f5_2 * (crypto_int64) g7_19; + crypto_int64 f5g8_19 = f5 * (crypto_int64) g8_19; + crypto_int64 f5g9_38 = f5_2 * (crypto_int64) g9_19; + crypto_int64 f6g0 = f6 * (crypto_int64) g0; + crypto_int64 f6g1 = f6 * (crypto_int64) g1; + crypto_int64 f6g2 = f6 * (crypto_int64) g2; + crypto_int64 f6g3 = f6 * (crypto_int64) g3; + crypto_int64 f6g4_19 = f6 * (crypto_int64) g4_19; + crypto_int64 f6g5_19 = f6 * (crypto_int64) g5_19; + crypto_int64 f6g6_19 = f6 * (crypto_int64) g6_19; + crypto_int64 f6g7_19 = f6 * (crypto_int64) g7_19; + crypto_int64 f6g8_19 = f6 * (crypto_int64) g8_19; + crypto_int64 f6g9_19 = f6 * (crypto_int64) g9_19; + crypto_int64 f7g0 = f7 * (crypto_int64) g0; + crypto_int64 f7g1_2 = f7_2 * (crypto_int64) g1; + crypto_int64 f7g2 = f7 * (crypto_int64) g2; + crypto_int64 f7g3_38 = f7_2 * (crypto_int64) g3_19; + crypto_int64 f7g4_19 = f7 * (crypto_int64) g4_19; + crypto_int64 f7g5_38 = f7_2 * (crypto_int64) g5_19; + crypto_int64 f7g6_19 = f7 * (crypto_int64) g6_19; + crypto_int64 f7g7_38 = f7_2 * (crypto_int64) g7_19; + crypto_int64 f7g8_19 = f7 * (crypto_int64) g8_19; + crypto_int64 f7g9_38 = f7_2 * (crypto_int64) g9_19; + crypto_int64 f8g0 = f8 * (crypto_int64) g0; + crypto_int64 f8g1 = f8 * (crypto_int64) g1; + crypto_int64 f8g2_19 = f8 * (crypto_int64) g2_19; + crypto_int64 f8g3_19 = f8 * (crypto_int64) g3_19; + crypto_int64 f8g4_19 = f8 * (crypto_int64) g4_19; + crypto_int64 f8g5_19 = f8 * (crypto_int64) g5_19; + crypto_int64 f8g6_19 = f8 * (crypto_int64) g6_19; + crypto_int64 f8g7_19 = f8 * (crypto_int64) g7_19; + crypto_int64 f8g8_19 = f8 * (crypto_int64) g8_19; + crypto_int64 f8g9_19 = f8 * (crypto_int64) g9_19; + crypto_int64 f9g0 = f9 * (crypto_int64) g0; + crypto_int64 f9g1_38 = f9_2 * (crypto_int64) g1_19; + crypto_int64 f9g2_19 = f9 * (crypto_int64) g2_19; + crypto_int64 f9g3_38 = f9_2 * (crypto_int64) g3_19; + crypto_int64 f9g4_19 = f9 * (crypto_int64) g4_19; + crypto_int64 f9g5_38 = f9_2 * (crypto_int64) g5_19; + crypto_int64 f9g6_19 = f9 * (crypto_int64) g6_19; + crypto_int64 f9g7_38 = f9_2 * (crypto_int64) g7_19; + crypto_int64 f9g8_19 = f9 * (crypto_int64) g8_19; + crypto_int64 f9g9_38 = f9_2 * (crypto_int64) g9_19; + crypto_int64 h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38; + crypto_int64 h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19; + crypto_int64 h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38; + crypto_int64 h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19; + crypto_int64 h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38; + crypto_int64 h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19; + crypto_int64 h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38; + crypto_int64 h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; + crypto_int64 h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; + crypto_int64 h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; + crypto_int64 carry0; + crypto_int64 carry1; + crypto_int64 carry2; + crypto_int64 carry3; + crypto_int64 carry4; + crypto_int64 carry5; + crypto_int64 carry6; + crypto_int64 carry7; + crypto_int64 carry8; + crypto_int64 carry9; + + /* + |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 + */ + + carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.71*2^59 */ + /* |h5| <= 1.71*2^59 */ + + carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.41*2^60 */ + /* |h6| <= 1.41*2^60 */ + + carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.71*2^59 */ + /* |h7| <= 1.71*2^59 */ + + carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.72*2^34 */ + /* |h8| <= 1.41*2^60 */ + + carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.71*2^59 */ + + carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.1*2^39 */ + + carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} diff --git a/libaxolotl/jni/ed25519/fe_neg.c b/libaxolotl/jni/ed25519/fe_neg.c new file mode 100644 index 000000000..2078ce528 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_neg.c @@ -0,0 +1,45 @@ +#include "fe.h" + +/* +h = -f + +Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + +Postconditions: + |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +*/ + +void fe_neg(fe h,const fe f) +{ + crypto_int32 f0 = f[0]; + crypto_int32 f1 = f[1]; + crypto_int32 f2 = f[2]; + crypto_int32 f3 = f[3]; + crypto_int32 f4 = f[4]; + crypto_int32 f5 = f[5]; + crypto_int32 f6 = f[6]; + crypto_int32 f7 = f[7]; + crypto_int32 f8 = f[8]; + crypto_int32 f9 = f[9]; + crypto_int32 h0 = -f0; + crypto_int32 h1 = -f1; + crypto_int32 h2 = -f2; + crypto_int32 h3 = -f3; + crypto_int32 h4 = -f4; + crypto_int32 h5 = -f5; + crypto_int32 h6 = -f6; + crypto_int32 h7 = -f7; + crypto_int32 h8 = -f8; + crypto_int32 h9 = -f9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} diff --git a/libaxolotl/jni/ed25519/fe_pow22523.c b/libaxolotl/jni/ed25519/fe_pow22523.c new file mode 100644 index 000000000..56675a590 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_pow22523.c @@ -0,0 +1,13 @@ +#include "fe.h" + +void fe_pow22523(fe out,const fe z) +{ + fe t0; + fe t1; + fe t2; + int i; + +#include "pow22523.h" + + return; +} diff --git a/libaxolotl/jni/ed25519/fe_sq.c b/libaxolotl/jni/ed25519/fe_sq.c new file mode 100644 index 000000000..8dd119841 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_sq.c @@ -0,0 +1,149 @@ +#include "fe.h" +#include "crypto_int64.h" + +/* +h = f * f +Can overlap h with f. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + +/* +See fe_mul.c for discussion of implementation strategy. +*/ + +void fe_sq(fe h,const fe f) +{ + crypto_int32 f0 = f[0]; + crypto_int32 f1 = f[1]; + crypto_int32 f2 = f[2]; + crypto_int32 f3 = f[3]; + crypto_int32 f4 = f[4]; + crypto_int32 f5 = f[5]; + crypto_int32 f6 = f[6]; + crypto_int32 f7 = f[7]; + crypto_int32 f8 = f[8]; + crypto_int32 f9 = f[9]; + crypto_int32 f0_2 = 2 * f0; + crypto_int32 f1_2 = 2 * f1; + crypto_int32 f2_2 = 2 * f2; + crypto_int32 f3_2 = 2 * f3; + crypto_int32 f4_2 = 2 * f4; + crypto_int32 f5_2 = 2 * f5; + crypto_int32 f6_2 = 2 * f6; + crypto_int32 f7_2 = 2 * f7; + crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ + crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ + crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ + crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ + crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ + crypto_int64 f0f0 = f0 * (crypto_int64) f0; + crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1; + crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2; + crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3; + crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4; + crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5; + crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6; + crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7; + crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8; + crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9; + crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1; + crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2; + crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2; + crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4; + crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2; + crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6; + crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2; + crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8; + crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38; + crypto_int64 f2f2 = f2 * (crypto_int64) f2; + crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3; + crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4; + crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5; + crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6; + crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7; + crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19; + crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38; + crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3; + crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4; + crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2; + crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6; + crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38; + crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19; + crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38; + crypto_int64 f4f4 = f4 * (crypto_int64) f4; + crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5; + crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19; + crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38; + crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19; + crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38; + crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38; + crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19; + crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38; + crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19; + crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38; + crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19; + crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38; + crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19; + crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38; + crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38; + crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19; + crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38; + crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19; + crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38; + crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38; + crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; + crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; + crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; + crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; + crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; + crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; + crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; + crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; + crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; + crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; + crypto_int64 carry0; + crypto_int64 carry1; + crypto_int64 carry2; + crypto_int64 carry3; + crypto_int64 carry4; + crypto_int64 carry5; + crypto_int64 carry6; + crypto_int64 carry7; + crypto_int64 carry8; + crypto_int64 carry9; + + carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + + carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + + carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + + carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + + carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} diff --git a/libaxolotl/jni/ed25519/fe_sq2.c b/libaxolotl/jni/ed25519/fe_sq2.c new file mode 100644 index 000000000..026ed3aac --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_sq2.c @@ -0,0 +1,160 @@ +#include "fe.h" +#include "crypto_int64.h" + +/* +h = 2 * f * f +Can overlap h with f. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + +/* +See fe_mul.c for discussion of implementation strategy. +*/ + +void fe_sq2(fe h,const fe f) +{ + crypto_int32 f0 = f[0]; + crypto_int32 f1 = f[1]; + crypto_int32 f2 = f[2]; + crypto_int32 f3 = f[3]; + crypto_int32 f4 = f[4]; + crypto_int32 f5 = f[5]; + crypto_int32 f6 = f[6]; + crypto_int32 f7 = f[7]; + crypto_int32 f8 = f[8]; + crypto_int32 f9 = f[9]; + crypto_int32 f0_2 = 2 * f0; + crypto_int32 f1_2 = 2 * f1; + crypto_int32 f2_2 = 2 * f2; + crypto_int32 f3_2 = 2 * f3; + crypto_int32 f4_2 = 2 * f4; + crypto_int32 f5_2 = 2 * f5; + crypto_int32 f6_2 = 2 * f6; + crypto_int32 f7_2 = 2 * f7; + crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ + crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ + crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ + crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ + crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ + crypto_int64 f0f0 = f0 * (crypto_int64) f0; + crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1; + crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2; + crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3; + crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4; + crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5; + crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6; + crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7; + crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8; + crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9; + crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1; + crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2; + crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2; + crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4; + crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2; + crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6; + crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2; + crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8; + crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38; + crypto_int64 f2f2 = f2 * (crypto_int64) f2; + crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3; + crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4; + crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5; + crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6; + crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7; + crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19; + crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38; + crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3; + crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4; + crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2; + crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6; + crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38; + crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19; + crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38; + crypto_int64 f4f4 = f4 * (crypto_int64) f4; + crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5; + crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19; + crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38; + crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19; + crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38; + crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38; + crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19; + crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38; + crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19; + crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38; + crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19; + crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38; + crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19; + crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38; + crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38; + crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19; + crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38; + crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19; + crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38; + crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38; + crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; + crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; + crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; + crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; + crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; + crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; + crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; + crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; + crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; + crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; + crypto_int64 carry0; + crypto_int64 carry1; + crypto_int64 carry2; + crypto_int64 carry3; + crypto_int64 carry4; + crypto_int64 carry5; + crypto_int64 carry6; + crypto_int64 carry7; + crypto_int64 carry8; + crypto_int64 carry9; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + + carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + + carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + + carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + + carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} diff --git a/libaxolotl/jni/ed25519/fe_sub.c b/libaxolotl/jni/ed25519/fe_sub.c new file mode 100644 index 000000000..6e26b7df8 --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_sub.c @@ -0,0 +1,57 @@ +#include "fe.h" + +/* +h = f - g +Can overlap h with f or g. + +Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + +Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +void fe_sub(fe h,const fe f,const fe g) +{ + crypto_int32 f0 = f[0]; + crypto_int32 f1 = f[1]; + crypto_int32 f2 = f[2]; + crypto_int32 f3 = f[3]; + crypto_int32 f4 = f[4]; + crypto_int32 f5 = f[5]; + crypto_int32 f6 = f[6]; + crypto_int32 f7 = f[7]; + crypto_int32 f8 = f[8]; + crypto_int32 f9 = f[9]; + crypto_int32 g0 = g[0]; + crypto_int32 g1 = g[1]; + crypto_int32 g2 = g[2]; + crypto_int32 g3 = g[3]; + crypto_int32 g4 = g[4]; + crypto_int32 g5 = g[5]; + crypto_int32 g6 = g[6]; + crypto_int32 g7 = g[7]; + crypto_int32 g8 = g[8]; + crypto_int32 g9 = g[9]; + crypto_int32 h0 = f0 - g0; + crypto_int32 h1 = f1 - g1; + crypto_int32 h2 = f2 - g2; + crypto_int32 h3 = f3 - g3; + crypto_int32 h4 = f4 - g4; + crypto_int32 h5 = f5 - g5; + crypto_int32 h6 = f6 - g6; + crypto_int32 h7 = f7 - g7; + crypto_int32 h8 = f8 - g8; + crypto_int32 h9 = f9 - g9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} diff --git a/libaxolotl/jni/ed25519/fe_tobytes.c b/libaxolotl/jni/ed25519/fe_tobytes.c new file mode 100644 index 000000000..0a63baf9c --- /dev/null +++ b/libaxolotl/jni/ed25519/fe_tobytes.c @@ -0,0 +1,119 @@ +#include "fe.h" + +/* +Preconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + +Write p=2^255-19; q=floor(h/p). +Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + +Proof: + Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + + Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + Then 0> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; + carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; + carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; + carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; + carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; + carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; + carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; + carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; + carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; + carry9 = h9 >> 25; h9 -= carry9 << 25; + /* h10 = carry9 */ + + /* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + Goal: Output h0+...+2^230 h9. + */ + + s[0] = h0 >> 0; + s[1] = h0 >> 8; + s[2] = h0 >> 16; + s[3] = (h0 >> 24) | (h1 << 2); + s[4] = h1 >> 6; + s[5] = h1 >> 14; + s[6] = (h1 >> 22) | (h2 << 3); + s[7] = h2 >> 5; + s[8] = h2 >> 13; + s[9] = (h2 >> 21) | (h3 << 5); + s[10] = h3 >> 3; + s[11] = h3 >> 11; + s[12] = (h3 >> 19) | (h4 << 6); + s[13] = h4 >> 2; + s[14] = h4 >> 10; + s[15] = h4 >> 18; + s[16] = h5 >> 0; + s[17] = h5 >> 8; + s[18] = h5 >> 16; + s[19] = (h5 >> 24) | (h6 << 1); + s[20] = h6 >> 7; + s[21] = h6 >> 15; + s[22] = (h6 >> 23) | (h7 << 3); + s[23] = h7 >> 5; + s[24] = h7 >> 13; + s[25] = (h7 >> 21) | (h8 << 4); + s[26] = h8 >> 4; + s[27] = h8 >> 12; + s[28] = (h8 >> 20) | (h9 << 6); + s[29] = h9 >> 2; + s[30] = h9 >> 10; + s[31] = h9 >> 18; +} diff --git a/libaxolotl/jni/ed25519/ge.h b/libaxolotl/jni/ed25519/ge.h new file mode 100644 index 000000000..55e95f95b --- /dev/null +++ b/libaxolotl/jni/ed25519/ge.h @@ -0,0 +1,95 @@ +#ifndef GE_H +#define GE_H + +/* +ge means group element. + +Here the group is the set of pairs (x,y) of field elements (see fe.h) +satisfying -x^2 + y^2 = 1 + d x^2y^2 +where d = -121665/121666. + +Representations: + ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + ge_precomp (Duif): (y+x,y-x,2dxy) +*/ + +#include "fe.h" + +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p1p1; + +typedef struct { + fe yplusx; + fe yminusx; + fe xy2d; +} ge_precomp; + +typedef struct { + fe YplusX; + fe YminusX; + fe Z; + fe T2d; +} ge_cached; + +#define ge_frombytes_negate_vartime crypto_sign_ed25519_ref10_ge_frombytes_negate_vartime +#define ge_tobytes crypto_sign_ed25519_ref10_ge_tobytes +#define ge_p3_tobytes crypto_sign_ed25519_ref10_ge_p3_tobytes + +#define ge_p2_0 crypto_sign_ed25519_ref10_ge_p2_0 +#define ge_p3_0 crypto_sign_ed25519_ref10_ge_p3_0 +#define ge_precomp_0 crypto_sign_ed25519_ref10_ge_precomp_0 +#define ge_p3_to_p2 crypto_sign_ed25519_ref10_ge_p3_to_p2 +#define ge_p3_to_cached crypto_sign_ed25519_ref10_ge_p3_to_cached +#define ge_p1p1_to_p2 crypto_sign_ed25519_ref10_ge_p1p1_to_p2 +#define ge_p1p1_to_p3 crypto_sign_ed25519_ref10_ge_p1p1_to_p3 +#define ge_p2_dbl crypto_sign_ed25519_ref10_ge_p2_dbl +#define ge_p3_dbl crypto_sign_ed25519_ref10_ge_p3_dbl + +#define ge_madd crypto_sign_ed25519_ref10_ge_madd +#define ge_msub crypto_sign_ed25519_ref10_ge_msub +#define ge_add crypto_sign_ed25519_ref10_ge_add +#define ge_sub crypto_sign_ed25519_ref10_ge_sub +#define ge_scalarmult_base crypto_sign_ed25519_ref10_ge_scalarmult_base +#define ge_double_scalarmult_vartime crypto_sign_ed25519_ref10_ge_double_scalarmult_vartime + +extern void ge_tobytes(unsigned char *,const ge_p2 *); +extern void ge_p3_tobytes(unsigned char *,const ge_p3 *); +extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *); + +extern void ge_p2_0(ge_p2 *); +extern void ge_p3_0(ge_p3 *); +extern void ge_precomp_0(ge_precomp *); +extern void ge_p3_to_p2(ge_p2 *,const ge_p3 *); +extern void ge_p3_to_cached(ge_cached *,const ge_p3 *); +extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *); +extern void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *); +extern void ge_p2_dbl(ge_p1p1 *,const ge_p2 *); +extern void ge_p3_dbl(ge_p1p1 *,const ge_p3 *); + +extern void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *); +extern void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *); +extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *); +extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *); +extern void ge_scalarmult_base(ge_p3 *,const unsigned char *); +extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *); + +#endif diff --git a/libaxolotl/jni/ed25519/ge_add.c b/libaxolotl/jni/ed25519/ge_add.c new file mode 100644 index 000000000..da7ff5d2e --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_add.c @@ -0,0 +1,11 @@ +#include "ge.h" + +/* +r = p + q +*/ + +void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) +{ + fe t0; +#include "ge_add.h" +} diff --git a/libaxolotl/jni/ed25519/ge_add.h b/libaxolotl/jni/ed25519/ge_add.h new file mode 100644 index 000000000..7481f8ffb --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_add.h @@ -0,0 +1,97 @@ + +/* qhasm: enter ge_add */ + +/* qhasm: fe X1 */ + +/* qhasm: fe Y1 */ + +/* qhasm: fe Z1 */ + +/* qhasm: fe Z2 */ + +/* qhasm: fe T1 */ + +/* qhasm: fe ZZ */ + +/* qhasm: fe YpX2 */ + +/* qhasm: fe YmX2 */ + +/* qhasm: fe T2d2 */ + +/* qhasm: fe X3 */ + +/* qhasm: fe Y3 */ + +/* qhasm: fe Z3 */ + +/* qhasm: fe T3 */ + +/* qhasm: fe YpX1 */ + +/* qhasm: fe YmX1 */ + +/* qhasm: fe A */ + +/* qhasm: fe B */ + +/* qhasm: fe C */ + +/* qhasm: fe D */ + +/* qhasm: YpX1 = Y1+X1 */ +/* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ +fe_add(r->X,p->Y,p->X); + +/* qhasm: YmX1 = Y1-X1 */ +/* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ +fe_sub(r->Y,p->Y,p->X); + +/* qhasm: A = YpX1*YpX2 */ +/* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YplusX); */ +fe_mul(r->Z,r->X,q->YplusX); + +/* qhasm: B = YmX1*YmX2 */ +/* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YminusX); */ +fe_mul(r->Y,r->Y,q->YminusX); + +/* qhasm: C = T2d2*T1 */ +/* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ +fe_mul(r->T,q->T2d,p->T); + +/* qhasm: ZZ = Z1*Z2 */ +/* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ +fe_mul(r->X,p->Z,q->Z); + +/* qhasm: D = 2*ZZ */ +/* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ +fe_add(t0,r->X,r->X); + +/* qhasm: X3 = A-B */ +/* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ +fe_sub(r->X,r->Z,r->Y); + +/* qhasm: Y3 = A+B */ +/* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ +fe_add(r->Y,r->Z,r->Y); + +/* qhasm: Z3 = D+C */ +/* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ +fe_add(r->Z,t0,r->T); + +/* qhasm: T3 = D-C */ +/* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ +fe_sub(r->T,t0,r->T); + +/* qhasm: return */ diff --git a/libaxolotl/jni/ed25519/ge_double_scalarmult.c b/libaxolotl/jni/ed25519/ge_double_scalarmult.c new file mode 100644 index 000000000..f8bf4bf77 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_double_scalarmult.c @@ -0,0 +1,96 @@ +#include "ge.h" + +static void slide(signed char *r,const unsigned char *a) +{ + int i; + int b; + int k; + + for (i = 0;i < 256;++i) + r[i] = 1 & (a[i >> 3] >> (i & 7)); + + for (i = 0;i < 256;++i) + if (r[i]) { + for (b = 1;b <= 6 && i + b < 256;++b) { + if (r[i + b]) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (k = i + b;k < 256;++k) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else + break; + } + } + } + +} + +static ge_precomp Bi[8] = { +#include "base2.h" +} ; + +/* +r = a * A + b * B +where a = a[0]+256*a[1]+...+256^31 a[31]. +and b = b[0]+256*b[1]+...+256^31 b[31]. +B is the Ed25519 base point (x,4/5) with x positive. +*/ + +void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b) +{ + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + + slide(aslide,a); + slide(bslide,b); + + ge_p3_to_cached(&Ai[0],A); + ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); + ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); + ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); + ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); + ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); + ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); + ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); + ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); + + ge_p2_0(r); + + for (i = 255;i >= 0;--i) { + if (aslide[i] || bslide[i]) break; + } + + for (;i >= 0;--i) { + ge_p2_dbl(&t,r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u,&t); + ge_add(&t,&u,&Ai[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u,&t); + ge_sub(&t,&u,&Ai[(-aslide[i])/2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u,&t); + ge_madd(&t,&u,&Bi[bslide[i]/2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u,&t); + ge_msub(&t,&u,&Bi[(-bslide[i])/2]); + } + + ge_p1p1_to_p2(r,&t); + } +} diff --git a/libaxolotl/jni/ed25519/ge_frombytes.c b/libaxolotl/jni/ed25519/ge_frombytes.c new file mode 100644 index 000000000..1a059ee93 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_frombytes.c @@ -0,0 +1,50 @@ +#include "ge.h" + +static const fe d = { +#include "d.h" +} ; + +static const fe sqrtm1 = { +#include "sqrtm1.h" +} ; + +int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s) +{ + fe u; + fe v; + fe v3; + fe vxx; + fe check; + + fe_frombytes(h->Y,s); + fe_1(h->Z); + fe_sq(u,h->Y); + fe_mul(v,u,d); + fe_sub(u,u,h->Z); /* u = y^2-1 */ + fe_add(v,v,h->Z); /* v = dy^2+1 */ + + fe_sq(v3,v); + fe_mul(v3,v3,v); /* v3 = v^3 */ + fe_sq(h->X,v3); + fe_mul(h->X,h->X,v); + fe_mul(h->X,h->X,u); /* x = uv^7 */ + + fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ + fe_mul(h->X,h->X,v3); + fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe_sq(vxx,h->X); + fe_mul(vxx,vxx,v); + fe_sub(check,vxx,u); /* vx^2-u */ + if (fe_isnonzero(check)) { + fe_add(check,vxx,u); /* vx^2+u */ + if (fe_isnonzero(check)) return -1; + fe_mul(h->X,h->X,sqrtm1); + } + + if (fe_isnegative(h->X) == (s[31] >> 7)) + fe_neg(h->X,h->X); + + fe_mul(h->T,h->X,h->Y); + return 0; +} diff --git a/libaxolotl/jni/ed25519/ge_madd.c b/libaxolotl/jni/ed25519/ge_madd.c new file mode 100644 index 000000000..622571774 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_madd.c @@ -0,0 +1,11 @@ +#include "ge.h" + +/* +r = p + q +*/ + +void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) +{ + fe t0; +#include "ge_madd.h" +} diff --git a/libaxolotl/jni/ed25519/ge_madd.h b/libaxolotl/jni/ed25519/ge_madd.h new file mode 100644 index 000000000..ecae84952 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_madd.h @@ -0,0 +1,88 @@ + +/* qhasm: enter ge_madd */ + +/* qhasm: fe X1 */ + +/* qhasm: fe Y1 */ + +/* qhasm: fe Z1 */ + +/* qhasm: fe T1 */ + +/* qhasm: fe ypx2 */ + +/* qhasm: fe ymx2 */ + +/* qhasm: fe xy2d2 */ + +/* qhasm: fe X3 */ + +/* qhasm: fe Y3 */ + +/* qhasm: fe Z3 */ + +/* qhasm: fe T3 */ + +/* qhasm: fe YpX1 */ + +/* qhasm: fe YmX1 */ + +/* qhasm: fe A */ + +/* qhasm: fe B */ + +/* qhasm: fe C */ + +/* qhasm: fe D */ + +/* qhasm: YpX1 = Y1+X1 */ +/* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ +fe_add(r->X,p->Y,p->X); + +/* qhasm: YmX1 = Y1-X1 */ +/* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ +fe_sub(r->Y,p->Y,p->X); + +/* qhasm: A = YpX1*ypx2 */ +/* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yplusx); */ +fe_mul(r->Z,r->X,q->yplusx); + +/* qhasm: B = YmX1*ymx2 */ +/* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yminusx); */ +fe_mul(r->Y,r->Y,q->yminusx); + +/* qhasm: C = xy2d2*T1 */ +/* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ +fe_mul(r->T,q->xy2d,p->T); + +/* qhasm: D = 2*Z1 */ +/* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ +fe_add(t0,p->Z,p->Z); + +/* qhasm: X3 = A-B */ +/* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ +fe_sub(r->X,r->Z,r->Y); + +/* qhasm: Y3 = A+B */ +/* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ +fe_add(r->Y,r->Z,r->Y); + +/* qhasm: Z3 = D+C */ +/* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ +fe_add(r->Z,t0,r->T); + +/* qhasm: T3 = D-C */ +/* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ +fe_sub(r->T,t0,r->T); + +/* qhasm: return */ diff --git a/libaxolotl/jni/ed25519/ge_msub.c b/libaxolotl/jni/ed25519/ge_msub.c new file mode 100644 index 000000000..741ecbf11 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_msub.c @@ -0,0 +1,11 @@ +#include "ge.h" + +/* +r = p - q +*/ + +void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) +{ + fe t0; +#include "ge_msub.h" +} diff --git a/libaxolotl/jni/ed25519/ge_msub.h b/libaxolotl/jni/ed25519/ge_msub.h new file mode 100644 index 000000000..500f986ba --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_msub.h @@ -0,0 +1,88 @@ + +/* qhasm: enter ge_msub */ + +/* qhasm: fe X1 */ + +/* qhasm: fe Y1 */ + +/* qhasm: fe Z1 */ + +/* qhasm: fe T1 */ + +/* qhasm: fe ypx2 */ + +/* qhasm: fe ymx2 */ + +/* qhasm: fe xy2d2 */ + +/* qhasm: fe X3 */ + +/* qhasm: fe Y3 */ + +/* qhasm: fe Z3 */ + +/* qhasm: fe T3 */ + +/* qhasm: fe YpX1 */ + +/* qhasm: fe YmX1 */ + +/* qhasm: fe A */ + +/* qhasm: fe B */ + +/* qhasm: fe C */ + +/* qhasm: fe D */ + +/* qhasm: YpX1 = Y1+X1 */ +/* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ +fe_add(r->X,p->Y,p->X); + +/* qhasm: YmX1 = Y1-X1 */ +/* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ +fe_sub(r->Y,p->Y,p->X); + +/* qhasm: A = YpX1*ymx2 */ +/* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yminusx); */ +fe_mul(r->Z,r->X,q->yminusx); + +/* qhasm: B = YmX1*ypx2 */ +/* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yplusx); */ +fe_mul(r->Y,r->Y,q->yplusx); + +/* qhasm: C = xy2d2*T1 */ +/* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ +fe_mul(r->T,q->xy2d,p->T); + +/* qhasm: D = 2*Z1 */ +/* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ +fe_add(t0,p->Z,p->Z); + +/* qhasm: X3 = A-B */ +/* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ +fe_sub(r->X,r->Z,r->Y); + +/* qhasm: Y3 = A+B */ +/* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ +fe_add(r->Y,r->Z,r->Y); + +/* qhasm: Z3 = D-C */ +/* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ +fe_sub(r->Z,t0,r->T); + +/* qhasm: T3 = D+C */ +/* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ +fe_add(r->T,t0,r->T); + +/* qhasm: return */ diff --git a/libaxolotl/jni/ed25519/ge_p1p1_to_p2.c b/libaxolotl/jni/ed25519/ge_p1p1_to_p2.c new file mode 100644 index 000000000..9bb5013d6 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p1p1_to_p2.c @@ -0,0 +1,12 @@ +#include "ge.h" + +/* +r = p +*/ + +extern void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p) +{ + fe_mul(r->X,p->X,p->T); + fe_mul(r->Y,p->Y,p->Z); + fe_mul(r->Z,p->Z,p->T); +} diff --git a/libaxolotl/jni/ed25519/ge_p1p1_to_p3.c b/libaxolotl/jni/ed25519/ge_p1p1_to_p3.c new file mode 100644 index 000000000..2f57b1096 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p1p1_to_p3.c @@ -0,0 +1,13 @@ +#include "ge.h" + +/* +r = p +*/ + +extern void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p) +{ + fe_mul(r->X,p->X,p->T); + fe_mul(r->Y,p->Y,p->Z); + fe_mul(r->Z,p->Z,p->T); + fe_mul(r->T,p->X,p->Y); +} diff --git a/libaxolotl/jni/ed25519/ge_p2_0.c b/libaxolotl/jni/ed25519/ge_p2_0.c new file mode 100644 index 000000000..6191d1e6e --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p2_0.c @@ -0,0 +1,8 @@ +#include "ge.h" + +void ge_p2_0(ge_p2 *h) +{ + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); +} diff --git a/libaxolotl/jni/ed25519/ge_p2_dbl.c b/libaxolotl/jni/ed25519/ge_p2_dbl.c new file mode 100644 index 000000000..2e332b5ce --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p2_dbl.c @@ -0,0 +1,11 @@ +#include "ge.h" + +/* +r = 2 * p +*/ + +void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p) +{ + fe t0; +#include "ge_p2_dbl.h" +} diff --git a/libaxolotl/jni/ed25519/ge_p2_dbl.h b/libaxolotl/jni/ed25519/ge_p2_dbl.h new file mode 100644 index 000000000..128efed90 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p2_dbl.h @@ -0,0 +1,73 @@ + +/* qhasm: enter ge_p2_dbl */ + +/* qhasm: fe X1 */ + +/* qhasm: fe Y1 */ + +/* qhasm: fe Z1 */ + +/* qhasm: fe A */ + +/* qhasm: fe AA */ + +/* qhasm: fe XX */ + +/* qhasm: fe YY */ + +/* qhasm: fe B */ + +/* qhasm: fe X3 */ + +/* qhasm: fe Y3 */ + +/* qhasm: fe Z3 */ + +/* qhasm: fe T3 */ + +/* qhasm: XX=X1^2 */ +/* asm 1: fe_sq(>XX=fe#1,XX=r->X,X); */ +fe_sq(r->X,p->X); + +/* qhasm: YY=Y1^2 */ +/* asm 1: fe_sq(>YY=fe#3,YY=r->Z,Y); */ +fe_sq(r->Z,p->Y); + +/* qhasm: B=2*Z1^2 */ +/* asm 1: fe_sq2(>B=fe#4,B=r->T,Z); */ +fe_sq2(r->T,p->Z); + +/* qhasm: A=X1+Y1 */ +/* asm 1: fe_add(>A=fe#2,A=r->Y,X,Y); */ +fe_add(r->Y,p->X,p->Y); + +/* qhasm: AA=A^2 */ +/* asm 1: fe_sq(>AA=fe#5,AA=t0,Y); */ +fe_sq(t0,r->Y); + +/* qhasm: Y3=YY+XX */ +/* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,X); */ +fe_add(r->Y,r->Z,r->X); + +/* qhasm: Z3=YY-XX */ +/* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,Z,X); */ +fe_sub(r->Z,r->Z,r->X); + +/* qhasm: X3=AA-Y3 */ +/* asm 1: fe_sub(>X3=fe#1,X3=r->X,Y); */ +fe_sub(r->X,t0,r->Y); + +/* qhasm: T3=B-Z3 */ +/* asm 1: fe_sub(>T3=fe#4,T3=r->T,T,Z); */ +fe_sub(r->T,r->T,r->Z); + +/* qhasm: return */ diff --git a/libaxolotl/jni/ed25519/ge_p3_0.c b/libaxolotl/jni/ed25519/ge_p3_0.c new file mode 100644 index 000000000..401b2935a --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p3_0.c @@ -0,0 +1,9 @@ +#include "ge.h" + +void ge_p3_0(ge_p3 *h) +{ + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); + fe_0(h->T); +} diff --git a/libaxolotl/jni/ed25519/ge_p3_dbl.c b/libaxolotl/jni/ed25519/ge_p3_dbl.c new file mode 100644 index 000000000..0d8a05915 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p3_dbl.c @@ -0,0 +1,12 @@ +#include "ge.h" + +/* +r = 2 * p +*/ + +void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p) +{ + ge_p2 q; + ge_p3_to_p2(&q,p); + ge_p2_dbl(r,&q); +} diff --git a/libaxolotl/jni/ed25519/ge_p3_to_cached.c b/libaxolotl/jni/ed25519/ge_p3_to_cached.c new file mode 100644 index 000000000..bde64228c --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p3_to_cached.c @@ -0,0 +1,17 @@ +#include "ge.h" + +/* +r = p +*/ + +static const fe d2 = { +#include "d2.h" +} ; + +extern void ge_p3_to_cached(ge_cached *r,const ge_p3 *p) +{ + fe_add(r->YplusX,p->Y,p->X); + fe_sub(r->YminusX,p->Y,p->X); + fe_copy(r->Z,p->Z); + fe_mul(r->T2d,p->T,d2); +} diff --git a/libaxolotl/jni/ed25519/ge_p3_to_p2.c b/libaxolotl/jni/ed25519/ge_p3_to_p2.c new file mode 100644 index 000000000..e532a9e4c --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p3_to_p2.c @@ -0,0 +1,12 @@ +#include "ge.h" + +/* +r = p +*/ + +extern void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p) +{ + fe_copy(r->X,p->X); + fe_copy(r->Y,p->Y); + fe_copy(r->Z,p->Z); +} diff --git a/libaxolotl/jni/ed25519/ge_p3_tobytes.c b/libaxolotl/jni/ed25519/ge_p3_tobytes.c new file mode 100644 index 000000000..21cb2fc65 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_p3_tobytes.c @@ -0,0 +1,14 @@ +#include "ge.h" + +void ge_p3_tobytes(unsigned char *s,const ge_p3 *h) +{ + fe recip; + fe x; + fe y; + + fe_invert(recip,h->Z); + fe_mul(x,h->X,recip); + fe_mul(y,h->Y,recip); + fe_tobytes(s,y); + s[31] ^= fe_isnegative(x) << 7; +} diff --git a/libaxolotl/jni/ed25519/ge_precomp_0.c b/libaxolotl/jni/ed25519/ge_precomp_0.c new file mode 100644 index 000000000..2e218861d --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_precomp_0.c @@ -0,0 +1,8 @@ +#include "ge.h" + +void ge_precomp_0(ge_precomp *h) +{ + fe_1(h->yplusx); + fe_1(h->yminusx); + fe_0(h->xy2d); +} diff --git a/libaxolotl/jni/ed25519/ge_scalarmult_base.c b/libaxolotl/jni/ed25519/ge_scalarmult_base.c new file mode 100644 index 000000000..421e4fa0f --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_scalarmult_base.c @@ -0,0 +1,105 @@ +#include "ge.h" +#include "crypto_uint32.h" + +static unsigned char equal(signed char b,signed char c) +{ + unsigned char ub = b; + unsigned char uc = c; + unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ + crypto_uint32 y = x; /* 0: yes; 1..255: no */ + y -= 1; /* 4294967295: yes; 0..254: no */ + y >>= 31; /* 1: yes; 0: no */ + return y; +} + +static unsigned char negative(signed char b) +{ + unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + x >>= 63; /* 1: yes; 0: no */ + return x; +} + +static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b) +{ + fe_cmov(t->yplusx,u->yplusx,b); + fe_cmov(t->yminusx,u->yminusx,b); + fe_cmov(t->xy2d,u->xy2d,b); +} + +/* base[i][j] = (j+1)*256^i*B */ +static ge_precomp base[32][8] = { +#include "base.h" +} ; + +static void select(ge_precomp *t,int pos,signed char b) +{ + ge_precomp minust; + unsigned char bnegative = negative(b); + unsigned char babs = b - (((-bnegative) & b) << 1); + + ge_precomp_0(t); + cmov(t,&base[pos][0],equal(babs,1)); + cmov(t,&base[pos][1],equal(babs,2)); + cmov(t,&base[pos][2],equal(babs,3)); + cmov(t,&base[pos][3],equal(babs,4)); + cmov(t,&base[pos][4],equal(babs,5)); + cmov(t,&base[pos][5],equal(babs,6)); + cmov(t,&base[pos][6],equal(babs,7)); + cmov(t,&base[pos][7],equal(babs,8)); + fe_copy(minust.yplusx,t->yminusx); + fe_copy(minust.yminusx,t->yplusx); + fe_neg(minust.xy2d,t->xy2d); + cmov(t,&minust,bnegative); +} + +/* +h = a * B +where a = a[0]+256*a[1]+...+256^31 a[31] +B is the Ed25519 base point (x,4/5) with x positive. + +Preconditions: + a[31] <= 127 +*/ + +void ge_scalarmult_base(ge_p3 *h,const unsigned char *a) +{ + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for (i = 0;i < 32;++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0;i < 63;++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge_p3_0(h); + for (i = 1;i < 64;i += 2) { + select(&t,i / 2,e[i]); + ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); + } + + ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r); + ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); + ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); + ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); + + for (i = 0;i < 64;i += 2) { + select(&t,i / 2,e[i]); + ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); + } +} diff --git a/libaxolotl/jni/ed25519/ge_sub.c b/libaxolotl/jni/ed25519/ge_sub.c new file mode 100644 index 000000000..69f3d5406 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_sub.c @@ -0,0 +1,11 @@ +#include "ge.h" + +/* +r = p - q +*/ + +void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) +{ + fe t0; +#include "ge_sub.h" +} diff --git a/libaxolotl/jni/ed25519/ge_sub.h b/libaxolotl/jni/ed25519/ge_sub.h new file mode 100644 index 000000000..b4ef1f5dd --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_sub.h @@ -0,0 +1,97 @@ + +/* qhasm: enter ge_sub */ + +/* qhasm: fe X1 */ + +/* qhasm: fe Y1 */ + +/* qhasm: fe Z1 */ + +/* qhasm: fe Z2 */ + +/* qhasm: fe T1 */ + +/* qhasm: fe ZZ */ + +/* qhasm: fe YpX2 */ + +/* qhasm: fe YmX2 */ + +/* qhasm: fe T2d2 */ + +/* qhasm: fe X3 */ + +/* qhasm: fe Y3 */ + +/* qhasm: fe Z3 */ + +/* qhasm: fe T3 */ + +/* qhasm: fe YpX1 */ + +/* qhasm: fe YmX1 */ + +/* qhasm: fe A */ + +/* qhasm: fe B */ + +/* qhasm: fe C */ + +/* qhasm: fe D */ + +/* qhasm: YpX1 = Y1+X1 */ +/* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ +fe_add(r->X,p->Y,p->X); + +/* qhasm: YmX1 = Y1-X1 */ +/* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ +fe_sub(r->Y,p->Y,p->X); + +/* qhasm: A = YpX1*YmX2 */ +/* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YminusX); */ +fe_mul(r->Z,r->X,q->YminusX); + +/* qhasm: B = YmX1*YpX2 */ +/* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YplusX); */ +fe_mul(r->Y,r->Y,q->YplusX); + +/* qhasm: C = T2d2*T1 */ +/* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ +fe_mul(r->T,q->T2d,p->T); + +/* qhasm: ZZ = Z1*Z2 */ +/* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ +fe_mul(r->X,p->Z,q->Z); + +/* qhasm: D = 2*ZZ */ +/* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ +fe_add(t0,r->X,r->X); + +/* qhasm: X3 = A-B */ +/* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ +fe_sub(r->X,r->Z,r->Y); + +/* qhasm: Y3 = A+B */ +/* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ +fe_add(r->Y,r->Z,r->Y); + +/* qhasm: Z3 = D-C */ +/* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ +fe_sub(r->Z,t0,r->T); + +/* qhasm: T3 = D+C */ +/* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ +fe_add(r->T,t0,r->T); + +/* qhasm: return */ diff --git a/libaxolotl/jni/ed25519/ge_tobytes.c b/libaxolotl/jni/ed25519/ge_tobytes.c new file mode 100644 index 000000000..31b3d33e0 --- /dev/null +++ b/libaxolotl/jni/ed25519/ge_tobytes.c @@ -0,0 +1,14 @@ +#include "ge.h" + +void ge_tobytes(unsigned char *s,const ge_p2 *h) +{ + fe recip; + fe x; + fe y; + + fe_invert(recip,h->Z); + fe_mul(x,h->X,recip); + fe_mul(y,h->Y,recip); + fe_tobytes(s,y); + s[31] ^= fe_isnegative(x) << 7; +} diff --git a/libaxolotl/jni/ed25519/main/main.c b/libaxolotl/jni/ed25519/main/main.c new file mode 100644 index 000000000..657b59f39 --- /dev/null +++ b/libaxolotl/jni/ed25519/main/main.c @@ -0,0 +1,41 @@ +#include +#include +#include "sha512.h" +#include "curve_sigs.h" + +int main(int argc, char* argv[]) +{ + unsigned char privkey[32]; + unsigned char pubkey[32]; + unsigned char signature[64]; + unsigned char msg[100]; + unsigned long long msg_len = 100; + + /* Initialize pubkey, privkey, msg */ + memset(msg, 0, 100); + memset(privkey, 0, 32); + memset(pubkey, 0, 32); + privkey[0] &= 248; + privkey[31] &= 63; + privkey[31] |= 64; + + privkey[8] = 189; /* just so there's some bits set */ + + curve25519_keygen(pubkey, privkey); + + curve25519_sign(signature, privkey, msg, msg_len); + + if (curve25519_verify(signature, pubkey, msg, msg_len) == 0) + printf("success #1\n"); + else + printf("failure #1\n"); + + signature[0] ^= 1; + + if (curve25519_verify(signature, pubkey, msg, msg_len) == 0) + printf("failure #2\n"); + else + printf("success #2\n"); + + return 1; +} diff --git a/libaxolotl/jni/ed25519/nacl_includes/crypto_hash_sha512.h b/libaxolotl/jni/ed25519/nacl_includes/crypto_hash_sha512.h new file mode 100644 index 000000000..b77f8620e --- /dev/null +++ b/libaxolotl/jni/ed25519/nacl_includes/crypto_hash_sha512.h @@ -0,0 +1,23 @@ +#ifndef crypto_hash_sha512_H +#define crypto_hash_sha512_H + +#define crypto_hash_sha512_ref_BYTES 64 +#ifdef __cplusplus +#include +extern std::string crypto_hash_sha512_ref(const std::string &); +extern "C" { +#endif +extern int crypto_hash_sha512_ref(unsigned char *,const unsigned char *,unsigned long long); +#ifdef __cplusplus +} +#endif + +#define crypto_hash_sha512 crypto_hash_sha512_ref +#define crypto_hash_sha512_BYTES crypto_hash_sha512_ref_BYTES +#define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/ref" +#ifndef crypto_hash_sha512_ref_VERSION +#define crypto_hash_sha512_ref_VERSION "-" +#endif +#define crypto_hash_sha512_VERSION crypto_hash_sha512_ref_VERSION + +#endif diff --git a/libaxolotl/jni/ed25519/nacl_includes/crypto_int32.h b/libaxolotl/jni/ed25519/nacl_includes/crypto_int32.h new file mode 100644 index 000000000..cae135e6e --- /dev/null +++ b/libaxolotl/jni/ed25519/nacl_includes/crypto_int32.h @@ -0,0 +1,6 @@ +#ifndef crypto_int32_h +#define crypto_int32_h + +typedef int crypto_int32; + +#endif diff --git a/libaxolotl/jni/ed25519/nacl_includes/crypto_int64.h b/libaxolotl/jni/ed25519/nacl_includes/crypto_int64.h new file mode 100644 index 000000000..fc92417b6 --- /dev/null +++ b/libaxolotl/jni/ed25519/nacl_includes/crypto_int64.h @@ -0,0 +1,6 @@ +#ifndef crypto_int64_h +#define crypto_int64_h + +typedef long long crypto_int64; + +#endif diff --git a/libaxolotl/jni/ed25519/nacl_includes/crypto_sign.h b/libaxolotl/jni/ed25519/nacl_includes/crypto_sign.h new file mode 100644 index 000000000..8472603e9 --- /dev/null +++ b/libaxolotl/jni/ed25519/nacl_includes/crypto_sign.h @@ -0,0 +1,16 @@ +#ifndef crypto_sign_H +#define crypto_sign_H + +#include "crypto_sign_edwards25519sha512batch.h" + +#define crypto_sign crypto_sign_edwards25519sha512batch +#define crypto_sign_open crypto_sign_edwards25519sha512batch_open +#define crypto_sign_keypair crypto_sign_edwards25519sha512batch_keypair +#define crypto_sign_BYTES crypto_sign_edwards25519sha512batch_BYTES +#define crypto_sign_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES +#define crypto_sign_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_SECRETKEYBYTES +#define crypto_sign_PRIMITIVE "edwards25519sha512batch" +#define crypto_sign_IMPLEMENTATION crypto_sign_edwards25519sha512batch_IMPLEMENTATION +#define crypto_sign_VERSION crypto_sign_edwards25519sha512batch_VERSION + +#endif diff --git a/libaxolotl/jni/ed25519/nacl_includes/crypto_sign_edwards25519sha512batch.h b/libaxolotl/jni/ed25519/nacl_includes/crypto_sign_edwards25519sha512batch.h new file mode 100644 index 000000000..62fae6116 --- /dev/null +++ b/libaxolotl/jni/ed25519/nacl_includes/crypto_sign_edwards25519sha512batch.h @@ -0,0 +1,33 @@ +#ifndef crypto_sign_edwards25519sha512batch_H +#define crypto_sign_edwards25519sha512batch_H + +#define crypto_sign_edwards25519sha512batch_ref10_SECRETKEYBYTES 64 +#define crypto_sign_edwards25519sha512batch_ref10_PUBLICKEYBYTES 32 +#define crypto_sign_edwards25519sha512batch_ref10_BYTES 64 +#ifdef __cplusplus +#include +extern std::string crypto_sign_edwards25519sha512batch_ref10(const std::string &,const std::string &); +extern std::string crypto_sign_edwards25519sha512batch_ref10_open(const std::string &,const std::string &); +extern std::string crypto_sign_edwards25519sha512batch_ref10_keypair(std::string *); +extern "C" { +#endif +extern int crypto_sign_edwards25519sha512batch_ref10(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); +extern int crypto_sign_edwards25519sha512batch_ref10_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); +extern int crypto_sign_edwards25519sha512batch_ref10_keypair(unsigned char *,unsigned char *); +#ifdef __cplusplus +} +#endif + +#define crypto_sign_edwards25519sha512batch crypto_sign_edwards25519sha512batch_ref10 +#define crypto_sign_edwards25519sha512batch_open crypto_sign_edwards25519sha512batch_ref10_open +#define crypto_sign_edwards25519sha512batch_keypair crypto_sign_edwards25519sha512batch_ref10_keypair +#define crypto_sign_edwards25519sha512batch_BYTES crypto_sign_edwards25519sha512batch_ref10_BYTES +#define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_ref10_PUBLICKEYBYTES +#define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_ref10_SECRETKEYBYTES +#define crypto_sign_edwards25519sha512batch_IMPLEMENTATION "crypto_sign/edwards25519sha512batch/ref10" +#ifndef crypto_sign_edwards25519sha512batch_ref10_VERSION +#define crypto_sign_edwards25519sha512batch_ref10_VERSION "-" +#endif +#define crypto_sign_edwards25519sha512batch_VERSION crypto_sign_edwards25519sha512batch_ref10_VERSION + +#endif diff --git a/libaxolotl/jni/ed25519/nacl_includes/crypto_uint32.h b/libaxolotl/jni/ed25519/nacl_includes/crypto_uint32.h new file mode 100644 index 000000000..21020d7b5 --- /dev/null +++ b/libaxolotl/jni/ed25519/nacl_includes/crypto_uint32.h @@ -0,0 +1,6 @@ +#ifndef crypto_uint32_h +#define crypto_uint32_h + +typedef unsigned int crypto_uint32; + +#endif diff --git a/libaxolotl/jni/ed25519/nacl_includes/crypto_uint64.h b/libaxolotl/jni/ed25519/nacl_includes/crypto_uint64.h new file mode 100644 index 000000000..5aa007037 --- /dev/null +++ b/libaxolotl/jni/ed25519/nacl_includes/crypto_uint64.h @@ -0,0 +1,6 @@ +#ifndef crypto_uint64_h +#define crypto_uint64_h + +typedef unsigned long long crypto_uint64; + +#endif diff --git a/libaxolotl/jni/ed25519/nacl_includes/crypto_verify_32.h b/libaxolotl/jni/ed25519/nacl_includes/crypto_verify_32.h new file mode 100644 index 000000000..978d84522 --- /dev/null +++ b/libaxolotl/jni/ed25519/nacl_includes/crypto_verify_32.h @@ -0,0 +1,22 @@ +#ifndef crypto_verify_32_H +#define crypto_verify_32_H + +#define crypto_verify_32_ref_BYTES 32 +#ifdef __cplusplus +#include +extern "C" { +#endif +extern int crypto_verify_32_ref(const unsigned char *,const unsigned char *); +#ifdef __cplusplus +} +#endif + +#define crypto_verify_32 crypto_verify_32_ref +#define crypto_verify_32_BYTES crypto_verify_32_ref_BYTES +#define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/ref" +#ifndef crypto_verify_32_ref_VERSION +#define crypto_verify_32_ref_VERSION "-" +#endif +#define crypto_verify_32_VERSION crypto_verify_32_ref_VERSION + +#endif diff --git a/libaxolotl/jni/ed25519/open.c b/libaxolotl/jni/ed25519/open.c new file mode 100644 index 000000000..1ec4cd2bf --- /dev/null +++ b/libaxolotl/jni/ed25519/open.c @@ -0,0 +1,48 @@ +#include +#include "crypto_sign.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_32.h" +#include "ge.h" +#include "sc.h" + +int crypto_sign_open( + unsigned char *m,unsigned long long *mlen, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk +) +{ + unsigned char pkcopy[32]; + unsigned char rcopy[32]; + unsigned char scopy[32]; + unsigned char h[64]; + unsigned char rcheck[32]; + ge_p3 A; + ge_p2 R; + + if (smlen < 64) goto badsig; + if (sm[63] & 224) goto badsig; + if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; + + memmove(pkcopy,pk,32); + memmove(rcopy,sm,32); + memmove(scopy,sm + 32,32); + + memmove(m,sm,smlen); + memmove(m + 32,pkcopy,32); + crypto_hash_sha512(h,m,smlen); + sc_reduce(h); + + ge_double_scalarmult_vartime(&R,h,&A,scopy); + ge_tobytes(rcheck,&R); + if (crypto_verify_32(rcheck,rcopy) == 0) { + memmove(m,m + 64,smlen - 64); + memset(m + smlen - 64,0,64); + *mlen = smlen - 64; + return 0; + } + +badsig: + *mlen = -1; + memset(m,0,smlen); + return -1; +} diff --git a/libaxolotl/jni/ed25519/pow22523.h b/libaxolotl/jni/ed25519/pow22523.h new file mode 100644 index 000000000..60ffe0d34 --- /dev/null +++ b/libaxolotl/jni/ed25519/pow22523.h @@ -0,0 +1,160 @@ + +/* qhasm: fe z1 */ + +/* qhasm: fe z2 */ + +/* qhasm: fe z8 */ + +/* qhasm: fe z9 */ + +/* qhasm: fe z11 */ + +/* qhasm: fe z22 */ + +/* qhasm: fe z_5_0 */ + +/* qhasm: fe z_10_5 */ + +/* qhasm: fe z_10_0 */ + +/* qhasm: fe z_20_10 */ + +/* qhasm: fe z_20_0 */ + +/* qhasm: fe z_40_20 */ + +/* qhasm: fe z_40_0 */ + +/* qhasm: fe z_50_10 */ + +/* qhasm: fe z_50_0 */ + +/* qhasm: fe z_100_50 */ + +/* qhasm: fe z_100_0 */ + +/* qhasm: fe z_200_100 */ + +/* qhasm: fe z_200_0 */ + +/* qhasm: fe z_250_50 */ + +/* qhasm: fe z_250_0 */ + +/* qhasm: fe z_252_2 */ + +/* qhasm: fe z_252_3 */ + +/* qhasm: enter pow22523 */ + +/* qhasm: z2 = z1^2^1 */ +/* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ +/* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ +fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); + +/* qhasm: z8 = z2^2^2 */ +/* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ +/* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ +fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); + +/* qhasm: z9 = z1*z8 */ +/* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#1,z22=fe#1,>z22=fe#1); */ +/* asm 2: fe_sq(>z22=t0,z22=t0,>z22=t0); */ +fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0); + +/* qhasm: z_5_0 = z9*z22 */ +/* asm 1: fe_mul(>z_5_0=fe#1,z_5_0=t0,z_10_5=fe#2,z_10_5=fe#2,>z_10_5=fe#2); */ +/* asm 2: fe_sq(>z_10_5=t1,z_10_5=t1,>z_10_5=t1); */ +fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1); + +/* qhasm: z_10_0 = z_10_5*z_5_0 */ +/* asm 1: fe_mul(>z_10_0=fe#1,z_10_0=t0,z_20_10=fe#2,z_20_10=fe#2,>z_20_10=fe#2); */ +/* asm 2: fe_sq(>z_20_10=t1,z_20_10=t1,>z_20_10=t1); */ +fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1); + +/* qhasm: z_20_0 = z_20_10*z_10_0 */ +/* asm 1: fe_mul(>z_20_0=fe#2,z_20_0=t1,z_40_20=fe#3,z_40_20=fe#3,>z_40_20=fe#3); */ +/* asm 2: fe_sq(>z_40_20=t2,z_40_20=t2,>z_40_20=t2); */ +fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2); + +/* qhasm: z_40_0 = z_40_20*z_20_0 */ +/* asm 1: fe_mul(>z_40_0=fe#2,z_40_0=t1,z_50_10=fe#2,z_50_10=fe#2,>z_50_10=fe#2); */ +/* asm 2: fe_sq(>z_50_10=t1,z_50_10=t1,>z_50_10=t1); */ +fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1); + +/* qhasm: z_50_0 = z_50_10*z_10_0 */ +/* asm 1: fe_mul(>z_50_0=fe#1,z_50_0=t0,z_100_50=fe#2,z_100_50=fe#2,>z_100_50=fe#2); */ +/* asm 2: fe_sq(>z_100_50=t1,z_100_50=t1,>z_100_50=t1); */ +fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1); + +/* qhasm: z_100_0 = z_100_50*z_50_0 */ +/* asm 1: fe_mul(>z_100_0=fe#2,z_100_0=t1,z_200_100=fe#3,z_200_100=fe#3,>z_200_100=fe#3); */ +/* asm 2: fe_sq(>z_200_100=t2,z_200_100=t2,>z_200_100=t2); */ +fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2); + +/* qhasm: z_200_0 = z_200_100*z_100_0 */ +/* asm 1: fe_mul(>z_200_0=fe#2,z_200_0=t1,z_250_50=fe#2,z_250_50=fe#2,>z_250_50=fe#2); */ +/* asm 2: fe_sq(>z_250_50=t1,z_250_50=t1,>z_250_50=t1); */ +fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1); + +/* qhasm: z_250_0 = z_250_50*z_50_0 */ +/* asm 1: fe_mul(>z_250_0=fe#1,z_250_0=t0,z_252_2=fe#1,z_252_2=fe#1,>z_252_2=fe#1); */ +/* asm 2: fe_sq(>z_252_2=t0,z_252_2=t0,>z_252_2=t0); */ +fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0); + +/* qhasm: z_252_3 = z_252_2*z1 */ +/* asm 1: fe_mul(>z_252_3=fe#12,z_252_3=out,z2=fe#1,z2=fe#1,>z2=fe#1); */ +/* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ +fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); + +/* qhasm: z8 = z2^2^2 */ +/* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ +/* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ +fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); + +/* qhasm: z9 = z1*z8 */ +/* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#3,z22=fe#3,>z22=fe#3); */ +/* asm 2: fe_sq(>z22=t2,z22=t2,>z22=t2); */ +fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2); + +/* qhasm: z_5_0 = z9*z22 */ +/* asm 1: fe_mul(>z_5_0=fe#2,z_5_0=t1,z_10_5=fe#3,z_10_5=fe#3,>z_10_5=fe#3); */ +/* asm 2: fe_sq(>z_10_5=t2,z_10_5=t2,>z_10_5=t2); */ +fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2); + +/* qhasm: z_10_0 = z_10_5*z_5_0 */ +/* asm 1: fe_mul(>z_10_0=fe#2,z_10_0=t1,z_20_10=fe#3,z_20_10=fe#3,>z_20_10=fe#3); */ +/* asm 2: fe_sq(>z_20_10=t2,z_20_10=t2,>z_20_10=t2); */ +fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2); + +/* qhasm: z_20_0 = z_20_10*z_10_0 */ +/* asm 1: fe_mul(>z_20_0=fe#3,z_20_0=t2,z_40_20=fe#4,z_40_20=fe#4,>z_40_20=fe#4); */ +/* asm 2: fe_sq(>z_40_20=t3,z_40_20=t3,>z_40_20=t3); */ +fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3); + +/* qhasm: z_40_0 = z_40_20*z_20_0 */ +/* asm 1: fe_mul(>z_40_0=fe#3,z_40_0=t2,z_50_10=fe#3,z_50_10=fe#3,>z_50_10=fe#3); */ +/* asm 2: fe_sq(>z_50_10=t2,z_50_10=t2,>z_50_10=t2); */ +fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2); + +/* qhasm: z_50_0 = z_50_10*z_10_0 */ +/* asm 1: fe_mul(>z_50_0=fe#2,z_50_0=t1,z_100_50=fe#3,z_100_50=fe#3,>z_100_50=fe#3); */ +/* asm 2: fe_sq(>z_100_50=t2,z_100_50=t2,>z_100_50=t2); */ +fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2); + +/* qhasm: z_100_0 = z_100_50*z_50_0 */ +/* asm 1: fe_mul(>z_100_0=fe#3,z_100_0=t2,z_200_100=fe#4,z_200_100=fe#4,>z_200_100=fe#4); */ +/* asm 2: fe_sq(>z_200_100=t3,z_200_100=t3,>z_200_100=t3); */ +fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3); + +/* qhasm: z_200_0 = z_200_100*z_100_0 */ +/* asm 1: fe_mul(>z_200_0=fe#3,z_200_0=t2,z_250_50=fe#3,z_250_50=fe#3,>z_250_50=fe#3); */ +/* asm 2: fe_sq(>z_250_50=t2,z_250_50=t2,>z_250_50=t2); */ +fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2); + +/* qhasm: z_250_0 = z_250_50*z_50_0 */ +/* asm 1: fe_mul(>z_250_0=fe#2,z_250_0=t1,z_255_5=fe#2,z_255_5=fe#2,>z_255_5=fe#2); */ +/* asm 2: fe_sq(>z_255_5=t1,z_255_5=t1,>z_255_5=t1); */ +fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1); + +/* qhasm: z_255_21 = z_255_5*z11 */ +/* asm 1: fe_mul(>z_255_21=fe#12,z_255_21=out,> 5); + crypto_int64 a2 = 2097151 & (load_3(a + 5) >> 2); + crypto_int64 a3 = 2097151 & (load_4(a + 7) >> 7); + crypto_int64 a4 = 2097151 & (load_4(a + 10) >> 4); + crypto_int64 a5 = 2097151 & (load_3(a + 13) >> 1); + crypto_int64 a6 = 2097151 & (load_4(a + 15) >> 6); + crypto_int64 a7 = 2097151 & (load_3(a + 18) >> 3); + crypto_int64 a8 = 2097151 & load_3(a + 21); + crypto_int64 a9 = 2097151 & (load_4(a + 23) >> 5); + crypto_int64 a10 = 2097151 & (load_3(a + 26) >> 2); + crypto_int64 a11 = (load_4(a + 28) >> 7); + crypto_int64 b0 = 2097151 & load_3(b); + crypto_int64 b1 = 2097151 & (load_4(b + 2) >> 5); + crypto_int64 b2 = 2097151 & (load_3(b + 5) >> 2); + crypto_int64 b3 = 2097151 & (load_4(b + 7) >> 7); + crypto_int64 b4 = 2097151 & (load_4(b + 10) >> 4); + crypto_int64 b5 = 2097151 & (load_3(b + 13) >> 1); + crypto_int64 b6 = 2097151 & (load_4(b + 15) >> 6); + crypto_int64 b7 = 2097151 & (load_3(b + 18) >> 3); + crypto_int64 b8 = 2097151 & load_3(b + 21); + crypto_int64 b9 = 2097151 & (load_4(b + 23) >> 5); + crypto_int64 b10 = 2097151 & (load_3(b + 26) >> 2); + crypto_int64 b11 = (load_4(b + 28) >> 7); + crypto_int64 c0 = 2097151 & load_3(c); + crypto_int64 c1 = 2097151 & (load_4(c + 2) >> 5); + crypto_int64 c2 = 2097151 & (load_3(c + 5) >> 2); + crypto_int64 c3 = 2097151 & (load_4(c + 7) >> 7); + crypto_int64 c4 = 2097151 & (load_4(c + 10) >> 4); + crypto_int64 c5 = 2097151 & (load_3(c + 13) >> 1); + crypto_int64 c6 = 2097151 & (load_4(c + 15) >> 6); + crypto_int64 c7 = 2097151 & (load_3(c + 18) >> 3); + crypto_int64 c8 = 2097151 & load_3(c + 21); + crypto_int64 c9 = 2097151 & (load_4(c + 23) >> 5); + crypto_int64 c10 = 2097151 & (load_3(c + 26) >> 2); + crypto_int64 c11 = (load_4(c + 28) >> 7); + crypto_int64 s0; + crypto_int64 s1; + crypto_int64 s2; + crypto_int64 s3; + crypto_int64 s4; + crypto_int64 s5; + crypto_int64 s6; + crypto_int64 s7; + crypto_int64 s8; + crypto_int64 s9; + crypto_int64 s10; + crypto_int64 s11; + crypto_int64 s12; + crypto_int64 s13; + crypto_int64 s14; + crypto_int64 s15; + crypto_int64 s16; + crypto_int64 s17; + crypto_int64 s18; + crypto_int64 s19; + crypto_int64 s20; + crypto_int64 s21; + crypto_int64 s22; + crypto_int64 s23; + crypto_int64 carry0; + crypto_int64 carry1; + crypto_int64 carry2; + crypto_int64 carry3; + crypto_int64 carry4; + crypto_int64 carry5; + crypto_int64 carry6; + crypto_int64 carry7; + crypto_int64 carry8; + crypto_int64 carry9; + crypto_int64 carry10; + crypto_int64 carry11; + crypto_int64 carry12; + crypto_int64 carry13; + crypto_int64 carry14; + crypto_int64 carry15; + crypto_int64 carry16; + crypto_int64 carry17; + crypto_int64 carry18; + crypto_int64 carry19; + crypto_int64 carry20; + crypto_int64 carry21; + crypto_int64 carry22; + + s0 = c0 + a0*b0; + s1 = c1 + a0*b1 + a1*b0; + s2 = c2 + a0*b2 + a1*b1 + a2*b0; + s3 = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0; + s4 = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0; + s5 = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0; + s6 = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0; + s7 = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0; + s8 = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0; + s9 = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0; + s10 = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0; + s11 = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0; + s12 = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1; + s13 = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2; + s14 = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3; + s15 = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4; + s16 = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5; + s17 = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6; + s18 = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7; + s19 = a8*b11 + a9*b10 + a10*b9 + a11*b8; + s20 = a9*b11 + a10*b10 + a11*b9; + s21 = a10*b11 + a11*b10; + s22 = a11*b11; + s23 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; + carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; + carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; + carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; + carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} diff --git a/libaxolotl/jni/ed25519/sc_reduce.c b/libaxolotl/jni/ed25519/sc_reduce.c new file mode 100644 index 000000000..d01f5a573 --- /dev/null +++ b/libaxolotl/jni/ed25519/sc_reduce.c @@ -0,0 +1,275 @@ +#include "sc.h" +#include "crypto_int64.h" +#include "crypto_uint32.h" +#include "crypto_uint64.h" + +static crypto_uint64 load_3(const unsigned char *in) +{ + crypto_uint64 result; + result = (crypto_uint64) in[0]; + result |= ((crypto_uint64) in[1]) << 8; + result |= ((crypto_uint64) in[2]) << 16; + return result; +} + +static crypto_uint64 load_4(const unsigned char *in) +{ + crypto_uint64 result; + result = (crypto_uint64) in[0]; + result |= ((crypto_uint64) in[1]) << 8; + result |= ((crypto_uint64) in[2]) << 16; + result |= ((crypto_uint64) in[3]) << 24; + return result; +} + +/* +Input: + s[0]+256*s[1]+...+256^63*s[63] = s + +Output: + s[0]+256*s[1]+...+256^31*s[31] = s mod l + where l = 2^252 + 27742317777372353535851937790883648493. + Overwrites s in place. +*/ + +void sc_reduce(unsigned char *s) +{ + crypto_int64 s0 = 2097151 & load_3(s); + crypto_int64 s1 = 2097151 & (load_4(s + 2) >> 5); + crypto_int64 s2 = 2097151 & (load_3(s + 5) >> 2); + crypto_int64 s3 = 2097151 & (load_4(s + 7) >> 7); + crypto_int64 s4 = 2097151 & (load_4(s + 10) >> 4); + crypto_int64 s5 = 2097151 & (load_3(s + 13) >> 1); + crypto_int64 s6 = 2097151 & (load_4(s + 15) >> 6); + crypto_int64 s7 = 2097151 & (load_3(s + 18) >> 3); + crypto_int64 s8 = 2097151 & load_3(s + 21); + crypto_int64 s9 = 2097151 & (load_4(s + 23) >> 5); + crypto_int64 s10 = 2097151 & (load_3(s + 26) >> 2); + crypto_int64 s11 = 2097151 & (load_4(s + 28) >> 7); + crypto_int64 s12 = 2097151 & (load_4(s + 31) >> 4); + crypto_int64 s13 = 2097151 & (load_3(s + 34) >> 1); + crypto_int64 s14 = 2097151 & (load_4(s + 36) >> 6); + crypto_int64 s15 = 2097151 & (load_3(s + 39) >> 3); + crypto_int64 s16 = 2097151 & load_3(s + 42); + crypto_int64 s17 = 2097151 & (load_4(s + 44) >> 5); + crypto_int64 s18 = 2097151 & (load_3(s + 47) >> 2); + crypto_int64 s19 = 2097151 & (load_4(s + 49) >> 7); + crypto_int64 s20 = 2097151 & (load_4(s + 52) >> 4); + crypto_int64 s21 = 2097151 & (load_3(s + 55) >> 1); + crypto_int64 s22 = 2097151 & (load_4(s + 57) >> 6); + crypto_int64 s23 = (load_4(s + 60) >> 3); + crypto_int64 carry0; + crypto_int64 carry1; + crypto_int64 carry2; + crypto_int64 carry3; + crypto_int64 carry4; + crypto_int64 carry5; + crypto_int64 carry6; + crypto_int64 carry7; + crypto_int64 carry8; + crypto_int64 carry9; + crypto_int64 carry10; + crypto_int64 carry11; + crypto_int64 carry12; + crypto_int64 carry13; + crypto_int64 carry14; + crypto_int64 carry15; + crypto_int64 carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} diff --git a/libaxolotl/jni/ed25519/sha512/LICENSE.txt b/libaxolotl/jni/ed25519/sha512/LICENSE.txt new file mode 100644 index 000000000..9789d32a1 --- /dev/null +++ b/libaxolotl/jni/ed25519/sha512/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2007-2011 Projet RNRT SAPHIR + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libaxolotl/jni/ed25519/sha512/md_helper.c b/libaxolotl/jni/ed25519/sha512/md_helper.c new file mode 100644 index 000000000..5384f03f7 --- /dev/null +++ b/libaxolotl/jni/ed25519/sha512/md_helper.c @@ -0,0 +1,346 @@ +/* $Id: md_helper.c 216 2010-06-08 09:46:57Z tp $ */ +/* + * This file contains some functions which implement the external data + * handling and padding for Merkle-Damgard hash functions which follow + * the conventions set out by MD4 (little-endian) or SHA-1 (big-endian). + * + * API: this file is meant to be included, not compiled as a stand-alone + * file. Some macros must be defined: + * RFUN name for the round function + * HASH "short name" for the hash function + * BE32 defined for big-endian, 32-bit based (e.g. SHA-1) + * LE32 defined for little-endian, 32-bit based (e.g. MD5) + * BE64 defined for big-endian, 64-bit based (e.g. SHA-512) + * LE64 defined for little-endian, 64-bit based (no example yet) + * PW01 if defined, append 0x01 instead of 0x80 (for Tiger) + * BLEN if defined, length of a message block (in bytes) + * PLW1 if defined, length is defined on one 64-bit word only (for Tiger) + * PLW4 if defined, length is defined on four 64-bit words (for WHIRLPOOL) + * SVAL if defined, reference to the context state information + * + * BLEN is used when a message block is not 16 (32-bit or 64-bit) words: + * this is used for instance for Tiger, which works on 64-bit words but + * uses 512-bit message blocks (eight 64-bit words). PLW1 and PLW4 are + * ignored if 32-bit words are used; if 64-bit words are used and PLW1 is + * set, then only one word (64 bits) will be used to encode the input + * message length (in bits), otherwise two words will be used (as in + * SHA-384 and SHA-512). If 64-bit words are used and PLW4 is defined (but + * not PLW1), four 64-bit words will be used to encode the message length + * (in bits). Note that regardless of those settings, only 64-bit message + * lengths are supported (in bits): messages longer than 2 Exabytes will be + * improperly hashed (this is unlikely to happen soon: 2 Exabytes is about + * 2 millions Terabytes, which is huge). + * + * If CLOSE_ONLY is defined, then this file defines only the sph_XXX_close() + * function. This is used for Tiger2, which is identical to Tiger except + * when it comes to the padding (Tiger2 uses the standard 0x80 byte instead + * of the 0x01 from original Tiger). + * + * The RFUN function is invoked with two arguments, the first pointing to + * aligned data (as a "const void *"), the second being state information + * from the context structure. By default, this state information is the + * "val" field from the context, and this field is assumed to be an array + * of words ("sph_u32" or "sph_u64", depending on BE32/LE32/BE64/LE64). + * from the context structure. The "val" field can have any type, except + * for the output encoding which assumes that it is an array of "sph_u32" + * values. By defining NO_OUTPUT, this last step is deactivated; the + * includer code is then responsible for writing out the hash result. When + * NO_OUTPUT is defined, the third parameter to the "close()" function is + * ignored. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#undef SPH_XCAT +#define SPH_XCAT(a, b) SPH_XCAT_(a, b) +#undef SPH_XCAT_ +#define SPH_XCAT_(a, b) a ## b + +#undef SPH_BLEN +#undef SPH_WLEN +#if defined BE64 || defined LE64 +#define SPH_BLEN 128U +#define SPH_WLEN 8U +#else +#define SPH_BLEN 64U +#define SPH_WLEN 4U +#endif + +#ifdef BLEN +#undef SPH_BLEN +#define SPH_BLEN BLEN +#endif + +#undef SPH_MAXPAD +#if defined PLW1 +#define SPH_MAXPAD (SPH_BLEN - SPH_WLEN) +#elif defined PLW4 +#define SPH_MAXPAD (SPH_BLEN - (SPH_WLEN << 2)) +#else +#define SPH_MAXPAD (SPH_BLEN - (SPH_WLEN << 1)) +#endif + +#undef SPH_VAL +#undef SPH_NO_OUTPUT +#ifdef SVAL +#define SPH_VAL SVAL +#define SPH_NO_OUTPUT 1 +#else +#define SPH_VAL sc->val +#endif + +#ifndef CLOSE_ONLY + +#ifdef SPH_UPTR +static void +SPH_XCAT(HASH, _short)(void *cc, const void *data, size_t len) +#else +void +SPH_XCAT(sph_, HASH)(void *cc, const void *data, size_t len) +#endif +{ + SPH_XCAT(sph_, SPH_XCAT(HASH, _context)) *sc; + unsigned current; + + sc = cc; +#if SPH_64 + current = (unsigned)sc->count & (SPH_BLEN - 1U); +#else + current = (unsigned)sc->count_low & (SPH_BLEN - 1U); +#endif + while (len > 0) { + unsigned clen; +#if !SPH_64 + sph_u32 clow, clow2; +#endif + + clen = SPH_BLEN - current; + if (clen > len) + clen = len; + memcpy(sc->buf + current, data, clen); + data = (const unsigned char *)data + clen; + current += clen; + len -= clen; + if (current == SPH_BLEN) { + RFUN(sc->buf, SPH_VAL); + current = 0; + } +#if SPH_64 + sc->count += clen; +#else + clow = sc->count_low; + clow2 = SPH_T32(clow + clen); + sc->count_low = clow2; + if (clow2 < clow) + sc->count_high ++; +#endif + } +} + +#ifdef SPH_UPTR +void +SPH_XCAT(sph_, HASH)(void *cc, const void *data, size_t len) +{ + SPH_XCAT(sph_, SPH_XCAT(HASH, _context)) *sc; + unsigned current; + size_t orig_len; +#if !SPH_64 + sph_u32 clow, clow2; +#endif + + if (len < (2 * SPH_BLEN)) { + SPH_XCAT(HASH, _short)(cc, data, len); + return; + } + sc = cc; +#if SPH_64 + current = (unsigned)sc->count & (SPH_BLEN - 1U); +#else + current = (unsigned)sc->count_low & (SPH_BLEN - 1U); +#endif + if (current > 0) { + unsigned t; + + t = SPH_BLEN - current; + SPH_XCAT(HASH, _short)(cc, data, t); + data = (const unsigned char *)data + t; + len -= t; + } +#if !SPH_UNALIGNED + if (((SPH_UPTR)data & (SPH_WLEN - 1U)) != 0) { + SPH_XCAT(HASH, _short)(cc, data, len); + return; + } +#endif + orig_len = len; + while (len >= SPH_BLEN) { + RFUN(data, SPH_VAL); + len -= SPH_BLEN; + data = (const unsigned char *)data + SPH_BLEN; + } + if (len > 0) + memcpy(sc->buf, data, len); +#if SPH_64 + sc->count += (sph_u64)orig_len; +#else + clow = sc->count_low; + clow2 = SPH_T32(clow + orig_len); + sc->count_low = clow2; + if (clow2 < clow) + sc->count_high ++; + /* + * This code handles the improbable situation where "size_t" is + * greater than 32 bits, and yet we do not have a 64-bit type. + */ + orig_len >>= 12; + orig_len >>= 10; + orig_len >>= 10; + sc->count_high += orig_len; +#endif +} +#endif + +#endif + +/* + * Perform padding and produce result. The context is NOT reinitialized + * by this function. + */ +static void +SPH_XCAT(HASH, _addbits_and_close)(void *cc, + unsigned ub, unsigned n, void *dst, unsigned rnum) +{ + SPH_XCAT(sph_, SPH_XCAT(HASH, _context)) *sc; + unsigned current, u; +#if !SPH_64 + sph_u32 low, high; +#endif + + sc = cc; +#if SPH_64 + current = (unsigned)sc->count & (SPH_BLEN - 1U); +#else + current = (unsigned)sc->count_low & (SPH_BLEN - 1U); +#endif +#ifdef PW01 + sc->buf[current ++] = (0x100 | (ub & 0xFF)) >> (8 - n); +#else + { + unsigned z; + + z = 0x80 >> n; + sc->buf[current ++] = ((ub & -z) | z) & 0xFF; + } +#endif + if (current > SPH_MAXPAD) { + memset(sc->buf + current, 0, SPH_BLEN - current); + RFUN(sc->buf, SPH_VAL); + memset(sc->buf, 0, SPH_MAXPAD); + } else { + memset(sc->buf + current, 0, SPH_MAXPAD - current); + } +#if defined BE64 +#if defined PLW1 + sph_enc64be_aligned(sc->buf + SPH_MAXPAD, + SPH_T64(sc->count << 3) + (sph_u64)n); +#elif defined PLW4 + memset(sc->buf + SPH_MAXPAD, 0, 2 * SPH_WLEN); + sph_enc64be_aligned(sc->buf + SPH_MAXPAD + 2 * SPH_WLEN, + sc->count >> 61); + sph_enc64be_aligned(sc->buf + SPH_MAXPAD + 3 * SPH_WLEN, + SPH_T64(sc->count << 3) + (sph_u64)n); +#else + sph_enc64be_aligned(sc->buf + SPH_MAXPAD, sc->count >> 61); + sph_enc64be_aligned(sc->buf + SPH_MAXPAD + SPH_WLEN, + SPH_T64(sc->count << 3) + (sph_u64)n); +#endif +#elif defined LE64 +#if defined PLW1 + sph_enc64le_aligned(sc->buf + SPH_MAXPAD, + SPH_T64(sc->count << 3) + (sph_u64)n); +#elif defined PLW1 + sph_enc64le_aligned(sc->buf + SPH_MAXPAD, + SPH_T64(sc->count << 3) + (sph_u64)n); + sph_enc64le_aligned(sc->buf + SPH_MAXPAD + SPH_WLEN, sc->count >> 61); + memset(sc->buf + SPH_MAXPAD + 2 * SPH_WLEN, 0, 2 * SPH_WLEN); +#else + sph_enc64le_aligned(sc->buf + SPH_MAXPAD, + SPH_T64(sc->count << 3) + (sph_u64)n); + sph_enc64le_aligned(sc->buf + SPH_MAXPAD + SPH_WLEN, sc->count >> 61); +#endif +#else +#if SPH_64 +#ifdef BE32 + sph_enc64be_aligned(sc->buf + SPH_MAXPAD, + SPH_T64(sc->count << 3) + (sph_u64)n); +#else + sph_enc64le_aligned(sc->buf + SPH_MAXPAD, + SPH_T64(sc->count << 3) + (sph_u64)n); +#endif +#else + low = sc->count_low; + high = SPH_T32((sc->count_high << 3) | (low >> 29)); + low = SPH_T32(low << 3) + (sph_u32)n; +#ifdef BE32 + sph_enc32be(sc->buf + SPH_MAXPAD, high); + sph_enc32be(sc->buf + SPH_MAXPAD + SPH_WLEN, low); +#else + sph_enc32le(sc->buf + SPH_MAXPAD, low); + sph_enc32le(sc->buf + SPH_MAXPAD + SPH_WLEN, high); +#endif +#endif +#endif + RFUN(sc->buf, SPH_VAL); +#ifdef SPH_NO_OUTPUT + (void)dst; + (void)rnum; + (void)u; +#else + for (u = 0; u < rnum; u ++) { +#if defined BE64 + sph_enc64be((unsigned char *)dst + 8 * u, sc->val[u]); +#elif defined LE64 + sph_enc64le((unsigned char *)dst + 8 * u, sc->val[u]); +#elif defined BE32 + sph_enc32be((unsigned char *)dst + 4 * u, sc->val[u]); +#else + sph_enc32le((unsigned char *)dst + 4 * u, sc->val[u]); +#endif + } +#endif +} + +static void +SPH_XCAT(HASH, _close)(void *cc, void *dst, unsigned rnum) +{ + SPH_XCAT(HASH, _addbits_and_close)(cc, 0, 0, dst, rnum); +} diff --git a/libaxolotl/jni/ed25519/sha512/sha2big.c b/libaxolotl/jni/ed25519/sha512/sha2big.c new file mode 100644 index 000000000..a6992233a --- /dev/null +++ b/libaxolotl/jni/ed25519/sha512/sha2big.c @@ -0,0 +1,247 @@ +/* $Id: sha2big.c 216 2010-06-08 09:46:57Z tp $ */ +/* + * SHA-384 / SHA-512 implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include + +#include "sph_sha2.h" + +#if SPH_64 + +#define CH(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z)) +#define MAJ(X, Y, Z) (((X) & (Y)) | (((X) | (Y)) & (Z))) + +#define ROTR64 SPH_ROTR64 + +#define BSG5_0(x) (ROTR64(x, 28) ^ ROTR64(x, 34) ^ ROTR64(x, 39)) +#define BSG5_1(x) (ROTR64(x, 14) ^ ROTR64(x, 18) ^ ROTR64(x, 41)) +#define SSG5_0(x) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ SPH_T64((x) >> 7)) +#define SSG5_1(x) (ROTR64(x, 19) ^ ROTR64(x, 61) ^ SPH_T64((x) >> 6)) + +static const sph_u64 K512[80] = { + SPH_C64(0x428A2F98D728AE22), SPH_C64(0x7137449123EF65CD), + SPH_C64(0xB5C0FBCFEC4D3B2F), SPH_C64(0xE9B5DBA58189DBBC), + SPH_C64(0x3956C25BF348B538), SPH_C64(0x59F111F1B605D019), + SPH_C64(0x923F82A4AF194F9B), SPH_C64(0xAB1C5ED5DA6D8118), + SPH_C64(0xD807AA98A3030242), SPH_C64(0x12835B0145706FBE), + SPH_C64(0x243185BE4EE4B28C), SPH_C64(0x550C7DC3D5FFB4E2), + SPH_C64(0x72BE5D74F27B896F), SPH_C64(0x80DEB1FE3B1696B1), + SPH_C64(0x9BDC06A725C71235), SPH_C64(0xC19BF174CF692694), + SPH_C64(0xE49B69C19EF14AD2), SPH_C64(0xEFBE4786384F25E3), + SPH_C64(0x0FC19DC68B8CD5B5), SPH_C64(0x240CA1CC77AC9C65), + SPH_C64(0x2DE92C6F592B0275), SPH_C64(0x4A7484AA6EA6E483), + SPH_C64(0x5CB0A9DCBD41FBD4), SPH_C64(0x76F988DA831153B5), + SPH_C64(0x983E5152EE66DFAB), SPH_C64(0xA831C66D2DB43210), + SPH_C64(0xB00327C898FB213F), SPH_C64(0xBF597FC7BEEF0EE4), + SPH_C64(0xC6E00BF33DA88FC2), SPH_C64(0xD5A79147930AA725), + SPH_C64(0x06CA6351E003826F), SPH_C64(0x142929670A0E6E70), + SPH_C64(0x27B70A8546D22FFC), SPH_C64(0x2E1B21385C26C926), + SPH_C64(0x4D2C6DFC5AC42AED), SPH_C64(0x53380D139D95B3DF), + SPH_C64(0x650A73548BAF63DE), SPH_C64(0x766A0ABB3C77B2A8), + SPH_C64(0x81C2C92E47EDAEE6), SPH_C64(0x92722C851482353B), + SPH_C64(0xA2BFE8A14CF10364), SPH_C64(0xA81A664BBC423001), + SPH_C64(0xC24B8B70D0F89791), SPH_C64(0xC76C51A30654BE30), + SPH_C64(0xD192E819D6EF5218), SPH_C64(0xD69906245565A910), + SPH_C64(0xF40E35855771202A), SPH_C64(0x106AA07032BBD1B8), + SPH_C64(0x19A4C116B8D2D0C8), SPH_C64(0x1E376C085141AB53), + SPH_C64(0x2748774CDF8EEB99), SPH_C64(0x34B0BCB5E19B48A8), + SPH_C64(0x391C0CB3C5C95A63), SPH_C64(0x4ED8AA4AE3418ACB), + SPH_C64(0x5B9CCA4F7763E373), SPH_C64(0x682E6FF3D6B2B8A3), + SPH_C64(0x748F82EE5DEFB2FC), SPH_C64(0x78A5636F43172F60), + SPH_C64(0x84C87814A1F0AB72), SPH_C64(0x8CC702081A6439EC), + SPH_C64(0x90BEFFFA23631E28), SPH_C64(0xA4506CEBDE82BDE9), + SPH_C64(0xBEF9A3F7B2C67915), SPH_C64(0xC67178F2E372532B), + SPH_C64(0xCA273ECEEA26619C), SPH_C64(0xD186B8C721C0C207), + SPH_C64(0xEADA7DD6CDE0EB1E), SPH_C64(0xF57D4F7FEE6ED178), + SPH_C64(0x06F067AA72176FBA), SPH_C64(0x0A637DC5A2C898A6), + SPH_C64(0x113F9804BEF90DAE), SPH_C64(0x1B710B35131C471B), + SPH_C64(0x28DB77F523047D84), SPH_C64(0x32CAAB7B40C72493), + SPH_C64(0x3C9EBE0A15C9BEBC), SPH_C64(0x431D67C49C100D4C), + SPH_C64(0x4CC5D4BECB3E42B6), SPH_C64(0x597F299CFC657E2A), + SPH_C64(0x5FCB6FAB3AD6FAEC), SPH_C64(0x6C44198C4A475817) +}; + +static const sph_u64 H384[8] = { + SPH_C64(0xCBBB9D5DC1059ED8), SPH_C64(0x629A292A367CD507), + SPH_C64(0x9159015A3070DD17), SPH_C64(0x152FECD8F70E5939), + SPH_C64(0x67332667FFC00B31), SPH_C64(0x8EB44A8768581511), + SPH_C64(0xDB0C2E0D64F98FA7), SPH_C64(0x47B5481DBEFA4FA4) +}; + +static const sph_u64 H512[8] = { + SPH_C64(0x6A09E667F3BCC908), SPH_C64(0xBB67AE8584CAA73B), + SPH_C64(0x3C6EF372FE94F82B), SPH_C64(0xA54FF53A5F1D36F1), + SPH_C64(0x510E527FADE682D1), SPH_C64(0x9B05688C2B3E6C1F), + SPH_C64(0x1F83D9ABFB41BD6B), SPH_C64(0x5BE0CD19137E2179) +}; + +/* + * This macro defines the body for a SHA-384 / SHA-512 compression function + * implementation. The "in" parameter should evaluate, when applied to a + * numerical input parameter from 0 to 15, to an expression which yields + * the corresponding input block. The "r" parameter should evaluate to + * an array or pointer expression designating the array of 8 words which + * contains the input and output of the compression function. + * + * SHA-512 is hard for the compiler. If the loop is completely unrolled, + * then the code will be quite huge (possibly more than 100 kB), and the + * performance will be degraded due to cache misses on the code. We + * unroll only eight steps, which avoids all needless copies when + * 64-bit registers are swapped. + */ + +#define SHA3_STEP(A, B, C, D, E, F, G, H, i) do { \ + sph_u64 T1, T2; \ + T1 = SPH_T64(H + BSG5_1(E) + CH(E, F, G) + K512[i] + W[i]); \ + T2 = SPH_T64(BSG5_0(A) + MAJ(A, B, C)); \ + D = SPH_T64(D + T1); \ + H = SPH_T64(T1 + T2); \ + } while (0) + +#define SHA3_ROUND_BODY(in, r) do { \ + int i; \ + sph_u64 A, B, C, D, E, F, G, H; \ + sph_u64 W[80]; \ + \ + for (i = 0; i < 16; i ++) \ + W[i] = in(i); \ + for (i = 16; i < 80; i ++) \ + W[i] = SPH_T64(SSG5_1(W[i - 2]) + W[i - 7] \ + + SSG5_0(W[i - 15]) + W[i - 16]); \ + A = (r)[0]; \ + B = (r)[1]; \ + C = (r)[2]; \ + D = (r)[3]; \ + E = (r)[4]; \ + F = (r)[5]; \ + G = (r)[6]; \ + H = (r)[7]; \ + for (i = 0; i < 80; i += 8) { \ + SHA3_STEP(A, B, C, D, E, F, G, H, i + 0); \ + SHA3_STEP(H, A, B, C, D, E, F, G, i + 1); \ + SHA3_STEP(G, H, A, B, C, D, E, F, i + 2); \ + SHA3_STEP(F, G, H, A, B, C, D, E, i + 3); \ + SHA3_STEP(E, F, G, H, A, B, C, D, i + 4); \ + SHA3_STEP(D, E, F, G, H, A, B, C, i + 5); \ + SHA3_STEP(C, D, E, F, G, H, A, B, i + 6); \ + SHA3_STEP(B, C, D, E, F, G, H, A, i + 7); \ + } \ + (r)[0] = SPH_T64((r)[0] + A); \ + (r)[1] = SPH_T64((r)[1] + B); \ + (r)[2] = SPH_T64((r)[2] + C); \ + (r)[3] = SPH_T64((r)[3] + D); \ + (r)[4] = SPH_T64((r)[4] + E); \ + (r)[5] = SPH_T64((r)[5] + F); \ + (r)[6] = SPH_T64((r)[6] + G); \ + (r)[7] = SPH_T64((r)[7] + H); \ + } while (0) + +/* + * One round of SHA-384 / SHA-512. The data must be aligned for 64-bit access. + */ +static void +sha3_round(const unsigned char *data, sph_u64 r[8]) +{ +#define SHA3_IN(x) sph_dec64be_aligned(data + (8 * (x))) + SHA3_ROUND_BODY(SHA3_IN, r); +#undef SHA3_IN +} + +/* see sph_sha3.h */ +void +sph_sha384_init(void *cc) +{ + sph_sha384_context *sc; + + sc = cc; + memcpy(sc->val, H384, sizeof H384); + sc->count = 0; +} + +/* see sph_sha3.h */ +void +sph_sha512_init(void *cc) +{ + sph_sha512_context *sc; + + sc = cc; + memcpy(sc->val, H512, sizeof H512); + sc->count = 0; +} + +#define RFUN sha3_round +#define HASH sha384 +#define BE64 1 +#include "md_helper.c" + +/* see sph_sha3.h */ +void +sph_sha384_close(void *cc, void *dst) +{ + sha384_close(cc, dst, 6); + sph_sha384_init(cc); +} + +/* see sph_sha3.h */ +void +sph_sha384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + sha384_addbits_and_close(cc, ub, n, dst, 6); + sph_sha384_init(cc); +} + +/* see sph_sha3.h */ +void +sph_sha512_close(void *cc, void *dst) +{ + sha384_close(cc, dst, 8); + sph_sha512_init(cc); +} + +/* see sph_sha3.h */ +void +sph_sha512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + sha384_addbits_and_close(cc, ub, n, dst, 8); + sph_sha512_init(cc); +} + +/* see sph_sha3.h */ +void +sph_sha384_comp(const sph_u64 msg[16], sph_u64 val[8]) +{ +#define SHA3_IN(x) msg[x] + SHA3_ROUND_BODY(SHA3_IN, val); +#undef SHA3_IN +} + +#endif diff --git a/libaxolotl/jni/ed25519/sha512/sph_sha2.h b/libaxolotl/jni/ed25519/sha512/sph_sha2.h new file mode 100644 index 000000000..d5bda731a --- /dev/null +++ b/libaxolotl/jni/ed25519/sha512/sph_sha2.h @@ -0,0 +1,370 @@ +/* $Id: sph_sha2.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * SHA-224, SHA-256, SHA-384 and SHA-512 interface. + * + * SHA-256 has been published in FIPS 180-2, now amended with a change + * notice to include SHA-224 as well (which is a simple variation on + * SHA-256). SHA-384 and SHA-512 are also defined in FIPS 180-2. FIPS + * standards can be found at: + * http://csrc.nist.gov/publications/fips/ + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_sha2.h + * @author Thomas Pornin + */ + +#ifndef SPH_SHA2_H__ +#define SPH_SHA2_H__ + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for SHA-224. + */ +#define SPH_SIZE_sha224 224 + +/** + * Output size (in bits) for SHA-256. + */ +#define SPH_SIZE_sha256 256 + +/** + * This structure is a context for SHA-224 computations: it contains the + * intermediate values and some data from the last entered block. Once + * a SHA-224 computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running SHA-224 computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + sph_u32 val[8]; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_sha224_context; + +/** + * This structure is a context for SHA-256 computations. It is identical + * to the SHA-224 context. However, a context is initialized for SHA-224 + * or SHA-256, but not both (the internal IV is not the + * same). + */ +typedef sph_sha224_context sph_sha256_context; + +/** + * Initialize a SHA-224 context. This process performs no memory allocation. + * + * @param cc the SHA-224 context (pointer to + * a sph_sha224_context) + */ +void sph_sha224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the SHA-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_sha224(void *cc, const void *data, size_t len); + +/** + * Terminate the current SHA-224 computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the SHA-224 context + * @param dst the destination buffer + */ +void sph_sha224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the SHA-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_sha224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Apply the SHA-224 compression function on the provided data. The + * msg parameter contains the 16 32-bit input blocks, + * as numerical values (hence after the big-endian decoding). The + * val parameter contains the 8 32-bit input blocks for + * the compression function; the output is written in place in this + * array. + * + * @param msg the message block (16 values) + * @param val the function 256-bit input and output + */ +void sph_sha224_comp(const sph_u32 msg[16], sph_u32 val[8]); + +/** + * Initialize a SHA-256 context. This process performs no memory allocation. + * + * @param cc the SHA-256 context (pointer to + * a sph_sha256_context) + */ +void sph_sha256_init(void *cc); + +#ifdef DOXYGEN_IGNORE +/** + * Process some data bytes, for SHA-256. This function is identical to + * sha_224() + * + * @param cc the SHA-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_sha256(void *cc, const void *data, size_t len); +#endif + +#ifndef DOXYGEN_IGNORE +#define sph_sha256 sph_sha224 +#endif + +/** + * Terminate the current SHA-256 computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the SHA-256 context + * @param dst the destination buffer + */ +void sph_sha256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the SHA-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_sha256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef DOXYGEN_IGNORE +/** + * Apply the SHA-256 compression function on the provided data. This + * function is identical to sha224_comp(). + * + * @param msg the message block (16 values) + * @param val the function 256-bit input and output + */ +void sph_sha256_comp(const sph_u32 msg[16], sph_u32 val[8]); +#endif + +#ifndef DOXYGEN_IGNORE +#define sph_sha256_comp sph_sha224_comp +#endif + +#if SPH_64 + +/** + * Output size (in bits) for SHA-384. + */ +#define SPH_SIZE_sha384 384 + +/** + * Output size (in bits) for SHA-512. + */ +#define SPH_SIZE_sha512 512 + +/** + * This structure is a context for SHA-384 computations: it contains the + * intermediate values and some data from the last entered block. Once + * a SHA-384 computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running SHA-384 computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[128]; /* first field, for alignment */ + sph_u64 val[8]; + sph_u64 count; +#endif +} sph_sha384_context; + +/** + * Initialize a SHA-384 context. This process performs no memory allocation. + * + * @param cc the SHA-384 context (pointer to + * a sph_sha384_context) + */ +void sph_sha384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the SHA-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_sha384(void *cc, const void *data, size_t len); + +/** + * Terminate the current SHA-384 computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the SHA-384 context + * @param dst the destination buffer + */ +void sph_sha384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the SHA-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_sha384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Apply the SHA-384 compression function on the provided data. The + * msg parameter contains the 16 64-bit input blocks, + * as numerical values (hence after the big-endian decoding). The + * val parameter contains the 8 64-bit input blocks for + * the compression function; the output is written in place in this + * array. + * + * @param msg the message block (16 values) + * @param val the function 512-bit input and output + */ +void sph_sha384_comp(const sph_u64 msg[16], sph_u64 val[8]); + +/** + * This structure is a context for SHA-512 computations. It is identical + * to the SHA-384 context. However, a context is initialized for SHA-384 + * or SHA-512, but not both (the internal IV is not the + * same). + */ +typedef sph_sha384_context sph_sha512_context; + +/** + * Initialize a SHA-512 context. This process performs no memory allocation. + * + * @param cc the SHA-512 context (pointer to + * a sph_sha512_context) + */ +void sph_sha512_init(void *cc); + +#ifdef DOXYGEN_IGNORE +/** + * Process some data bytes, for SHA-512. This function is identical to + * sph_sha384(). + * + * @param cc the SHA-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_sha512(void *cc, const void *data, size_t len); +#endif + +#ifndef DOXYGEN_IGNORE +#define sph_sha512 sph_sha384 +#endif + +/** + * Terminate the current SHA-512 computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the SHA-512 context + * @param dst the destination buffer + */ +void sph_sha512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the SHA-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_sha512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef DOXYGEN_IGNORE +/** + * Apply the SHA-512 compression function. This function is identical to + * sph_sha384_comp(). + * + * @param msg the message block (16 values) + * @param val the function 512-bit input and output + */ +void sph_sha512_comp(const sph_u64 msg[16], sph_u64 val[8]); +#endif + +#ifndef DOXYGEN_IGNORE +#define sph_sha512_comp sph_sha384_comp +#endif + +#endif + +#endif diff --git a/libaxolotl/jni/ed25519/sha512/sph_types.h b/libaxolotl/jni/ed25519/sha512/sph_types.h new file mode 100644 index 000000000..7295b0b37 --- /dev/null +++ b/libaxolotl/jni/ed25519/sha512/sph_types.h @@ -0,0 +1,1976 @@ +/* $Id: sph_types.h 260 2011-07-21 01:02:38Z tp $ */ +/** + * Basic type definitions. + * + * This header file defines the generic integer types that will be used + * for the implementation of hash functions; it also contains helper + * functions which encode and decode multi-byte integer values, using + * either little-endian or big-endian conventions. + * + * This file contains a compile-time test on the size of a byte + * (the unsigned char C type). If bytes are not octets, + * i.e. if they do not have a size of exactly 8 bits, then compilation + * is aborted. Architectures where bytes are not octets are relatively + * rare, even in the embedded devices market. We forbid non-octet bytes + * because there is no clear convention on how octet streams are encoded + * on such systems. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_types.h + * @author Thomas Pornin + */ + +#ifndef SPH_TYPES_H__ +#define SPH_TYPES_H__ + +#include + +/* + * All our I/O functions are defined over octet streams. We do not know + * how to handle input data if bytes are not octets. + */ +#if CHAR_BIT != 8 +#error This code requires 8-bit bytes +#endif + +/* ============= BEGIN documentation block for Doxygen ============ */ + +#ifdef DOXYGEN_IGNORE + +/** @mainpage sphlib C code documentation + * + * @section overview Overview + * + * sphlib is a library which contains implementations of + * various cryptographic hash functions. These pages have been generated + * with doxygen and + * document the API for the C implementations. + * + * The API is described in appropriate header files, which are available + * in the "Files" section. Each hash function family has its own header, + * whose name begins with "sph_" and contains the family + * name. For instance, the API for the RIPEMD hash functions is available + * in the header file sph_ripemd.h. + * + * @section principles API structure and conventions + * + * @subsection io Input/output conventions + * + * In all generality, hash functions operate over strings of bits. + * Individual bits are rarely encountered in C programming or actual + * communication protocols; most protocols converge on the ubiquitous + * "octet" which is a group of eight bits. Data is thus expressed as a + * stream of octets. The C programming language contains the notion of a + * "byte", which is a data unit managed under the type "unsigned + * char". The C standard prescribes that a byte should hold at + * least eight bits, but possibly more. Most modern architectures, even + * in the embedded world, feature eight-bit bytes, i.e. map bytes to + * octets. + * + * Nevertheless, for some of the implemented hash functions, an extra + * API has been added, which allows the input of arbitrary sequences of + * bits: when the computation is about to be closed, 1 to 7 extra bits + * can be added. The functions for which this API is implemented include + * the SHA-2 functions and all SHA-3 candidates. + * + * sphlib defines hash function which may hash octet streams, + * i.e. streams of bits where the number of bits is a multiple of eight. + * The data input functions in the sphlib API expect data + * as anonymous pointers ("const void *") with a length + * (of type "size_t") which gives the input data chunk length + * in bytes. A byte is assumed to be an octet; the sph_types.h + * header contains a compile-time test which prevents compilation on + * architectures where this property is not met. + * + * The hash function output is also converted into bytes. All currently + * implemented hash functions have an output width which is a multiple of + * eight, and this is likely to remain true for new designs. + * + * Most hash functions internally convert input data into 32-bit of 64-bit + * words, using either little-endian or big-endian conversion. The hash + * output also often consists of such words, which are encoded into output + * bytes with a similar endianness convention. Some hash functions have + * been only loosely specified on that subject; when necessary, + * sphlib has been tested against published "reference" + * implementations in order to use the same conventions. + * + * @subsection shortname Function short name + * + * Each implemented hash function has a "short name" which is used + * internally to derive the identifiers for the functions and context + * structures which the function uses. For instance, MD5 has the short + * name "md5". Short names are listed in the next section, + * for the implemented hash functions. In subsequent sections, the + * short name will be assumed to be "XXX": replace with the + * actual hash function name to get the C identifier. + * + * Note: some functions within the same family share the same core + * elements, such as update function or context structure. Correspondingly, + * some of the defined types or functions may actually be macros which + * transparently evaluate to another type or function name. + * + * @subsection context Context structure + * + * Each implemented hash fonction has its own context structure, available + * under the type name "sph_XXX_context" for the hash function + * with short name "XXX". This structure holds all needed + * state for a running hash computation. + * + * The contents of these structures are meant to be opaque, and private + * to the implementation. However, these contents are specified in the + * header files so that application code which uses sphlib + * may access the size of those structures. + * + * The caller is responsible for allocating the context structure, + * whether by dynamic allocation (malloc() or equivalent), + * static allocation (a global permanent variable), as an automatic + * variable ("on the stack"), or by any other mean which ensures proper + * structure alignment. sphlib code performs no dynamic + * allocation by itself. + * + * The context must be initialized before use, using the + * sph_XXX_init() function. This function sets the context + * state to proper initial values for hashing. + * + * Since all state data is contained within the context structure, + * sphlib is thread-safe and reentrant: several hash + * computations may be performed in parallel, provided that they do not + * operate on the same context. Moreover, a running computation can be + * cloned by copying the context (with a simple memcpy()): + * the context and its clone are then independant and may be updated + * with new data and/or closed without interfering with each other. + * Similarly, a context structure can be moved in memory at will: + * context structures contain no pointer, in particular no pointer to + * themselves. + * + * @subsection dataio Data input + * + * Hashed data is input with the sph_XXX() fonction, which + * takes as parameters a pointer to the context, a pointer to the data + * to hash, and the number of data bytes to hash. The context is updated + * with the new data. + * + * Data can be input in one or several calls, with arbitrary input lengths. + * However, it is best, performance wise, to input data by relatively big + * chunks (say a few kilobytes), because this allows sphlib to + * optimize things and avoid internal copying. + * + * When all data has been input, the context can be closed with + * sph_XXX_close(). The hash output is computed and written + * into the provided buffer. The caller must take care to provide a + * buffer of appropriate length; e.g., when using SHA-1, the output is + * a 20-byte word, therefore the output buffer must be at least 20-byte + * long. + * + * For some hash functions, the sph_XXX_addbits_and_close() + * function can be used instead of sph_XXX_close(). This + * function can take a few extra bits to be added at + * the end of the input message. This allows hashing messages with a + * bit length which is not a multiple of 8. The extra bits are provided + * as an unsigned integer value, and a bit count. The bit count must be + * between 0 and 7, inclusive. The extra bits are provided as bits 7 to + * 0 (bits of numerical value 128, 64, 32... downto 0), in that order. + * For instance, to add three bits of value 1, 1 and 0, the unsigned + * integer will have value 192 (1*128 + 1*64 + 0*32) and the bit count + * will be 3. + * + * The SPH_SIZE_XXX macro is defined for each hash function; + * it evaluates to the function output size, expressed in bits. For instance, + * SPH_SIZE_sha1 evaluates to 160. + * + * When closed, the context is automatically reinitialized and can be + * immediately used for another computation. It is not necessary to call + * sph_XXX_init() after a close. Note that + * sph_XXX_init() can still be called to "reset" a context, + * i.e. forget previously input data, and get back to the initial state. + * + * @subsection alignment Data alignment + * + * "Alignment" is a property of data, which is said to be "properly + * aligned" when its emplacement in memory is such that the data can + * be optimally read by full words. This depends on the type of access; + * basically, some hash functions will read data by 32-bit or 64-bit + * words. sphlib does not mandate such alignment for input + * data, but using aligned data can substantially improve performance. + * + * As a rule, it is best to input data by chunks whose length (in bytes) + * is a multiple of eight, and which begins at "generally aligned" + * addresses, such as the base address returned by a call to + * malloc(). + * + * @section functions Implemented functions + * + * We give here the list of implemented functions. They are grouped by + * family; to each family corresponds a specific header file. Each + * individual function has its associated "short name". Please refer to + * the documentation for that header file to get details on the hash + * function denomination and provenance. + * + * Note: the functions marked with a '(64)' in the list below are + * available only if the C compiler provides an integer type of length + * 64 bits or more. Such a type is mandatory in the latest C standard + * (ISO 9899:1999, aka "C99") and is present in several older compilers + * as well, so chances are that such a type is available. + * + * - HAVAL family: file sph_haval.h + * - HAVAL-128/3 (128-bit, 3 passes): short name: haval128_3 + * - HAVAL-128/4 (128-bit, 4 passes): short name: haval128_4 + * - HAVAL-128/5 (128-bit, 5 passes): short name: haval128_5 + * - HAVAL-160/3 (160-bit, 3 passes): short name: haval160_3 + * - HAVAL-160/4 (160-bit, 4 passes): short name: haval160_4 + * - HAVAL-160/5 (160-bit, 5 passes): short name: haval160_5 + * - HAVAL-192/3 (192-bit, 3 passes): short name: haval192_3 + * - HAVAL-192/4 (192-bit, 4 passes): short name: haval192_4 + * - HAVAL-192/5 (192-bit, 5 passes): short name: haval192_5 + * - HAVAL-224/3 (224-bit, 3 passes): short name: haval224_3 + * - HAVAL-224/4 (224-bit, 4 passes): short name: haval224_4 + * - HAVAL-224/5 (224-bit, 5 passes): short name: haval224_5 + * - HAVAL-256/3 (256-bit, 3 passes): short name: haval256_3 + * - HAVAL-256/4 (256-bit, 4 passes): short name: haval256_4 + * - HAVAL-256/5 (256-bit, 5 passes): short name: haval256_5 + * - MD2: file sph_md2.h, short name: md2 + * - MD4: file sph_md4.h, short name: md4 + * - MD5: file sph_md5.h, short name: md5 + * - PANAMA: file sph_panama.h, short name: panama + * - RadioGatun family: file sph_radiogatun.h + * - RadioGatun[32]: short name: radiogatun32 + * - RadioGatun[64]: short name: radiogatun64 (64) + * - RIPEMD family: file sph_ripemd.h + * - RIPEMD: short name: ripemd + * - RIPEMD-128: short name: ripemd128 + * - RIPEMD-160: short name: ripemd160 + * - SHA-0: file sph_sha0.h, short name: sha0 + * - SHA-1: file sph_sha1.h, short name: sha1 + * - SHA-2 family, 32-bit hashes: file sph_sha2.h + * - SHA-224: short name: sha224 + * - SHA-256: short name: sha256 + * - SHA-384: short name: sha384 (64) + * - SHA-512: short name: sha512 (64) + * - Tiger family: file sph_tiger.h + * - Tiger: short name: tiger (64) + * - Tiger2: short name: tiger2 (64) + * - WHIRLPOOL family: file sph_whirlpool.h + * - WHIRLPOOL-0: short name: whirlpool0 (64) + * - WHIRLPOOL-1: short name: whirlpool1 (64) + * - WHIRLPOOL: short name: whirlpool (64) + * + * The fourteen second-round SHA-3 candidates are also implemented; + * when applicable, the implementations follow the "final" specifications + * as published for the third round of the SHA-3 competition (BLAKE, + * Groestl, JH, Keccak and Skein have been tweaked for third round). + * + * - BLAKE family: file sph_blake.h + * - BLAKE-224: short name: blake224 + * - BLAKE-256: short name: blake256 + * - BLAKE-384: short name: blake384 + * - BLAKE-512: short name: blake512 + * - BMW (Blue Midnight Wish) family: file sph_bmw.h + * - BMW-224: short name: bmw224 + * - BMW-256: short name: bmw256 + * - BMW-384: short name: bmw384 (64) + * - BMW-512: short name: bmw512 (64) + * - CubeHash family: file sph_cubehash.h (specified as + * CubeHash16/32 in the CubeHash specification) + * - CubeHash-224: short name: cubehash224 + * - CubeHash-256: short name: cubehash256 + * - CubeHash-384: short name: cubehash384 + * - CubeHash-512: short name: cubehash512 + * - ECHO family: file sph_echo.h + * - ECHO-224: short name: echo224 + * - ECHO-256: short name: echo256 + * - ECHO-384: short name: echo384 + * - ECHO-512: short name: echo512 + * - Fugue family: file sph_fugue.h + * - Fugue-224: short name: fugue224 + * - Fugue-256: short name: fugue256 + * - Fugue-384: short name: fugue384 + * - Fugue-512: short name: fugue512 + * - Groestl family: file sph_groestl.h + * - Groestl-224: short name: groestl224 + * - Groestl-256: short name: groestl256 + * - Groestl-384: short name: groestl384 + * - Groestl-512: short name: groestl512 + * - Hamsi family: file sph_hamsi.h + * - Hamsi-224: short name: hamsi224 + * - Hamsi-256: short name: hamsi256 + * - Hamsi-384: short name: hamsi384 + * - Hamsi-512: short name: hamsi512 + * - JH family: file sph_jh.h + * - JH-224: short name: jh224 + * - JH-256: short name: jh256 + * - JH-384: short name: jh384 + * - JH-512: short name: jh512 + * - Keccak family: file sph_keccak.h + * - Keccak-224: short name: keccak224 + * - Keccak-256: short name: keccak256 + * - Keccak-384: short name: keccak384 + * - Keccak-512: short name: keccak512 + * - Luffa family: file sph_luffa.h + * - Luffa-224: short name: luffa224 + * - Luffa-256: short name: luffa256 + * - Luffa-384: short name: luffa384 + * - Luffa-512: short name: luffa512 + * - Shabal family: file sph_shabal.h + * - Shabal-192: short name: shabal192 + * - Shabal-224: short name: shabal224 + * - Shabal-256: short name: shabal256 + * - Shabal-384: short name: shabal384 + * - Shabal-512: short name: shabal512 + * - SHAvite-3 family: file sph_shavite.h + * - SHAvite-224 (nominally "SHAvite-3 with 224-bit output"): + * short name: shabal224 + * - SHAvite-256 (nominally "SHAvite-3 with 256-bit output"): + * short name: shabal256 + * - SHAvite-384 (nominally "SHAvite-3 with 384-bit output"): + * short name: shabal384 + * - SHAvite-512 (nominally "SHAvite-3 with 512-bit output"): + * short name: shabal512 + * - SIMD family: file sph_simd.h + * - SIMD-224: short name: simd224 + * - SIMD-256: short name: simd256 + * - SIMD-384: short name: simd384 + * - SIMD-512: short name: simd512 + * - Skein family: file sph_skein.h + * - Skein-224 (nominally specified as Skein-512-224): short name: + * skein224 (64) + * - Skein-256 (nominally specified as Skein-512-256): short name: + * skein256 (64) + * - Skein-384 (nominally specified as Skein-512-384): short name: + * skein384 (64) + * - Skein-512 (nominally specified as Skein-512-512): short name: + * skein512 (64) + * + * For the second-round SHA-3 candidates, the functions are as specified + * for round 2, i.e. with the "tweaks" that some candidates added + * between round 1 and round 2. Also, some of the submitted packages for + * round 2 contained errors, in the specification, reference code, or + * both. sphlib implements the corrected versions. + */ + +/** @hideinitializer + * Unsigned integer type whose length is at least 32 bits; on most + * architectures, it will have a width of exactly 32 bits. Unsigned C + * types implement arithmetics modulo a power of 2; use the + * SPH_T32() macro to ensure that the value is truncated + * to exactly 32 bits. Unless otherwise specified, all macros and + * functions which accept sph_u32 values assume that these + * values fit on 32 bits, i.e. do not exceed 2^32-1, even on architectures + * where sph_u32 is larger than that. + */ +typedef __arch_dependant__ sph_u32; + +/** @hideinitializer + * Signed integer type corresponding to sph_u32; it has + * width 32 bits or more. + */ +typedef __arch_dependant__ sph_s32; + +/** @hideinitializer + * Unsigned integer type whose length is at least 64 bits; on most + * architectures which feature such a type, it will have a width of + * exactly 64 bits. C99-compliant platform will have this type; it + * is also defined when the GNU compiler (gcc) is used, and on + * platforms where unsigned long is large enough. If this + * type is not available, then some hash functions which depends on + * a 64-bit type will not be available (most notably SHA-384, SHA-512, + * Tiger and WHIRLPOOL). + */ +typedef __arch_dependant__ sph_u64; + +/** @hideinitializer + * Signed integer type corresponding to sph_u64; it has + * width 64 bits or more. + */ +typedef __arch_dependant__ sph_s64; + +/** + * This macro expands the token x into a suitable + * constant expression of type sph_u32. Depending on + * how this type is defined, a suffix such as UL may + * be appended to the argument. + * + * @param x the token to expand into a suitable constant expression + */ +#define SPH_C32(x) + +/** + * Truncate a 32-bit value to exactly 32 bits. On most systems, this is + * a no-op, recognized as such by the compiler. + * + * @param x the value to truncate (of type sph_u32) + */ +#define SPH_T32(x) + +/** + * Rotate a 32-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 31. This macro assumes that its + * first argument fits in 32 bits (no extra bit allowed on machines where + * sph_u32 is wider); both arguments may be evaluated + * several times. + * + * @param x the value to rotate (of type sph_u32) + * @param n the rotation count (between 1 and 31, inclusive) + */ +#define SPH_ROTL32(x, n) + +/** + * Rotate a 32-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 31. This macro assumes that its + * first argument fits in 32 bits (no extra bit allowed on machines where + * sph_u32 is wider); both arguments may be evaluated + * several times. + * + * @param x the value to rotate (of type sph_u32) + * @param n the rotation count (between 1 and 31, inclusive) + */ +#define SPH_ROTR32(x, n) + +/** + * This macro is defined on systems for which a 64-bit type has been + * detected, and is used for sph_u64. + */ +#define SPH_64 + +/** + * This macro is defined on systems for the "native" integer size is + * 64 bits (64-bit values fit in one register). + */ +#define SPH_64_TRUE + +/** + * This macro expands the token x into a suitable + * constant expression of type sph_u64. Depending on + * how this type is defined, a suffix such as ULL may + * be appended to the argument. This macro is defined only if a + * 64-bit type was detected and used for sph_u64. + * + * @param x the token to expand into a suitable constant expression + */ +#define SPH_C64(x) + +/** + * Truncate a 64-bit value to exactly 64 bits. On most systems, this is + * a no-op, recognized as such by the compiler. This macro is defined only + * if a 64-bit type was detected and used for sph_u64. + * + * @param x the value to truncate (of type sph_u64) + */ +#define SPH_T64(x) + +/** + * Rotate a 64-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 63. This macro assumes that its + * first argument fits in 64 bits (no extra bit allowed on machines where + * sph_u64 is wider); both arguments may be evaluated + * several times. This macro is defined only if a 64-bit type was detected + * and used for sph_u64. + * + * @param x the value to rotate (of type sph_u64) + * @param n the rotation count (between 1 and 63, inclusive) + */ +#define SPH_ROTL64(x, n) + +/** + * Rotate a 64-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 63. This macro assumes that its + * first argument fits in 64 bits (no extra bit allowed on machines where + * sph_u64 is wider); both arguments may be evaluated + * several times. This macro is defined only if a 64-bit type was detected + * and used for sph_u64. + * + * @param x the value to rotate (of type sph_u64) + * @param n the rotation count (between 1 and 63, inclusive) + */ +#define SPH_ROTR64(x, n) + +/** + * This macro evaluates to inline or an equivalent construction, + * if available on the compilation platform, or to nothing otherwise. This + * is used to declare inline functions, for which the compiler should + * endeavour to include the code directly in the caller. Inline functions + * are typically defined in header files as replacement for macros. + */ +#define SPH_INLINE + +/** + * This macro is defined if the platform has been detected as using + * little-endian convention. This implies that the sph_u32 + * type (and the sph_u64 type also, if it is defined) has + * an exact width (i.e. exactly 32-bit, respectively 64-bit). + */ +#define SPH_LITTLE_ENDIAN + +/** + * This macro is defined if the platform has been detected as using + * big-endian convention. This implies that the sph_u32 + * type (and the sph_u64 type also, if it is defined) has + * an exact width (i.e. exactly 32-bit, respectively 64-bit). + */ +#define SPH_BIG_ENDIAN + +/** + * This macro is defined if 32-bit words (and 64-bit words, if defined) + * can be read from and written to memory efficiently in little-endian + * convention. This is the case for little-endian platforms, and also + * for the big-endian platforms which have special little-endian access + * opcodes (e.g. Ultrasparc). + */ +#define SPH_LITTLE_FAST + +/** + * This macro is defined if 32-bit words (and 64-bit words, if defined) + * can be read from and written to memory efficiently in big-endian + * convention. This is the case for little-endian platforms, and also + * for the little-endian platforms which have special big-endian access + * opcodes. + */ +#define SPH_BIG_FAST + +/** + * On some platforms, this macro is defined to an unsigned integer type + * into which pointer values may be cast. The resulting value can then + * be tested for being a multiple of 2, 4 or 8, indicating an aligned + * pointer for, respectively, 16-bit, 32-bit or 64-bit memory accesses. + */ +#define SPH_UPTR + +/** + * When defined, this macro indicates that unaligned memory accesses + * are possible with only a minor penalty, and thus should be prefered + * over strategies which first copy data to an aligned buffer. + */ +#define SPH_UNALIGNED + +/** + * Byte-swap a 32-bit word (i.e. 0x12345678 becomes + * 0x78563412). This is an inline function which resorts + * to inline assembly on some platforms, for better performance. + * + * @param x the 32-bit value to byte-swap + * @return the byte-swapped value + */ +static inline sph_u32 sph_bswap32(sph_u32 x); + +/** + * Byte-swap a 64-bit word. This is an inline function which resorts + * to inline assembly on some platforms, for better performance. This + * function is defined only if a suitable 64-bit type was found for + * sph_u64 + * + * @param x the 64-bit value to byte-swap + * @return the byte-swapped value + */ +static inline sph_u64 sph_bswap64(sph_u64 x); + +/** + * Decode a 16-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline unsigned sph_dec16le(const void *src); + +/** + * Encode a 16-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc16le(void *dst, unsigned val); + +/** + * Decode a 16-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline unsigned sph_dec16be(const void *src); + +/** + * Encode a 16-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc16be(void *dst, unsigned val); + +/** + * Decode a 32-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32le(const void *src); + +/** + * Decode a 32-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec32le() function. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32le_aligned(const void *src); + +/** + * Encode a 32-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32le(void *dst, sph_u32 val); + +/** + * Encode a 32-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc32le() function. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32le_aligned(void *dst, sph_u32 val); + +/** + * Decode a 32-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32be(const void *src); + +/** + * Decode a 32-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec32be() function. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32be_aligned(const void *src); + +/** + * Encode a 32-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32be(void *dst, sph_u32 val); + +/** + * Encode a 32-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc32be() function. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32be_aligned(void *dst, sph_u32 val); + +/** + * Decode a 64-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64le(const void *src); + +/** + * Decode a 64-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec64le() function. This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64le_aligned(const void *src); + +/** + * Encode a 64-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64le(void *dst, sph_u64 val); + +/** + * Encode a 64-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc64le() function. This function is defined + * only if a suitable 64-bit type was detected and used for + * sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64le_aligned(void *dst, sph_u64 val); + +/** + * Decode a 64-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64be(const void *src); + +/** + * Decode a 64-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec64be() function. This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64be_aligned(const void *src); + +/** + * Encode a 64-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64be(void *dst, sph_u64 val); + +/** + * Encode a 64-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc64be() function. This function is defined + * only if a suitable 64-bit type was detected and used for + * sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64be_aligned(void *dst, sph_u64 val); + +#endif + +/* ============== END documentation block for Doxygen ============= */ + +#ifndef DOXYGEN_IGNORE + +/* + * We want to define the types "sph_u32" and "sph_u64" which hold + * unsigned values of at least, respectively, 32 and 64 bits. These + * tests should select appropriate types for most platforms. The + * macro "SPH_64" is defined if the 64-bit is supported. + */ + +#undef SPH_64 +#undef SPH_64_TRUE + +#if defined __STDC__ && __STDC_VERSION__ >= 199901L + +/* + * On C99 implementations, we can use to get an exact 64-bit + * type, if any, or otherwise use a wider type (which must exist, for + * C99 conformance). + */ + +#include + +#ifdef UINT32_MAX +typedef uint32_t sph_u32; +typedef int32_t sph_s32; +#else +typedef uint_fast32_t sph_u32; +typedef int_fast32_t sph_s32; +#endif +#if !SPH_NO_64 +#ifdef UINT64_MAX +typedef uint64_t sph_u64; +typedef int64_t sph_s64; +#else +typedef uint_fast64_t sph_u64; +typedef int_fast64_t sph_s64; +#endif +#endif + +#define SPH_C32(x) ((sph_u32)(x)) +#if !SPH_NO_64 +#define SPH_C64(x) ((sph_u64)(x)) +#define SPH_64 1 +#endif + +#else + +/* + * On non-C99 systems, we use "unsigned int" if it is wide enough, + * "unsigned long" otherwise. This supports all "reasonable" architectures. + * We have to be cautious: pre-C99 preprocessors handle constants + * differently in '#if' expressions. Hence the shifts to test UINT_MAX. + */ + +#if ((UINT_MAX >> 11) >> 11) >= 0x3FF + +typedef unsigned int sph_u32; +typedef int sph_s32; + +#define SPH_C32(x) ((sph_u32)(x ## U)) + +#else + +typedef unsigned long sph_u32; +typedef long sph_s32; + +#define SPH_C32(x) ((sph_u32)(x ## UL)) + +#endif + +#if !SPH_NO_64 + +/* + * We want a 64-bit type. We use "unsigned long" if it is wide enough (as + * is common on 64-bit architectures such as AMD64, Alpha or Sparcv9), + * "unsigned long long" otherwise, if available. We use ULLONG_MAX to + * test whether "unsigned long long" is available; we also know that + * gcc features this type, even if the libc header do not know it. + */ + +#if ((ULONG_MAX >> 31) >> 31) >= 3 + +typedef unsigned long sph_u64; +typedef long sph_s64; + +#define SPH_C64(x) ((sph_u64)(x ## UL)) + +#define SPH_64 1 + +#elif ((ULLONG_MAX >> 31) >> 31) >= 3 || defined __GNUC__ + +typedef unsigned long long sph_u64; +typedef long long sph_s64; + +#define SPH_C64(x) ((sph_u64)(x ## ULL)) + +#define SPH_64 1 + +#else + +/* + * No 64-bit type... + */ + +#endif + +#endif + +#endif + +/* + * If the "unsigned long" type has length 64 bits or more, then this is + * a "true" 64-bit architectures. This is also true with Visual C on + * amd64, even though the "long" type is limited to 32 bits. + */ +#if SPH_64 && (((ULONG_MAX >> 31) >> 31) >= 3 || defined _M_X64) +#define SPH_64_TRUE 1 +#endif + +/* + * Implementation note: some processors have specific opcodes to perform + * a rotation. Recent versions of gcc recognize the expression above and + * use the relevant opcodes, when appropriate. + */ + +#define SPH_T32(x) ((x) & SPH_C32(0xFFFFFFFF)) +#define SPH_ROTL32(x, n) SPH_T32(((x) << (n)) | ((x) >> (32 - (n)))) +#define SPH_ROTR32(x, n) SPH_ROTL32(x, (32 - (n))) + +#if SPH_64 + +#define SPH_T64(x) ((x) & SPH_C64(0xFFFFFFFFFFFFFFFF)) +#define SPH_ROTL64(x, n) SPH_T64(((x) << (n)) | ((x) >> (64 - (n)))) +#define SPH_ROTR64(x, n) SPH_ROTL64(x, (64 - (n))) + +#endif + +#ifndef DOXYGEN_IGNORE +/* + * Define SPH_INLINE to be an "inline" qualifier, if available. We define + * some small macro-like functions which benefit greatly from being inlined. + */ +#if (defined __STDC__ && __STDC_VERSION__ >= 199901L) || defined __GNUC__ +#define SPH_INLINE inline +#elif defined _MSC_VER +#define SPH_INLINE __inline +#else +#define SPH_INLINE +#endif +#endif + +/* + * We define some macros which qualify the architecture. These macros + * may be explicit set externally (e.g. as compiler parameters). The + * code below sets those macros if they are not already defined. + * + * Most macros are boolean, thus evaluate to either zero or non-zero. + * The SPH_UPTR macro is special, in that it evaluates to a C type, + * or is not defined. + * + * SPH_UPTR if defined: unsigned type to cast pointers into + * + * SPH_UNALIGNED non-zero if unaligned accesses are efficient + * SPH_LITTLE_ENDIAN non-zero if architecture is known to be little-endian + * SPH_BIG_ENDIAN non-zero if architecture is known to be big-endian + * SPH_LITTLE_FAST non-zero if little-endian decoding is fast + * SPH_BIG_FAST non-zero if big-endian decoding is fast + * + * If SPH_UPTR is defined, then encoding and decoding of 32-bit and 64-bit + * values will try to be "smart". Either SPH_LITTLE_ENDIAN or SPH_BIG_ENDIAN + * _must_ be non-zero in those situations. The 32-bit and 64-bit types + * _must_ also have an exact width. + * + * SPH_SPARCV9_GCC_32 UltraSPARC-compatible with gcc, 32-bit mode + * SPH_SPARCV9_GCC_64 UltraSPARC-compatible with gcc, 64-bit mode + * SPH_SPARCV9_GCC UltraSPARC-compatible with gcc + * SPH_I386_GCC x86-compatible (32-bit) with gcc + * SPH_I386_MSVC x86-compatible (32-bit) with Microsoft Visual C + * SPH_AMD64_GCC x86-compatible (64-bit) with gcc + * SPH_AMD64_MSVC x86-compatible (64-bit) with Microsoft Visual C + * SPH_PPC32_GCC PowerPC, 32-bit, with gcc + * SPH_PPC64_GCC PowerPC, 64-bit, with gcc + * + * TODO: enhance automatic detection, for more architectures and compilers. + * Endianness is the most important. SPH_UNALIGNED and SPH_UPTR help with + * some very fast functions (e.g. MD4) when using unaligned input data. + * The CPU-specific-with-GCC macros are useful only for inline assembly, + * normally restrained to this header file. + */ + +/* + * 32-bit x86, aka "i386 compatible". + */ +#if defined __i386__ || defined _M_IX86 + +#define SPH_DETECT_UNALIGNED 1 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u32 +#ifdef __GNUC__ +#define SPH_DETECT_I386_GCC 1 +#endif +#ifdef _MSC_VER +#define SPH_DETECT_I386_MSVC 1 +#endif + +/* + * 64-bit x86, hereafter known as "amd64". + */ +#elif defined __x86_64 || defined _M_X64 + +#define SPH_DETECT_UNALIGNED 1 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u64 +#ifdef __GNUC__ +#define SPH_DETECT_AMD64_GCC 1 +#endif +#ifdef _MSC_VER +#define SPH_DETECT_AMD64_MSVC 1 +#endif + +/* + * 64-bit Sparc architecture (implies v9). + */ +#elif ((defined __sparc__ || defined __sparc) && defined __arch64__) \ + || defined __sparcv9 + +#define SPH_DETECT_BIG_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u64 +#ifdef __GNUC__ +#define SPH_DETECT_SPARCV9_GCC_64 1 +#define SPH_DETECT_LITTLE_FAST 1 +#endif + +/* + * 32-bit Sparc. + */ +#elif (defined __sparc__ || defined __sparc) \ + && !(defined __sparcv9 || defined __arch64__) + +#define SPH_DETECT_BIG_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u32 +#if defined __GNUC__ && defined __sparc_v9__ +#define SPH_DETECT_SPARCV9_GCC_32 1 +#define SPH_DETECT_LITTLE_FAST 1 +#endif + +/* + * ARM, little-endian. + */ +#elif defined __arm__ && __ARMEL__ + +#define SPH_DETECT_LITTLE_ENDIAN 1 + +/* + * MIPS, little-endian. + */ +#elif MIPSEL || _MIPSEL || __MIPSEL || __MIPSEL__ + +#define SPH_DETECT_LITTLE_ENDIAN 1 + +/* + * MIPS, big-endian. + */ +#elif MIPSEB || _MIPSEB || __MIPSEB || __MIPSEB__ + +#define SPH_DETECT_BIG_ENDIAN 1 + +/* + * PowerPC. + */ +#elif defined __powerpc__ || defined __POWERPC__ || defined __ppc__ \ + || defined _ARCH_PPC + +/* + * Note: we do not declare cross-endian access to be "fast": even if + * using inline assembly, implementation should still assume that + * keeping the decoded word in a temporary is faster than decoding + * it again. + */ +#if defined __GNUC__ +#if SPH_64_TRUE +#define SPH_DETECT_PPC64_GCC 1 +#else +#define SPH_DETECT_PPC32_GCC 1 +#endif +#endif + +#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN +#define SPH_DETECT_BIG_ENDIAN 1 +#elif defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN +#define SPH_DETECT_LITTLE_ENDIAN 1 +#endif + +/* + * Itanium, 64-bit. + */ +#elif defined __ia64 || defined __ia64__ \ + || defined __itanium__ || defined _M_IA64 + +#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN +#define SPH_DETECT_BIG_ENDIAN 1 +#else +#define SPH_DETECT_LITTLE_ENDIAN 1 +#endif +#if defined __LP64__ || defined _LP64 +#define SPH_DETECT_UPTR sph_u64 +#else +#define SPH_DETECT_UPTR sph_u32 +#endif + +#endif + +#if defined SPH_DETECT_SPARCV9_GCC_32 || defined SPH_DETECT_SPARCV9_GCC_64 +#define SPH_DETECT_SPARCV9_GCC 1 +#endif + +#if defined SPH_DETECT_UNALIGNED && !defined SPH_UNALIGNED +#define SPH_UNALIGNED SPH_DETECT_UNALIGNED +#endif +#if defined SPH_DETECT_UPTR && !defined SPH_UPTR +#define SPH_UPTR SPH_DETECT_UPTR +#endif +#if defined SPH_DETECT_LITTLE_ENDIAN && !defined SPH_LITTLE_ENDIAN +#define SPH_LITTLE_ENDIAN SPH_DETECT_LITTLE_ENDIAN +#endif +#if defined SPH_DETECT_BIG_ENDIAN && !defined SPH_BIG_ENDIAN +#define SPH_BIG_ENDIAN SPH_DETECT_BIG_ENDIAN +#endif +#if defined SPH_DETECT_LITTLE_FAST && !defined SPH_LITTLE_FAST +#define SPH_LITTLE_FAST SPH_DETECT_LITTLE_FAST +#endif +#if defined SPH_DETECT_BIG_FAST && !defined SPH_BIG_FAST +#define SPH_BIG_FAST SPH_DETECT_BIG_FAST +#endif +#if defined SPH_DETECT_SPARCV9_GCC_32 && !defined SPH_SPARCV9_GCC_32 +#define SPH_SPARCV9_GCC_32 SPH_DETECT_SPARCV9_GCC_32 +#endif +#if defined SPH_DETECT_SPARCV9_GCC_64 && !defined SPH_SPARCV9_GCC_64 +#define SPH_SPARCV9_GCC_64 SPH_DETECT_SPARCV9_GCC_64 +#endif +#if defined SPH_DETECT_SPARCV9_GCC && !defined SPH_SPARCV9_GCC +#define SPH_SPARCV9_GCC SPH_DETECT_SPARCV9_GCC +#endif +#if defined SPH_DETECT_I386_GCC && !defined SPH_I386_GCC +#define SPH_I386_GCC SPH_DETECT_I386_GCC +#endif +#if defined SPH_DETECT_I386_MSVC && !defined SPH_I386_MSVC +#define SPH_I386_MSVC SPH_DETECT_I386_MSVC +#endif +#if defined SPH_DETECT_AMD64_GCC && !defined SPH_AMD64_GCC +#define SPH_AMD64_GCC SPH_DETECT_AMD64_GCC +#endif +#if defined SPH_DETECT_AMD64_MSVC && !defined SPH_AMD64_MSVC +#define SPH_AMD64_MSVC SPH_DETECT_AMD64_MSVC +#endif +#if defined SPH_DETECT_PPC32_GCC && !defined SPH_PPC32_GCC +#define SPH_PPC32_GCC SPH_DETECT_PPC32_GCC +#endif +#if defined SPH_DETECT_PPC64_GCC && !defined SPH_PPC64_GCC +#define SPH_PPC64_GCC SPH_DETECT_PPC64_GCC +#endif + +#if SPH_LITTLE_ENDIAN && !defined SPH_LITTLE_FAST +#define SPH_LITTLE_FAST 1 +#endif +#if SPH_BIG_ENDIAN && !defined SPH_BIG_FAST +#define SPH_BIG_FAST 1 +#endif + +#if defined SPH_UPTR && !(SPH_LITTLE_ENDIAN || SPH_BIG_ENDIAN) +#error SPH_UPTR defined, but endianness is not known. +#endif + +#if SPH_I386_GCC && !SPH_NO_ASM + +/* + * On x86 32-bit, with gcc, we use the bswapl opcode to byte-swap 32-bit + * values. + */ + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + __asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} + +#if SPH_64 + +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + return ((sph_u64)sph_bswap32((sph_u32)x) << 32) + | (sph_u64)sph_bswap32((sph_u32)(x >> 32)); +} + +#endif + +#elif SPH_AMD64_GCC && !SPH_NO_ASM + +/* + * On x86 64-bit, with gcc, we use the bswapl opcode to byte-swap 32-bit + * and 64-bit values. + */ + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + __asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} + +#if SPH_64 + +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + __asm__ __volatile__ ("bswapq %0" : "=r" (x) : "0" (x)); + return x; +} + +#endif + +/* + * Disabled code. Apparently, Microsoft Visual C 2005 is smart enough + * to generate proper opcodes for endianness swapping with the pure C + * implementation below. + * + +#elif SPH_I386_MSVC && !SPH_NO_ASM + +static __inline sph_u32 __declspec(naked) __fastcall +sph_bswap32(sph_u32 x) +{ + __asm { + bswap ecx + mov eax,ecx + ret + } +} + +#if SPH_64 + +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + return ((sph_u64)sph_bswap32((sph_u32)x) << 32) + | (sph_u64)sph_bswap32((sph_u32)(x >> 32)); +} + +#endif + + * + * [end of disabled code] + */ + +#else + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + x = SPH_T32((x << 16) | (x >> 16)); + x = ((x & SPH_C32(0xFF00FF00)) >> 8) + | ((x & SPH_C32(0x00FF00FF)) << 8); + return x; +} + +#if SPH_64 + +/** + * Byte-swap a 64-bit value. + * + * @param x the input value + * @return the byte-swapped value + */ +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + x = SPH_T64((x << 32) | (x >> 32)); + x = ((x & SPH_C64(0xFFFF0000FFFF0000)) >> 16) + | ((x & SPH_C64(0x0000FFFF0000FFFF)) << 16); + x = ((x & SPH_C64(0xFF00FF00FF00FF00)) >> 8) + | ((x & SPH_C64(0x00FF00FF00FF00FF)) << 8); + return x; +} + +#endif + +#endif + +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + +/* + * On UltraSPARC systems, native ordering is big-endian, but it is + * possible to perform little-endian read accesses by specifying the + * address space 0x88 (ASI_PRIMARY_LITTLE). Basically, either we use + * the opcode "lda [%reg]0x88,%dst", where %reg is the register which + * contains the source address and %dst is the destination register, + * or we use "lda [%reg+imm]%asi,%dst", which uses the %asi register + * to get the address space name. The latter format is better since it + * combines an addition and the actual access in a single opcode; but + * it requires the setting (and subsequent resetting) of %asi, which is + * slow. Some operations (i.e. MD5 compression function) combine many + * successive little-endian read accesses, which may share the same + * %asi setting. The macros below contain the appropriate inline + * assembly. + */ + +#define SPH_SPARCV9_SET_ASI \ + sph_u32 sph_sparcv9_asi; \ + __asm__ __volatile__ ( \ + "rd %%asi,%0\n\twr %%g0,0x88,%%asi" : "=r" (sph_sparcv9_asi)); + +#define SPH_SPARCV9_RESET_ASI \ + __asm__ __volatile__ ("wr %%g0,%0,%%asi" : : "r" (sph_sparcv9_asi)); + +#define SPH_SPARCV9_DEC32LE(base, idx) ({ \ + sph_u32 sph_sparcv9_tmp; \ + __asm__ __volatile__ ("lda [%1+" #idx "*4]%%asi,%0" \ + : "=r" (sph_sparcv9_tmp) : "r" (base)); \ + sph_sparcv9_tmp; \ + }) + +#endif + +static SPH_INLINE void +sph_enc16be(void *dst, unsigned val) +{ + ((unsigned char *)dst)[0] = (val >> 8); + ((unsigned char *)dst)[1] = val; +} + +static SPH_INLINE unsigned +sph_dec16be(const void *src) +{ + return ((unsigned)(((const unsigned char *)src)[0]) << 8) + | (unsigned)(((const unsigned char *)src)[1]); +} + +static SPH_INLINE void +sph_enc16le(void *dst, unsigned val) +{ + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = val >> 8; +} + +static SPH_INLINE unsigned +sph_dec16le(const void *src) +{ + return (unsigned)(((const unsigned char *)src)[0]) + | ((unsigned)(((const unsigned char *)src)[1]) << 8); +} + +/** + * Encode a 32-bit value into the provided buffer (big endian convention). + * + * @param dst the destination buffer + * @param val the 32-bit value to encode + */ +static SPH_INLINE void +sph_enc32be(void *dst, sph_u32 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; +#else + if (((SPH_UPTR)dst & 3) == 0) { +#if SPH_LITTLE_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; + } else { + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; + } +#endif +#else + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (big endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (32-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc32be_aligned(void *dst, sph_u32 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u32 *)dst = sph_bswap32(val); +#elif SPH_BIG_ENDIAN + *(sph_u32 *)dst = val; +#else + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (big endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32be(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif +#else + if (((SPH_UPTR)src & 3) == 0) { +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif + } else { + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); + } +#endif +#else + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (big endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (32-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32be_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#elif SPH_BIG_ENDIAN + return *(const sph_u32 *)src; +#else + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (little endian convention). + * + * @param dst the destination buffer + * @param val the 32-bit value to encode + */ +static SPH_INLINE void +sph_enc32le(void *dst, sph_u32 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; +#else + if (((SPH_UPTR)dst & 3) == 0) { +#if SPH_BIG_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; + } else { + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + } +#endif +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (little endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (32-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc32le_aligned(void *dst, sph_u32 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u32 *)dst = val; +#elif SPH_BIG_ENDIAN + *(sph_u32 *)dst = sph_bswap32(val); +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (little endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32le(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif +#else + if (((SPH_UPTR)src & 3) == 0) { +#if SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + sph_u32 tmp; + + /* + * "__volatile__" is needed here because without it, + * gcc-3.4.3 miscompiles the code and performs the + * access before the test on the address, thus triggering + * a bus error... + */ + __asm__ __volatile__ ( + "lda [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * On PowerPC, this turns out not to be worth the effort: the inline + * assembly makes GCC optimizer uncomfortable, which tends to nullify + * the decoding gains. + * + * For most hash functions, using this inline assembly trick changes + * hashing speed by less than 5% and often _reduces_ it. The biggest + * gains are for MD4 (+11%) and CubeHash (+30%). For all others, it is + * less then 10%. The speed gain on CubeHash is probably due to the + * chronic shortage of registers that CubeHash endures; for the other + * functions, the generic code appears to be efficient enough already. + * +#elif (SPH_PPC32_GCC || SPH_PPC64_GCC) && !SPH_NO_ASM + sph_u32 tmp; + + __asm__ __volatile__ ( + "lwbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap32(*(const sph_u32 *)src); +#endif +#else + return *(const sph_u32 *)src; +#endif + } else { + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); + } +#endif +#else + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (little endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (32-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32le_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return *(const sph_u32 *)src; +#elif SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + sph_u32 tmp; + + __asm__ __volatile__ ("lda [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif (SPH_PPC32_GCC || SPH_PPC64_GCC) && !SPH_NO_ASM + sph_u32 tmp; + + __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap32(*(const sph_u32 *)src); +#endif +#else + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); +#endif +} + +#if SPH_64 + +/** + * Encode a 64-bit value into the provided buffer (big endian convention). + * + * @param dst the destination buffer + * @param val the 64-bit value to encode + */ +static SPH_INLINE void +sph_enc64be(void *dst, sph_u64 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; +#else + if (((SPH_UPTR)dst & 7) == 0) { +#if SPH_LITTLE_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; + } else { + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; + } +#endif +#else + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (big endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (64-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc64be_aligned(void *dst, sph_u64 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u64 *)dst = sph_bswap64(val); +#elif SPH_BIG_ENDIAN + *(sph_u64 *)dst = val; +#else + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (big endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64be(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif +#else + if (((SPH_UPTR)src & 7) == 0) { +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif + } else { + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); + } +#endif +#else + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (big endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (64-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64be_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#elif SPH_BIG_ENDIAN + return *(const sph_u64 *)src; +#else + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (little endian convention). + * + * @param dst the destination buffer + * @param val the 64-bit value to encode + */ +static SPH_INLINE void +sph_enc64le(void *dst, sph_u64 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; +#else + if (((SPH_UPTR)dst & 7) == 0) { +#if SPH_BIG_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; + } else { + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); + } +#endif +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (little endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (64-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc64le_aligned(void *dst, sph_u64 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u64 *)dst = val; +#elif SPH_BIG_ENDIAN + *(sph_u64 *)dst = sph_bswap64(val); +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (little endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64le(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif +#else + if (((SPH_UPTR)src & 7) == 0) { +#if SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC_64 && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ( + "ldxa [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif SPH_PPC32_GCC && !SPH_NO_ASM + return (sph_u64)sph_dec32le_aligned(src) + | ((sph_u64)sph_dec32le_aligned( + (const char *)src + 4) << 32); +#elif SPH_PPC64_GCC && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ( + "ldbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap64(*(const sph_u64 *)src); +#endif +#else + return *(const sph_u64 *)src; +#endif + } else { + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); + } +#endif +#else + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (little endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (64-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64le_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return *(const sph_u64 *)src; +#elif SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC_64 && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ("ldxa [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif SPH_PPC32_GCC && !SPH_NO_ASM + return (sph_u64)sph_dec32le_aligned(src) + | ((sph_u64)sph_dec32le_aligned((const char *)src + 4) << 32); +#elif SPH_PPC64_GCC && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ("ldbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap64(*(const sph_u64 *)src); +#endif +#else + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); +#endif +} + +#endif + +#endif /* Doxygen excluded block */ + +#endif diff --git a/libaxolotl/jni/ed25519/sign.c b/libaxolotl/jni/ed25519/sign.c new file mode 100644 index 000000000..de53742a6 --- /dev/null +++ b/libaxolotl/jni/ed25519/sign.c @@ -0,0 +1,41 @@ +#include +#include "crypto_sign.h" +#include "crypto_hash_sha512.h" +#include "ge.h" +#include "sc.h" + +int crypto_sign( + unsigned char *sm,unsigned long long *smlen, + const unsigned char *m,unsigned long long mlen, + const unsigned char *sk +) +{ + unsigned char pk[32]; + unsigned char az[64]; + unsigned char nonce[64]; + unsigned char hram[64]; + ge_p3 R; + + memmove(pk,sk + 32,32); + + crypto_hash_sha512(az,sk,32); + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + *smlen = mlen + 64; + memmove(sm + 64,m,mlen); + memmove(sm + 32,az + 32,32); + crypto_hash_sha512(nonce,sm + 32,mlen + 32); + memmove(sm + 32,pk,32); + + sc_reduce(nonce); + ge_scalarmult_base(&R,nonce); + ge_p3_tobytes(sm,&R); + + crypto_hash_sha512(hram,sm,mlen + 64); + sc_reduce(hram); + sc_muladd(sm + 32,hram,az,nonce); + + return 0; +} diff --git a/libaxolotl/jni/ed25519/sqrtm1.h b/libaxolotl/jni/ed25519/sqrtm1.h new file mode 100644 index 000000000..d8caa23b6 --- /dev/null +++ b/libaxolotl/jni/ed25519/sqrtm1.h @@ -0,0 +1 @@ +-32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482 diff --git a/libaxolotl/libs/armeabi-v7a/libcurve25519.so b/libaxolotl/libs/armeabi-v7a/libcurve25519.so index 57efd28a843b65155d1aae40297f7ad53c6b42a6..90a3df310bb145aefee9f82628314abd6a860186 100755 GIT binary patch literal 90172 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ξiPox8~DZbqyY} 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 delta 4050 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 delta 6629 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 delta 1451 zcmZ8hZ)j6j6u&nwZC=tEU)s`kvuU4e+O+F7T^-%fZAm5jFqN*X$^>;uG5)~}k+mCz z4UKbX%UX#%*d0SOpWX0F!S;h~G6E_x#@yP%CfKM`f-TZP8HJ(8-+76f+lAlzo!>p@ zo_p?n_ug#M_4BYynVQ}$&NO%LU+ffuQ6|s~AtY$=ZJ?)!06G}uCBFl_0{;s9Hdq7f zcLKfl2IDd0dx}x?jfykZ*Sr78X=!rDu@r*8fUiop!~obt0rMq20Z#gb_{&%HUxVfe znotMFui_$04Iy^F(Oc{=#Glj(|FgRDe_BMN;~$iHq%RsB80_Dhi0(a@h#vT)|KqrI zbk+Ml4VfwdR4gh0kL8oqJ-l$9m%Y4D7r=|=jne_%Fy=}W!o2hz{A@tGFxbhA!8)_F zHX55Zz-hO>!cp+?+{3LxjKu?mu@m*sBawjqRU}|ujRbf;G2#pqzO`-|{tXw4aVv!r zM1%qQu3TztuvPRG8tpu%|CU3@)mo!9t=4DNJI2Gc`)b{P-zPerOLU6yi!c4*TYY_oXn%^U;^ww)dz+LV zl%|%RA=MF-e$9ljm5nfr1dO^k#_+asGXWmH8_x4VxmLRdBNvn{T5^`u0>amEh!Yz= zG)J@!w&?ciryTEiD^F?%y!w@Huk)&%rVTM)&XGFRCjG8$5Gjc7+T_cwB*fWyQuA%H z#q~Wz>^7;2c6jm-i+4zcSk&O>)ZZmF&@Nvs-v*I?pf0q_7t23~9a~Vpx66&kxB$6E z+w|rmA_I2%2GJ1gJop>1_=RXEH~^jmuLu7K&VrY~>0gQJA46jk!r&!v9Bj@K4TEF1 zh%SSB^F#%(afhe@fAU>D{8$Th@E#M)*7vj=o`I>ZOh3cA;jUJwsaagJkS@X0uggOabJ`9Z# zFHFf7+*~@NUd>L)Cif&vMp!+9tgx#_-!@0_a6$Yz*JA)z+G