tadd_scalar.c - sick - sign and check files using ed25519
 (HTM) git clone git://z3bra.org/sick
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tadd_scalar.c (2170B)
       ---
            1 #include "ed25519.h"
            2 #include "ge.h"
            3 #include "sc.h"
            4 #include "sha512.h"
            5 
            6 
            7 /* see http://crypto.stackexchange.com/a/6215/4697 */
            8 void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) {
            9     const unsigned char SC_1[32] = {1}; /* scalar with value 1 */
           10     
           11     unsigned char n[32]; 
           12     ge_p3 nB;
           13     ge_p1p1 A_p1p1;
           14     ge_p3 A;
           15     ge_p3 public_key_unpacked;
           16     ge_cached T;
           17 
           18     sha512_context hash;
           19     unsigned char hashbuf[64];
           20 
           21     int i;
           22 
           23     /* copy the scalar and clear highest bit */
           24     for (i = 0; i < 31; ++i) {
           25         n[i] = scalar[i];
           26     }
           27     n[31] = scalar[31] & 127;
           28 
           29     /* private key: a = n + t */
           30     if (private_key) {
           31         sc_muladd(private_key, SC_1, n, private_key);
           32 
           33         // https://github.com/orlp/ed25519/issues/3
           34         sha512_init(&hash);
           35         sha512_update(&hash, private_key + 32, 32);
           36         sha512_update(&hash, scalar, 32);
           37         sha512_final(&hash, hashbuf);
           38         for (i = 0; i < 32; ++i) {
           39             private_key[32 + i] = hashbuf[i];
           40         }
           41     }
           42 
           43     /* public key: A = nB + T */
           44     if (public_key) {
           45         /* if we know the private key we don't need a point addition, which is faster */
           46         /* using a "timing attack" you could find out wether or not we know the private
           47            key, but this information seems rather useless - if this is important pass
           48            public_key and private_key seperately in 2 function calls */
           49         if (private_key) {
           50             ge_scalarmult_base(&A, private_key);
           51         } else {
           52             /* unpack public key into T */
           53             ge_frombytes_negate_vartime(&public_key_unpacked, public_key);
           54             fe_neg(public_key_unpacked.X, public_key_unpacked.X); /* undo negate */
           55             fe_neg(public_key_unpacked.T, public_key_unpacked.T); /* undo negate */
           56             ge_p3_to_cached(&T, &public_key_unpacked);
           57 
           58             /* calculate n*B */
           59             ge_scalarmult_base(&nB, n);
           60 
           61             /* A = n*B + T */
           62             ge_add(&A_p1p1, &nB, &T);
           63             ge_p1p1_to_p3(&A, &A_p1p1);
           64         }
           65             
           66         /* pack public key */
           67         ge_p3_tobytes(public_key, &A);
           68     }
           69 }