예제 #1
0
// Step 3
// y = (sk_r + c * sk) mod #(B)  with sk secret
int schnorr_id_response(uint8_t response[SCHNORR_ID_RESPONSEBYTES],
                        const uint8_t sk[SCHNORR_SECRETKEYBYTES],
                        const uint8_t sk_r[SCHNORR_SECRETKEYBYTES],
                        const uint8_t challenge[SCHNORR_ID_CHALLENGEBYTES]) {
  sc25519 sc_sk;
  sc25519 sc_sk_r;
  sc25519 sc_challenge;

  sc25519_from32bytes(&sc_sk, sk);
  sc25519_from32bytes(&sc_sk_r, sk_r);
  sc25519_from_challenge_bytes(&sc_challenge, challenge);

  sc25519_mul(&sc_sk, &sc_sk, &sc_challenge);
  sc25519_add(&sc_sk, &sc_sk, &sc_sk_r);

  sc25519_to32bytes(response, &sc_sk);
  return 0;
}
int schnorr_publickey(uint8_t pk[SCHNORR_PUBLICKEYBYTES],
                      const uint8_t sk[SCHNORR_SECRETKEYBYTES]) {
  sc25519 sc_sk;
  ge25519 ge_pk;

  sc25519_from32bytes(&sc_sk, sk);

  ge25519_scalarmult_base(&ge_pk, &sc_sk);
  ge25519_pack(pk, &ge_pk);
  return 0;
}
예제 #3
0
int crypto_sign_ed25519(
    unsigned char *sm,unsigned long long *smlen,
    const unsigned char *m,unsigned long long mlen,
    const unsigned char *sk
    )
{
  sc25519 sck, scs, scsk;
  ge25519 ger;
  unsigned char r[32];
  unsigned char s[32];
  unsigned char extsk[64];
  unsigned long long i;
  unsigned char hmg[crypto_hash_sha512_BYTES];
  unsigned char hram[crypto_hash_sha512_BYTES];

  crypto_hash_sha512(extsk, sk, 32);
  extsk[0] &= 248;
  extsk[31] &= 127;
  extsk[31] |= 64;

  *smlen = mlen+64;
  for(i=0;i<mlen;i++)
    sm[64 + i] = m[i];
  for(i=0;i<32;i++)
    sm[32 + i] = extsk[32+i];

  crypto_hash_sha512(hmg, sm+32, mlen+32); /* Generate k as h(extsk[32],...,extsk[63],m) */

  /* Computation of R */
  sc25519_from64bytes(&sck, hmg);
  ge25519_scalarmult_base(&ger, &sck);
  ge25519_pack(r, &ger);
  
  /* Computation of s */
  for(i=0;i<32;i++)
    sm[i] = r[i];

  get_hram(hram, sm, sk+32, sm, mlen+64);

  sc25519_from64bytes(&scs, hram);
  sc25519_from32bytes(&scsk, extsk);
  sc25519_mul(&scs, &scs, &scsk);
  
  sc25519_add(&scs, &scs, &sck);

  sc25519_to32bytes(s,&scs); /* cat s */
  for(i=0;i<32;i++)
    sm[32 + i] = s[i]; 

  return 0;
}
void test_sc25519_mul()
{
  unsigned char a[32], b[32];
  sc25519 fa, fb, fr;
  int n;

  for(n=0;n<NTESTS;n++)
  {
    randombytes(a,32);
    randombytes(b,32);
    sc25519_from32bytes(&fa, a);
    sc25519_from32bytes(&fb, b);
    sc25519_mul(&fr, &fa, &fb);

    print("(");
    sc25519_print(&fa);
    print("*");
    sc25519_print(&fb);
    print(") % 7237005577332262213973186563042994240857116359379907606001950938285454250989 -");
    sc25519_print(&fr);
    print("\r\n");
  }
}
예제 #5
0
void sc25519_random(sc25519 *r, int c)
{
	unsigned char x[32];

	simpleot_randombytes(x, 32);

	if (c == 0) 
	{
		x[31] &= 15;
	}
	else    
	{    
		x[0] &= 248;
		x[31] &= 127;
	}

	sc25519_from32bytes(r, x);
}
예제 #6
0
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 hram[64];
  unsigned char rcheck[32];
  ge25519 get1, get2;
  sc25519 schram, scs;

  if (smlen < 64) goto badsig;
  if (sm[63] & 224) goto badsig;
  if (ge25519_unpackneg_vartime(&get1,pk)) goto badsig;

  memmove(pkcopy,pk,32);
  memmove(rcopy,sm,32);

  sc25519_from32bytes(&scs, sm+32);

  memmove(m,sm,smlen);
  memmove(m + 32,pkcopy,32);
  crypto_hash_sha512(hram,m,smlen);

  sc25519_from64bytes(&schram, hram);

  ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
  ge25519_pack(rcheck, &get2);

  if (crypto_verify_32(rcopy,rcheck) == 0) {
    memmove(m,m + 64,smlen - 64);
    memset(m + smlen - 64,0,64);
    *mlen = smlen - 64;
    return 0;
  }

badsig:
  *mlen = (unsigned long long) -1;
  memset(m,0,smlen);
  return -1;
}
예제 #7
0
int crypto_sign_ed25519_open(
    unsigned char *m,unsigned long long *mlen,
    const unsigned char *sm,unsigned long long smlen,
    const unsigned char *pk
    )
{
  unsigned int i;
  int ret;
  unsigned char t2[32];
  ge25519 get1, get2;
  sc25519 schram, scs;
  unsigned char hram[crypto_hash_sha512_BYTES];

  *mlen = (unsigned long long) -1;
  if (smlen < 64) return -1;

  if (ge25519_unpackneg_vartime(&get1, pk)) return -1;

  get_hram(hram,sm,pk,m,smlen);

  sc25519_from64bytes(&schram, hram);

  sc25519_from32bytes(&scs, sm+32);

  ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
  ge25519_pack(t2, &get2);

  ret = crypto_verify_32(sm, t2);

  if (!ret)
  {
    for(i=0;i<smlen-64;i++)
      m[i] = sm[i + 64];
    *mlen = smlen-64;
  }
  else
  {
    for(i=0;i<smlen-64;i++)
      m[i] = 0;
  }
  return ret;
}
예제 #8
0
// Step 3 bis
// verify pk_r = y.B - c.pk  with pk = sk.B
int schnorr_id_verify(const uint8_t pk[SCHNORR_PUBLICKEYBYTES],
                      const uint8_t pk_r[SCHNORR_PUBLICKEYBYTES],
                      const uint8_t challenge[SCHNORR_ID_CHALLENGEBYTES],
                      const uint8_t response[SCHNORR_ID_RESPONSEBYTES]) {
  ge25519 ge_pk_neg;
  sc25519 sc_challenge;
  sc25519 sc_response;
  ge25519 ge_pk_r_verifier;
  uint8_t pk_r_verifier[SCHNORR_PUBLICKEYBYTES];


  if (ge25519_unpackneg_vartime(&ge_pk_neg, pk))
    return -1;

  sc25519_from_challenge_bytes(&sc_challenge, challenge);
  sc25519_from32bytes(&sc_response, response);

  ge25519_double_scalarmult_vartime(&ge_pk_r_verifier,
                                    &ge_pk_neg, &sc_challenge,
                                    &ge25519_base, &sc_response);
  ge25519_pack(pk_r_verifier, &ge_pk_r_verifier);
  return verify_32(pk_r, pk_r_verifier);
}
예제 #9
0
int crypto_sign_ed25519_keypair(
    unsigned char *pk,
    unsigned char *sk
    )
{
  sc25519 scsk;
  ge25519 gepk;
  unsigned char extsk[64];
  int i;

  randombytes(sk, 32);
  crypto_hash_sha512(extsk, sk, 32);
  extsk[0] &= 248;
  extsk[31] &= 127;
  extsk[31] |= 64;

  sc25519_from32bytes(&scsk,extsk);
  
  ge25519_scalarmult_base(&gepk, &scsk);
  ge25519_pack(pk, &gepk);
  for(i=0;i<32;i++)
    sk[32 + i] = pk[i];
  return 0;
}
예제 #10
0
파일: batch.c 프로젝트: 0x20c24/cjdns
int crypto_sign_open_batch(
    unsigned char* const m[],unsigned long long mlen[],
    unsigned char* const sm[],const unsigned long long smlen[],
    unsigned char* const pk[], 
    unsigned long long num
    )
{
  int ret = 0;
  unsigned long long i, j;
  shortsc25519 r[MAXBATCH];
  sc25519 scalars[2*MAXBATCH+1];
  ge25519 points[2*MAXBATCH+1];
  unsigned char hram[crypto_hash_sha512_BYTES];
  unsigned long long batchsize;

  for (i = 0;i < num;++i) mlen[i] = -1;

  while (num >= 3) {
    batchsize = num;
    if (batchsize > MAXBATCH) batchsize = MAXBATCH;

    for (i = 0;i < batchsize;++i)
      if (smlen[i] < 64) goto fallback;

    randombytes((unsigned char*)r,sizeof(shortsc25519) * batchsize);

    /* Computing scalars[0] = ((r1s1 + r2s2 + ...)) */
    for(i=0;i<batchsize;i++)
    {
      sc25519_from32bytes(&scalars[i], sm[i]+32); 
      sc25519_mul_shortsc(&scalars[i], &scalars[i], &r[i]);
    }
    for(i=1;i<batchsize;i++)
      sc25519_add(&scalars[0], &scalars[0], &scalars[i]);
    
    /* Computing scalars[1] ... scalars[batchsize] as r[i]*H(R[i],A[i],m[i]) */
    for(i=0;i<batchsize;i++)
    {
      get_hram(hram, sm[i], pk[i], m[i], smlen[i]);
      sc25519_from64bytes(&scalars[i+1],hram);
      sc25519_mul_shortsc(&scalars[i+1],&scalars[i+1],&r[i]);
    }
    /* Setting scalars[batchsize+1] ... scalars[2*batchsize] to r[i] */
    for(i=0;i<batchsize;i++)
      sc25519_from_shortsc(&scalars[batchsize+i+1],&r[i]);
  
    /* Computing points */
    points[0] = ge25519_base;
  
    for(i=0;i<batchsize;i++)
      if (ge25519_unpackneg_vartime(&points[i+1], pk[i])) goto fallback;
    for(i=0;i<batchsize;i++)
      if (ge25519_unpackneg_vartime(&points[batchsize+i+1], sm[i])) goto fallback;
  
    ge25519_multi_scalarmult_vartime(points, points, scalars, 2*batchsize+1);
  
    if (ge25519_isneutral_vartime(points)) {
      for(i=0;i<batchsize;i++)
      {
        for(j=0;j<smlen[i]-64;j++)
          m[i][j] = sm[i][j + 64];
        mlen[i] = smlen[i]-64;
      }
    } else {
      fallback:

      for (i = 0;i < batchsize;++i)
        ret |= crypto_sign_open(m[i], &mlen[i], sm[i], smlen[i], pk[i]);
    }

    m += batchsize;
    mlen += batchsize;
    sm += batchsize;
    smlen += batchsize;
    pk += batchsize;
    num -= batchsize;
  }

  for (i = 0;i < num;++i)
    ret |= crypto_sign_open(m[i], &mlen[i], sm[i], smlen[i], pk[i]);

  return ret;
}