aboutsummaryrefslogtreecommitdiff
path: root/lib/curve25519-donna/contrib/Curve25519Donna.c
blob: 71b816c6b622afc5706db6d3623f391718427d7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
    James Robson
    Public domain.
*/

#include "Curve25519Donna.h"
#include <stdio.h>
#include <stdlib.h>

extern void curve25519_donna(unsigned char *output, const unsigned char *a,
                             const unsigned char *b);

unsigned char*
as_unsigned_char_array(JNIEnv* env, jbyteArray array, int* len);

jbyteArray as_byte_array(JNIEnv* env, unsigned char* buf, int len);


jbyteArray as_byte_array(JNIEnv* env, unsigned char* buf, int len) {
    jbyteArray array = (*env)->NewByteArray(env, len);
    (*env)->SetByteArrayRegion(env, array, 0, len, (jbyte*)buf);

    //int i;
    //for (i = 0;i < len;++i) printf("%02x",(unsigned int) buf[i]); printf(" ");
    //printf("\n");

    return array;
}

unsigned char*
as_unsigned_char_array(JNIEnv* env, jbyteArray array, int* len) {

    *len = (*env)->GetArrayLength(env, array);
    unsigned char* buf = (unsigned char*)calloc(*len+1, sizeof(char));
    (*env)->GetByteArrayRegion (env, array, 0, *len, (jbyte*)buf);
    return buf;

}

JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_curve25519Donna
  (JNIEnv *env, jobject obj, jbyteArray a, jbyteArray b) {

    unsigned char o[32] = {0};
    int l1, l2;
    unsigned char* a1 = as_unsigned_char_array(env, a, &l1);
    unsigned char* b1 = as_unsigned_char_array(env, b, &l2);

    if ( !(l1 == 32 && l2 == 32) ) {
        fprintf(stderr, "Error, must be length 32");
        return NULL;
    }


    curve25519_donna(o, (const unsigned char*)a1, (const unsigned char*)b1);

    free(a1);
    free(b1);

    return as_byte_array(env, (unsigned char*)o, 32);
}

JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_makePrivate
  (JNIEnv *env, jobject obj, jbyteArray secret) {

    int len;
    unsigned char* k = as_unsigned_char_array(env, secret, &len);

    if (len != 32) {
        fprintf(stderr, "Error, must be length 32");        
        return NULL;
    }

    k[0] &= 248;
    k[31] &= 127;
    k[31] |= 64;
    return as_byte_array(env, k, 32);
}

JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_getPublic
  (JNIEnv *env, jobject obj, jbyteArray privkey) {

    int len;
    unsigned char* private = as_unsigned_char_array(env, privkey, &len);

    if (len != 32) {
        fprintf(stderr, "Error, must be length 32");        
        return NULL;
    }

    unsigned char pubkey[32];
    unsigned char basepoint[32] = {9};

    curve25519_donna(pubkey, private, basepoint);
    return as_byte_array(env, (unsigned char*)pubkey, 32);
}

JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_makeSharedSecret
  (JNIEnv *env, jobject obj, jbyteArray privkey, jbyteArray their_pubkey) {

    unsigned char shared_secret[32];

    int l1, l2;
    unsigned char* private = as_unsigned_char_array(env, privkey, &l1);
    unsigned char* pubkey = as_unsigned_char_array(env, their_pubkey, &l2);

    if ( !(l1 == 32 && l2 == 32) ) {
        fprintf(stderr, "Error, must be length 32");
        return NULL;
    }

    curve25519_donna(shared_secret, private, pubkey);
    return as_byte_array(env, (unsigned char*)shared_secret, 32);
}

JNIEXPORT void JNICALL Java_Curve25519Donna_helowrld
  (JNIEnv *env, jobject obj) {
    printf("helowrld\n");
}