blinding.c (3779B)
1 /* Added to ref10 for Tor. We place this in the public domain. Alternatively, 2 * you may have it under the Creative Commons 0 "CC0" license. */ 3 //#include "fe.h" 4 #include "ge.h" 5 #include "sc.h" 6 #include "crypto_hash_sha512.h" 7 #include "ed25519_ref10.h" 8 9 #include <string.h> 10 #include "lib/crypt_ops/crypto_util.h" 11 12 static void 13 ed25519_ref10_gettweak(unsigned char *out, const unsigned char *param) 14 { 15 memcpy(out, param, 32); 16 17 out[0] &= 248; /* Is this necessary necessary ? */ 18 out[31] &= 63; 19 out[31] |= 64; 20 } 21 22 int ed25519_ref10_blind_secret_key(unsigned char *out, 23 const unsigned char *inp, 24 const unsigned char *param) 25 { 26 const char str[] = "Derive temporary signing key hash input"; 27 unsigned char tweak[64]; 28 unsigned char zero[32]; 29 ed25519_ref10_gettweak(tweak, param); 30 31 memset(zero, 0, 32); 32 sc_muladd(out, inp, tweak, zero); 33 34 crypto_hash_sha512_2(tweak, (const unsigned char *)str, strlen(str), 35 inp+32, 32); 36 memcpy(out+32, tweak, 32); 37 38 memwipe(tweak, 0, sizeof(tweak)); 39 40 return 0; 41 } 42 43 int ed25519_ref10_blind_public_key(unsigned char *out, 44 const unsigned char *inp, 45 const unsigned char *param) 46 { 47 unsigned char tweak[64]; 48 unsigned char zero[32]; 49 unsigned char pkcopy[32]; 50 ge_p3 A; 51 ge_p2 Aprime; 52 int retval = -1; 53 54 ed25519_ref10_gettweak(tweak, param); 55 56 memset(zero, 0, sizeof(zero)); 57 /* Not the greatest implementation of all of this. I wish I had 58 * better-suited primitives to work with here... (but I don't wish that so 59 * strongly that I'm about to code my own ge_scalarmult_vartime). */ 60 61 /* We negate the public key first, so that we can pass it to 62 * frombytes_negate_vartime, which negates it again. If there were a 63 * "ge_frombytes", we'd use that, but there isn't. */ 64 memcpy(pkcopy, inp, 32); 65 pkcopy[31] ^= (1<<7); 66 if (ge_frombytes_negate_vartime(&A, pkcopy) != 0) { 67 goto done; 68 } 69 /* There isn't a regular ge_scalarmult -- we have to do tweak*A + zero*B. */ 70 ge_double_scalarmult_vartime(&Aprime, tweak, &A, zero); 71 ge_tobytes(out, &Aprime); 72 73 retval = 0; 74 75 done: 76 memwipe(tweak, 0, sizeof(tweak)); 77 memwipe(&A, 0, sizeof(A)); 78 memwipe(&Aprime, 0, sizeof(Aprime)); 79 memwipe(pkcopy, 0, sizeof(pkcopy)); 80 81 return retval; 82 } 83 84 /* This is the group order encoded in a format that 85 * ge_double_scalarmult_vartime() understands. The group order m is: 86 * m = 2^252 + 27742317777372353535851937790883648493 = 87 * 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed 88 */ 89 static const uint8_t modm_m[32] = {0xed,0xd3,0xf5,0x5c,0x1a,0x63,0x12,0x58, 90 0xd6,0x9c,0xf7,0xa2,0xde,0xf9,0xde,0x14, 91 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 92 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10}; 93 94 /* Do the scalar multiplication of <b>pubkey</b> with the group order 95 * <b>modm_m</b>. Place the result in <b>out</b> which must be at least 32 96 * bytes long. */ 97 int 98 ed25519_ref10_scalarmult_with_group_order(unsigned char *out, 99 const unsigned char *pubkey) 100 { 101 unsigned char pkcopy[32]; 102 unsigned char zero[32] = {0}; 103 ge_p3 Point; 104 ge_p2 Result; 105 106 /* All this is done to fit 'pubkey' in 'Point' so that it can be used by 107 * ed25519 ref code. Same thing as in blinding function */ 108 memcpy(pkcopy, pubkey, 32); 109 pkcopy[31] ^= (1<<7); 110 if (ge_frombytes_negate_vartime(&Point, pkcopy) != 0) { 111 return -1; /* error: bail out */ 112 } 113 114 /* There isn't a regular scalarmult -- we have to do r = l*P + 0*B */ 115 ge_double_scalarmult_vartime(&Result, modm_m, &Point, zero); 116 ge_tobytes(out, &Result); 117 118 return 0; 119 }