/* Return public key associated with sk */ void curve25519_dh_CalculatePublicKey( unsigned char *pk, /* [32-bytes] OUT: Public key */ unsigned char *sk) /* [32-bytes] IN/OUT: Your secret key */ { ecp_TrimSecretKey(sk); ecp_PointMultiply(pk, ecp_BasePoint, sk, 32); }
/* Create a shared secret */ void curve25519_dh_CreateSharedKey( unsigned char *shared, /* [32-bytes] OUT: Created shared key */ const unsigned char *pk, /* [32-bytes] IN: Other side's public key */ unsigned char *sk) /* [32-bytes] IN/OUT: Your secret key */ { ecp_TrimSecretKey(sk); ecp_PointMultiply(shared, pk, sk, 32); }
int curve25519_SelfTest(int level) { int rc = 0; U64 A[4], B[4], C[4]; U8 a[32], b[32], c[32], d[32]; ecp_AddReduce(A, _w_I, _w_P); ECP_MOD(A); if (ecp_Cmp(A, _w_I) != 0) { rc++; printf("assert I+p == I mod p FAILED!!\n"); ecp_PrintHexWords("A_1", A, 4); } if (ecp_Cmp(_w_I, _w_P) >= 0) { rc++; printf("assert I < P FAILED!!\n"); } if (ecp_Cmp(_w_P, _w_I) <= 0) { rc++; printf("assert P > I FAILED!!\n"); } ecp_MulReduce(B, _w_I, _w_D); ECP_MOD(B); if (ecp_Cmp(B, _w_IxD) != 0) { rc++; printf("assert I*D FAILED!!\n"); ecp_PrintHexWords("A_2", B, 4); } // assert I*I == p-1 ecp_MulMod(A, _w_I, _w_I); if (ecp_Cmp(A, _w_Pm1) != 0) { rc++; printf("assert mul(I,I) == p-1 FAILED!!\n"); ecp_PrintHexWords("A_3", A, 4); } // assert I**2 == p-1 ecp_SqrReduce(B, _w_I); ECP_MOD(B); if (ecp_Cmp(B, _w_Pm1) != 0) { rc++; printf("assert square(I) == p-1 FAILED!!\n"); ecp_PrintHexWords("B_4", B, 4); } // assert (-I)*(-I) == p-1 ecp_Sub(B, _w_P, _w_I); ecp_MulMod(A, B, B); if (ecp_Cmp(A, _w_Pm1) != 0) { rc++; printf("assert mul(-I,-I) == p-1 FAILED!!\n"); ecp_PrintHexWords("A_5", A, 4); ecp_PrintHexWords("B_5", B, 4); } ecp_SetValue(A, 50153); ecp_Inverse(B, A); ecp_MulMod(A, A, B); if (ecp_Cmp(A, _w_One) != 0) { rc++; printf("invmod FAILED!!\n"); ecp_PrintHexWords("inv_50153", B, 4); ecp_PrintHexWords("expected_1", A, 4); } // assert expmod(d,(p-1)/2,p) == p-1 ecp_ExpMod(A, _w_D, _b_Pm1d2, 32); if (ecp_Cmp(A, _w_Pm1) != 0) { rc++; printf("assert expmod(d,(p-1)/2,p) == p-1 FAILED!!\n"); ecp_PrintHexWords("A_3", A, 4); } ecp_CalculateY(a, ecp_BasePoint); ecp_BytesToWords(A, a); if (ecp_Cmp(A, _w_Gy) != 0) { rc++; printf("assert clacY(Base) == Base.y FAILED!!\n"); ecp_PrintHexBytes("Calculated_Base.y", a, 32); } ecp_PointMultiply(a, ecp_BasePoint, _b_Om1, 32); if (memcmp(a, ecp_BasePoint, 32) != 0) { rc++; printf("assert (l-1).Base == Base FAILED!!\n"); ecp_PrintHexBytes("A_5", a, 32); } ecp_PointMultiply(a, ecp_BasePoint, _b_O, 32); ecp_BytesToWords(A, a); if (!ecp_IsZero(A)) { rc++; printf("assert l.Base == 0 FAILED!!\n"); ecp_PrintHexBytes("A_6", a, 32); } // Key generation ecp_PointMultiply(a, ecp_BasePoint, pk1, 32); ecp_PrintHexBytes("PublicKey1", a, 32); ecp_PointMultiply(b, ecp_BasePoint, pk2, 32); ecp_PrintHexBytes("PublicKey2", b, 32); // ECDH - key exchange ecp_PointMultiply(c, b, pk1, 32); ecp_PrintHexBytes("SharedKey1", c, 32); ecp_PointMultiply(d, a, pk2, 32); ecp_PrintHexBytes("SharedKey2", d, 32); if (memcmp(c, d, 32) != 0) { rc++; printf("ECDH key exchange FAILED!!\n"); } memset(a, 0x44, 32); // our secret key ecp_PointMultiply(b, ecp_BasePoint, a, 32); // public key ecp_PointMultiply(c, b, _b_k1, 32); ecp_PointMultiply(d, c, _b_k2, 32); if (memcmp(d, b, 32) != 0) { rc++; printf("assert k1.k2.D == D FAILED!!\n"); ecp_PrintHexBytes("D", d, 4); ecp_PrintHexBytes("C", c, 4); ecp_PrintHexBytes("A", a, 4); } ecp_BytesToWords(A, _b_k1); ecp_BytesToWords(B, _b_k2); eco_InvModBPO(C, A); if (ecp_Cmp(C, B) != 0) { rc++; printf("assert 1/k1 == k2 mod BPO FAILED!!\n"); ecp_PrintHexWords("Calc", C, 4); ecp_PrintHexWords("Expt", B, 4); } eco_MulMod(C, A, B); if (ecp_Cmp(C, _w_One) != 0) { rc++; printf("assert k1*k2 == 1 mod BPO FAILED!!\n"); ecp_PrintHexWords("Calc", C, 4); } return rc; }