Exemplo n.º 1
0
int
main()
{
  static const uint8_t point1[32] = {
    0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  };
  static const uint8_t point2[32] = {
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  };
  static const uint8_t scalar[32] = { 1 };
  uint8_t out1[32], out2[32];

  curve25519_donna(out1, scalar, point1);
  curve25519_donna(out2, scalar, point2);

  if (0 == memcmp(out1, out2, sizeof(out1))) {
    fprintf(stderr, "Top bit not ignored.\n");
    return 1;
  }

  fprintf(stderr, "Top bit correctly ignored.\n");
  return 0;
}
static void *run( void *state )  {
  thr_state *st = (thr_state*)state;
  unsigned char mypublic[32];
  uint64_t start, end;
  unsigned i;
  const unsigned iterations = 100000;

  printf("Waiting in thread %d ...\n", st->i+1);
  while( *st->all_start==0 ) ; 		/* spin */
  //printf("Proceed to testing in thread %d\n", st->i);

  // Load the caches
  for (i = 0; i < 1000; ++i) {
    curve25519_donna(mypublic, st->secret, basepoint);
  }

  start = time_now();
  for (i = 0; i < iterations; ++i) {
    curve25519_donna(mypublic, st->secret, basepoint);
  }
  end = time_now();

  st->op_sec = iterations*1000000. / (end - start);
  st->total_sec = (end - start)/1000000.;
  st->exited = 1;
  //printf("Exited thread %d\n", st->i);
  return NULL;
}
Exemplo n.º 3
0
void doit(unsigned char *ek,unsigned char *e,unsigned char *k)
{
	int i;

	for (i = 0;i < 32;++i) printhex((unsigned int) e[i]);
	for (i = 0;i < 32;++i) printhex((unsigned int) k[i]);
	curve25519_donna(ek,e,k);
	for (i = 0;i < 32;++i) printhex((unsigned int) ek[i]);
}
Exemplo n.º 4
0
void CECPQ1_finish(uint8_t shared_key[CECPQ1_SHARED_KEY_BYTES],
                   const CECPQ1_key& offer_key,
                   const uint8_t received[CECPQ1_ACCEPT_BYTES])
   {
   curve25519_donna(shared_key, offer_key.m_x25519.data(), received);

   newhope_shareda(shared_key + 32, &offer_key.m_newhope, received + 32,
                   Newhope_Mode::BoringSSL);
   }
Exemplo n.º 5
0
int main() {
	static const uint8_t basepoint[32] = {9};
	unsigned char publicKey[32] = {0};
	curve25519_donna(publicKey, privateKey, basepoint);
	printf("done\n");
	for (int i = 0; i < 32; ++i)
	{
		printf("%d ", publicKey[i]);
	}
	printf("\n");
}
Exemplo n.º 6
0
uint8_t do_one_computation(uint8_t *data) {
  uint8_t out[32] = {0};
  const uint8_t secret[32] = {1,2,3};
  uint8_t ret = 0;
  const uint8_t basepoint[32] = {9};
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  curve25519_donna(out, data, basepoint); memcpy(data, out, 32);
  ret ^= out[0];
  return ret;
}
Exemplo n.º 7
0
static void curve25519_djb_doit(unsigned char *ek,unsigned char *e,unsigned char *k, int print)
{
  int i;

  if (print) {
    for (i = 0;i < 32;++i) printf("%02x",(unsigned int) e[i]); printf(" ");
    for (i = 0;i < 32;++i) printf("%02x",(unsigned int) k[i]); printf(" ");
  }
  curve25519_donna(ek,e,k);
  if (print) {
    for (i = 0;i < 32;++i) printf("%02x",(unsigned int) ek[i]); printf("\n");
  }
}
Exemplo n.º 8
0
int
pairing_session_handshake(pairing_session_t *session, const unsigned char ecdh_key[32], const unsigned char ed_key[32])
{
	unsigned char ecdh_priv[32];

	assert(session);

	if (session->status == STATUS_FINISHED) {
		return -1;
	}
	if (ed25519_create_seed(ecdh_priv)) {
		return -2;
	}

	memcpy(session->ecdh_theirs, ecdh_key, 32);
	memcpy(session->ed_theirs, ed_key, 32);
	curve25519_donna(session->ecdh_ours, ecdh_priv, kCurve25519BasePoint);
	curve25519_donna(session->ecdh_secret, ecdh_priv, session->ecdh_theirs);

	session->status = STATUS_HANDSHAKE;
	return 0;
}
Exemplo n.º 9
0
static void
test_main(void) {
	int i;
	static const curve25519_key max = {
		255,255,255,255,255,255,255,255,
		255,255,255,255,255,255,255,255,
		255,255,255,255,255,255,255,255,
		255,255,255,255,255,255,255,255
	};
	static const curve25519_key mid = {
		127,127,127,127,127,127,127,127,
		127,127,127,127,127,127,127,127,
		127,127,127,127,127,127,127,127,
		127,127,127,127,127,127,127,127
	};
	curve25519_key pk[2];
	curve25519_key shared[2];
	uint64_t ticks, curveticks = maxticks;

	curve25519_donna(pk[0], max, max);
	for (i = 0; i < 1023; i++)
		curve25519_donna(pk[(i & 1) ^ 1], pk[i & 1], max);
	curve25519_donna_basepoint(pk[0], pk[1]);
	curveassert_equal(curve25519_expected, pk[0], sizeof(curve25519_key), "curve25519 sanity test failed to generate correct value");

	curve25519_donna_basepoint(pk[0], max);
	curve25519_donna_basepoint(pk[1], mid);
	curve25519_donna(shared[0], max, pk[1]);
	curve25519_donna(shared[1], mid, pk[0]);
	curveassert_equal(curve25519_shared, shared[0], sizeof(curve25519_key), "curve25519 failed to generate the same shared key (1)");
	curveassert_equal(curve25519_shared, shared[1], sizeof(curve25519_key), "curve25519 failed to generate the same shared key (2)");

	for (i = 0; i < 2048; i++) {
		timeit(curve25519_donna(pk[1], pk[0], max), curveticks);
	}

	printf("%.0f ticks/curve25519 scalarmult\n", (double)curveticks);
}
Exemplo n.º 10
0
void CECPQ1_accept(uint8_t shared_key[CECPQ1_SHARED_KEY_BYTES],
                   uint8_t send[CECPQ1_ACCEPT_BYTES],
                   const uint8_t received[CECPQ1_OFFER_BYTES],
                   RandomNumberGenerator& rng)
   {
   secure_vector<byte> x25519_key = rng.random_vec(32);

   curve25519_basepoint(send, x25519_key.data());

   curve25519_donna(shared_key, x25519_key.data(), received);

   newhope_sharedb(shared_key + 32, send + 32, received + 32,
                   rng, Newhope_Mode::BoringSSL);
   }
Exemplo n.º 11
0
JNIEXPORT jbyteArray JNICALL Java_org_whispersystems_textsecure_crypto_ecc_Curve25519_calculateAgreement
  (JNIEnv *env, jclass clazz, jbyteArray privateKey, jbyteArray publicKey)
{
    jbyteArray sharedKey       = (*env)->NewByteArray(env, 32);
    uint8_t*   sharedKeyBytes  = (uint8_t*)(*env)->GetByteArrayElements(env, sharedKey, 0);
    uint8_t*   privateKeyBytes = (uint8_t*)(*env)->GetByteArrayElements(env, privateKey, 0);
    uint8_t*   publicKeyBytes  = (uint8_t*)(*env)->GetByteArrayElements(env, publicKey, 0);

    curve25519_donna(sharedKeyBytes, privateKeyBytes, publicKeyBytes);

    (*env)->ReleaseByteArrayElements(env, sharedKey, sharedKeyBytes, 0);
    (*env)->ReleaseByteArrayElements(env, publicKey, publicKeyBytes, 0);
    (*env)->ReleaseByteArrayElements(env, privateKey, privateKeyBytes, 0);

    return sharedKey;
}
Exemplo n.º 12
0
JNIEXPORT jbyteArray JNICALL Java_org_whispersystems_textsecure_crypto_ecc_Curve25519_generatePublicKey
  (JNIEnv *env, jclass clazz, jbyteArray privateKey)
{
    static const uint8_t  basepoint[32] = {9};

    jbyteArray publicKey       = (*env)->NewByteArray(env, 32);
    uint8_t*   publicKeyBytes  = (uint8_t*)(*env)->GetByteArrayElements(env, publicKey, 0);
    uint8_t*   privateKeyBytes = (uint8_t*)(*env)->GetByteArrayElements(env, privateKey, 0);

    curve25519_donna(publicKeyBytes, privateKeyBytes, basepoint);

    (*env)->ReleaseByteArrayElements(env, publicKey, publicKeyBytes, 0);
    (*env)->ReleaseByteArrayElements(env, privateKey, privateKeyBytes, 0);

    return publicKey;
}
JNIEXPORT jbyteArray JNICALL Java_org_whispersystems_curve25519_NativeCurve25519Provider_calculateAgreement
(JNIEnv *env, jobject obj, jbyteArray privateKey, jbyteArray publicKey)
{
    jbyteArray sharedKey       = (*env)->NewByteArray(env, 32);
    uint8_t*   sharedKeyBytes  = (uint8_t*)(*env)->GetByteArrayElements(env, sharedKey, 0);
    uint8_t*   privateKeyBytes = (uint8_t*)(*env)->GetByteArrayElements(env, privateKey, 0);
    uint8_t*   publicKeyBytes  = (uint8_t*)(*env)->GetByteArrayElements(env, publicKey, 0);

    curve25519_donna(sharedKeyBytes, privateKeyBytes, publicKeyBytes);

    (*env)->ReleaseByteArrayElements(env, sharedKey, sharedKeyBytes, 0);
    (*env)->ReleaseByteArrayElements(env, publicKey, publicKeyBytes, 0);
    (*env)->ReleaseByteArrayElements(env, privateKey, privateKeyBytes, 0);

    return sharedKey;
}
JNIEXPORT jbyteArray JNICALL Java_org_whispersystems_curve25519_NativeCurve25519Provider_generatePublicKey
(JNIEnv *env, jobject obj, jbyteArray privateKey)
{
    static const uint8_t  basepoint[32] = {9};

    jbyteArray publicKey       = (*env)->NewByteArray(env, 32);
    uint8_t*   publicKeyBytes  = (uint8_t*)(*env)->GetByteArrayElements(env, publicKey, 0);
    uint8_t*   privateKeyBytes = (uint8_t*)(*env)->GetByteArrayElements(env, privateKey, 0);

    curve25519_donna(publicKeyBytes, privateKeyBytes, basepoint);

    (*env)->ReleaseByteArrayElements(env, publicKey, publicKeyBytes, 0);
    (*env)->ReleaseByteArrayElements(env, privateKey, privateKeyBytes, 0);

    return publicKey;
}
Exemplo n.º 15
0
OSStatus	curve25519_test( int print )
{
	OSStatus			err;
	uint8_t				e[ 32 ], k[ 32 ], ek[ 32 ], ek2[ 32 ];
	size_t				i, j, len;
	CFAbsoluteTime		t = 0;
	
	for( i = 0; i < countof( kCurve25519TestVectors ); ++i )
	{
		const curve25519_test_vector * const 	tv = &kCurve25519TestVectors[ i ];
		
		err = HexToData( tv->e, kSizeCString, kHexToData_NoFlags, e, sizeof( e ), &len, NULL, NULL );
		require_noerr( err, exit );
		require_action( len == 32, exit, err = kSizeErr );
		
		err = HexToData( tv->k, kSizeCString, kHexToData_NoFlags, k, sizeof( k ), &len, NULL, NULL );
		require_noerr( err, exit );
		require_action( len == 32, exit, err = kSizeErr );
		
		err = HexToData( tv->ek, kSizeCString, kHexToData_NoFlags, ek, sizeof( ek ), &len, NULL, NULL );
		require_noerr( err, exit );
		require_action( len == 32, exit, err = kSizeErr );
		
		memset( ek2, 0, sizeof( ek2 ) );
		curve25519_donna( ek2, e, k );
		require_action( memcmp( ek, ek2, 32 ) == 0, exit, err = kMismatchErr );
		
		if( print )
		{
			for( j = 0; j < 32; ++j ) printf( "%02x", e[ j ] );  printf( " " );
			for( j = 0; j < 32; ++j ) printf( "%02x", k[ j ] );  printf( " " );
			for( j = 0; j < 32; ++j ) printf( "%02x", ek[ j ] ); printf( "\n" );
		}
	}
	
	t = CFAbsoluteTimeGetCurrent();
	err = curve25519_djb_test( print );
	require_noerr( err, exit );
	t = CFAbsoluteTimeGetCurrent() - t;
	
exit:
	FPrintF( stdout, "%###s: %s (%f seconds)\n", __ROUTINE__, !err ? "PASSED" : "FAILED", t );
	return( err );
}
Exemplo n.º 16
0
STATIC int
curve25519_impl(uint8_t *output, const uint8_t *secret,
                const uint8_t *basepoint)
{
  uint8_t bp[CURVE25519_PUBKEY_LEN];
  int r;
  memcpy(bp, basepoint, CURVE25519_PUBKEY_LEN);
  /* Clear the high bit, in case our backend foolishly looks at it. */
  bp[31] &= 0x7f;
#ifdef USE_CURVE25519_DONNA
  r = curve25519_donna(output, secret, bp);
#elif defined(USE_CURVE25519_NACL)
  r = crypto_scalarmult_curve25519(output, secret, bp);
#else
#error "No implementation of curve25519 is available."
#endif
  memwipe(bp, 0, sizeof(bp));
  return r;
}
Exemplo n.º 17
0
static OSStatus
    __MFiSAP_Exchange_ServerM1( 
        MFiSAPRef       inRef, 
        const uint8_t * inInputPtr,
        size_t          inInputLen, 
        uint8_t **      outOutputPtr,
        size_t *        outOutputLen )
{
    OSStatus            err;
    const uint8_t *     inputEnd;
    const uint8_t *     clientECDHPublicKey;
    uint8_t             ourPrivateKey[ kMFiSAP_ECDHKeyLen ];
    uint8_t             ourPublicKey[ kMFiSAP_ECDHKeyLen ];
    SHA_CTX             sha1Context;
    uint8_t             digest[ 20 ];
    uint8_t *           signaturePtr = NULL;
    size_t              signatureLen;
    uint8_t *           certificatePtr = NULL;
    size_t              certificateLen;
    uint8_t             aesMasterKey[ kMFiSAP_AESKeyLen ];
    uint8_t             aesMasterIV[ kMFiSAP_AESKeyLen ];
    uint8_t *           buf;
    uint8_t *           dst;
    size_t              len;

    if( ( UpTicks() - gMFiSAP_LastTicks ) < UpTicksPerSecond() )
    {
        if( gMFiSAP_ThrottleCounter < 4 ) ++gMFiSAP_ThrottleCounter;
        SleepForUpTicks( gMFiSAP_ThrottleCounter * UpTicksPerSecond() );
    }
    else
    {
        gMFiSAP_ThrottleCounter = 0;
    }
    gMFiSAP_LastTicks = UpTicks();

    // Validate inputs. Input data must be: <1:version> <32:client's ECDH public key>.

    inputEnd = inInputPtr + inInputLen;
    require_action( inputEnd > inInputPtr, exit, err = kSizeErr ); // Detect bad length causing ptr wrap.

    require_action( ( inputEnd - inInputPtr ) >= kMFiSAP_VersionLen, exit, err = kSizeErr );
    inRef->version = *inInputPtr++;
    require_action( inRef->version == kMFiSAPVersion1, exit, err = kVersionErr );

    require_action( ( inputEnd - inInputPtr ) >= kMFiSAP_ECDHKeyLen, exit, err = kSizeErr );
    clientECDHPublicKey = inInputPtr;
    inInputPtr += kMFiSAP_ECDHKeyLen;

    require_action( inInputPtr == inputEnd, exit, err = kSizeErr );

    // Generate a random ECDH key pair.

    err = PlatformRandomBytes( ourPrivateKey, sizeof( ourPrivateKey ) );
    require_noerr( err, exit );
    curve25519_donna( ourPublicKey, ourPrivateKey, NULL );

    // Use our private key and the client's public key to generate the shared secret.
    // Hash the shared secret and truncate it to form the AES master key.
    // Hash the shared secret with salt to derive the AES master IV.

    curve25519_donna( inRef->sharedSecret, ourPrivateKey, clientECDHPublicKey );
    SHA1_Init( &sha1Context );
    SHA1_Update( &sha1Context, kMFiSAP_AES_KEY_SaltPtr, kMFiSAP_AES_KEY_SaltLen );
    SHA1_Update( &sha1Context, inRef->sharedSecret, sizeof( inRef->sharedSecret ) );
    SHA1_Final( digest, &sha1Context );
    memcpy( aesMasterKey, digest, sizeof( aesMasterKey ) );

    SHA1_Init( &sha1Context );
    SHA1_Update( &sha1Context, kMFiSAP_AES_IV_SaltPtr, kMFiSAP_AES_IV_SaltLen );
    SHA1_Update( &sha1Context, inRef->sharedSecret, sizeof( inRef->sharedSecret ) );
    SHA1_Final( digest, &sha1Context );
    memcpy( aesMasterIV, digest, sizeof( aesMasterIV ) );

    // Use the auth chip to sign a hash of <32:our ECDH public key> <32:client's ECDH public key>.
    // And copy the auth chip's certificate so the client can verify the signature.

    SHA1_Init( &sha1Context );
    SHA1_Update( &sha1Context, ourPublicKey, sizeof( ourPublicKey ) );
    SHA1_Update( &sha1Context, clientECDHPublicKey, kMFiSAP_ECDHKeyLen );
    SHA1_Final( digest, &sha1Context );
    err = PlatformMFiAuthCreateSignature( digest, sizeof( digest ), &signaturePtr, &signatureLen );
    require_noerr( err, exit );

    err = PlatformMFiAuthCopyCertificate( &certificatePtr, &certificateLen );
    require_noerr( err, exit );

    // Encrypt the signature with the AES master key and master IV.
    
    err = AES_CTR_Init( &inRef->aesMasterContext, aesMasterKey, aesMasterIV );
    require_noerr( err, exit );

    err = AES_CTR_Update( &inRef->aesMasterContext, signaturePtr, signatureLen, signaturePtr );
    if( err ) AES_CTR_Final( &inRef->aesMasterContext );
    require_noerr( err, exit );

    inRef->aesMasterValid = true;

    // Return the response:
    //
    //      <32:our ECDH public key>
    //      <4:big endian certificate length>
    //      <N:certificate data>
    //      <4:big endian signature length>
    //      <N:encrypted signature data>

    len = kMFiSAP_ECDHKeyLen + 4 + certificateLen + 4 + signatureLen;
    buf = (uint8_t *) malloc( len );
    require_action( buf, exit, err = kNoMemoryErr );
    dst = buf;

    memcpy( dst, ourPublicKey, sizeof( ourPublicKey ) );
    dst += sizeof( ourPublicKey );

    *dst++ = (uint8_t)( ( certificateLen >> 24 ) & 0xFF );
    *dst++ = (uint8_t)( ( certificateLen >> 16 ) & 0xFF );
    *dst++ = (uint8_t)( ( certificateLen >>  8 ) & 0xFF );
    *dst++ = (uint8_t)(   certificateLen         & 0xFF );
    memcpy( dst, certificatePtr, certificateLen );
    dst += certificateLen;

    *dst++ = (uint8_t)( ( signatureLen >> 24 ) & 0xFF );
    *dst++ = (uint8_t)( ( signatureLen >> 16 ) & 0xFF );
    *dst++ = (uint8_t)( ( signatureLen >>  8 ) & 0xFF );
    *dst++ = (uint8_t)(   signatureLen         & 0xFF );
    memcpy( dst, signaturePtr, signatureLen );
    dst += signatureLen;

    check( dst == ( buf + len ) );
    *outOutputPtr = buf;
    *outOutputLen = (size_t)( dst - buf );

exit:
    if( certificatePtr )    free( certificatePtr );
    if( signaturePtr )      free( signaturePtr );
    return( err );
}
Exemplo n.º 18
0
    void operator()(std::map<uint64_t, uint64_t> &accounts, std::string thread_seed) {
        // Our approach is to pick a random point and repeatedly double it.
        // This is cheaper than the more naive approach of multiplying the
        // generator point times random exponents.
        // We work in batches because our point doubling algorithm requires a
        // modular inversion which is more efficiently computed in batches.
        const int n = BATCH_SIZE;
        felem xs[BATCH_SIZE], zs[BATCH_SIZE];
        std::vector<bytestring> exponents;
        static const unsigned char generator[32] = {9};
        for ( int i = 0; i < n; i++ ) {
            bytestring exponent(32, 0);
            std::string exponent_seed = boost::str(boost::format("%1%:%2%") % thread_seed % i);
            sha256((unsigned char*) &exponent_seed[0], exponent_seed.size(), &exponent[0]);
            // transform initial exponent according to curve25519 tweaks
            exponent[0] &= 248;
            exponent[31] &= 127;
            exponent[31] |= 64;
            uint8_t pubkey[32];
            curve25519_donna(pubkey, &exponent[0], generator);
            fexpand(xs[i], pubkey);
            exponents.push_back(exponent);
        }
        for ( uint64_t doublings = 1; true; doublings++ ) {
            for ( int i = 0; i < n; i++ ) {
                felem xout;
                xz_ge_double(xout, zs[i], xs[i]);
                fcopy(xs[i], xout);
            }
            batch_inverse(zs, n);
            for ( int i = 0; i < n; i++ ) {
                felem xout;
                fmul(xout, xs[i], zs[i]);
                uint8_t pubkey[32], pubkey_hash[32];
                fcontract(pubkey, xout);
                // not entirely sure normalizing the representation of x is necessary but can't hurt
                fexpand(xout, pubkey);
                fcopy(xs[i], xout);
                sha256(pubkey, 32, pubkey_hash);
                uint64_t account_id = *((uint64_t*) pubkey_hash);

                unsigned int a = (pubkey_hash[0] << 24) | (pubkey_hash[1] << 16) | (pubkey_hash[2] << 8) | (pubkey_hash[3]);
                if((a==0x25c5a207) || (a==0x861fc1a3) || (a==0x65ae467f) || (a==0xba973233) || (a==0x6e01b0b7) || (a==0x28dca32c) || (a==0xf297ad07) || (a==0xed66fe31) || (a==0xba2d6f04) || (a==0xc846bf0c) || (a==0x4fa8cf07) || (a==0x4e6e2b3d) || (a==0x1febd530) || (a==0x780ad9aa) || (a==0xb60166f3) || (a==0xa0860100) || (a==0xe239bdb) || (a==0xe708b03a) || (a==0xb1efa06b) || (a==0xe2ea7edf) || (a==0x1c96882c)) {
                    boost::lock_guard<boost::recursive_mutex> lock(guard);
                    boost::multiprecision::cpp_int e = compute_exponent(exponents[i], doublings);
                    std::cout << "found share " << account_id << std::endl;
                    std::cout << "  pubkey = " << get_array(pubkey) << std::endl;
                    std::cout << "  pubhash = " << get_array(pubkey_hash) << std::endl;
                    std::cout << "  secret exponent = " << e << std::endl;

                    unsigned char net_order[32];
                    for(int i=0; i<32; ++i) {
                        int j = e.convert_to<int>();
                        net_order[31-i] = j & 0xFF;
                        e = e >> 8;
                    }
                    submit_share(account,get_array(net_order));


                }

            }
            checked += n;
        }
Exemplo n.º 19
0
void Curve25519::calculateAgreement(const char *myprivate, const char *theirpublic, char *shared_key)
{
    //uint8_t shared_key[32];
    curve25519_donna((uint8_t *)shared_key, (const uint8_t *)myprivate, (const uint8_t *)theirpublic);
}
Exemplo n.º 20
0
void Curve25519::generatePublicKey(const char *privatekey, char *mypublic)
{
    //uint8_t mypublic[32];
    const uint8_t basepoint[32] = {9};
    curve25519_donna((uint8_t *)mypublic, (const uint8_t *)privatekey, basepoint);
}
Exemplo n.º 21
0
void zktest()
{
    /*
     # Given the public key of B (remote_pub), shows that the shared secret
     # between A and B was generated by A.
     # Returns zero-knowledge proof of shared Diffie-Hellman secret between A & B.
     def prove_shared_secret(self, remote_pub):
     G = self.G; prover_pub = self.public; phi = self. P - 1;
     secret = self.get_shared_secret(remote_pub)
     
     # Random key in the group Z_q
     randKey = DiffieHellman() # random secret
     commit1 = randKey.public
     commit2 = randKey.get_shared_secret(remote_pub)
     */
    void fdifference_backwards(uint64_t *out, const uint64_t *in); // output = in - output
    void fmul(uint64_t *output,const uint64_t *in,const uint64_t *in2);
    void fcontract(uint8_t *output, const uint64_t *input);
    void fexpand(uint64_t *output, const uint8_t *in);
    bits256 curve25519(bits256,bits256);
    static uint8_t _basepoint[32] = {9};
    bits320 randsecret,challenge,product,response,selfsecret,secret;
    bits256 remote_pub,basepoint,remote_secret,randkey,commit1,commit2,_secret,tmp,buf[8]; int32_t n = 0;
    tmp = GENESIS_PRIVKEY;
    _secret = curve25519(tmp,remote_pub);
    fexpand(secret.ulongs,_secret.bytes);
    randombytes(randkey.bytes,sizeof(randkey)), randkey.bytes[0] &= 248, randkey.bytes[31] &= 127, randkey.bytes[31] |= 64;
    randombytes(remote_secret.bytes,sizeof(remote_secret)), remote_secret.bytes[0] &= 248, remote_secret.bytes[31] &= 127, remote_secret.bytes[31] |= 64;
    memcpy(basepoint.bytes,_basepoint,sizeof(basepoint));
    remote_pub = curve25519(remote_secret,basepoint);
    fexpand(randsecret.ulongs,randkey.bytes);
    curve25519_donna(commit1.bytes,randkey.bytes,_basepoint);
    commit2 = curve25519(randkey,remote_pub);
    /*
     # shift and hash
     concat = str(G) + str(prover_pub) + str(remote_pub) + str(secret) + str(commit1) + str(commit2)
     h = hashlib.md5()
     h.update(concat.encode("utf-8"))
     challenge = int(h.hexdigest(), 16)
     product = (self.secret * challenge) % phi
     response = (randKey.secret - product) % phi
     
     return (secret, challenge, response)*/
    buf[n++] = GENESIS_PRIVKEY, buf[n++] = GENESIS_PUBKEY;
    buf[n++] = remote_pub, buf[n++] = _secret, buf[n++] = commit1, buf[n++] = commit2;
    memset(challenge.bytes,0,sizeof(challenge));
    calc_sha256(0,tmp.bytes,buf[0].bytes,n*sizeof(buf[0]));
    fexpand(challenge.ulongs,tmp.bytes);
    tmp = GENESIS_PRIVKEY;
    fexpand(selfsecret.ulongs,tmp.bytes);
    fmul(product.ulongs,selfsecret.ulongs,challenge.ulongs);
    response = product;
    fdifference_backwards(product.ulongs,randsecret.ulongs);
    /*
     # Verifies proof generated above. Verifier c is showing that
     # shared secret between A and B was generated by A.
     # returns 0 if if verification fails; returns shared secret otherwise
     def verify_shared_secret(self, prover_pub, remote_pub, secret, challenge,
     response):
     P = self.P; G = self.G ; public = self.public
     
     # g^r * (a's public key)^challenge
     commit1 = (pow(G, response, P) * pow(public, challenge, P)) % P
     
     # (b's public key)^response * (secret)^challenge
     commit2 = (pow(remote_pub, response, P) * pow(secret, challenge, P)) % P
     */
    bits256 _commit1b,_commit2b,_tmp2,_challenge,_response; bits320 Tmp,Tmp2,commit2b;
    fcontract(_challenge.bytes,challenge.ulongs);
    fcontract(_response.bytes,response.ulongs);
    tmp = curve25519(_secret,_challenge);
    _tmp2 = curve25519(remote_pub,_response);
    fexpand(Tmp.ulongs,tmp.bytes);
    fexpand(Tmp2.ulongs,_tmp2.bytes);
    fmul(commit2b.ulongs,Tmp.ulongs,Tmp2.ulongs);
    fcontract(_commit2b.bytes,commit2b.ulongs);
    printf("commits %llx %llx vs %llx %llx\n",commit1.txid,commit2.txid,_commit1b.txid,_commit2b.txid);
    /*
     # Shift and hash
     hasher = hashlib.md5()
     concat = str(G) + str(prover_pub) + str(remote_pub) + str(secret) + str(commit1) + str(commit2)
     hasher.update(concat.encode("utf-8"))
     check = int(hasher.hexdigest(), 16)
     
     if challenge == check:
     return secret
     else:
     return 0
     
     def main():
     a = DiffieHellman()
     b = DiffieHellman()
     results = a.prove_shared_secret(b.public)
     assert a.verify_shared_secret(a.public, b.public, results[0],  \
     results[1], results[2])
     */
}
Exemplo n.º 22
0
void curve25519_ecdh(void *shared, const void *priv, const void *other)
{
    curve25519_donna(shared, priv, other);
}
Exemplo n.º 23
0
void curve25519_pub(void *pub, const void *priv)
{
    static const uint8_t basepoint[32] = { 9 };
    curve25519_donna(pub, priv, basepoint);
}