tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }