diff --git a/aws/cl_zcash/software/runtime/test_zcash.cpp b/aws/cl_zcash/software/runtime/test_zcash.cpp index bff68b0..7b9091a 100644 --- a/aws/cl_zcash/software/runtime/test_zcash.cpp +++ b/aws/cl_zcash/software/runtime/test_zcash.cpp @@ -80,7 +80,7 @@ int main(int argc, char **argv) { uint32_t value = 0; unsigned int timeout = 0; unsigned int read_len = 0; - uint8_t reply[512]; + uint8_t reply[640]; // Process command line args { int i; @@ -116,8 +116,8 @@ int main(int argc, char **argv) { // Store generator points in FPGA size_t g1_slot = 64; - size_t g2_slot = 68; - + size_t g2_slot = 68; + data.point_type = zcash_fpga::FP2_AF; memset(&data, 0x0, sizeof(zcash_fpga::bls12_381_data_t)); string_to_hex("024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", (unsigned char *)data.dat); @@ -151,7 +151,8 @@ int main(int argc, char **argv) { data.point_type = zcash_fpga::FP_AF; memset(&data, 0x0, sizeof(zcash_fpga::bls12_381_data_t)); string_to_hex("08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1", (unsigned char *)data.dat); - rc = zfpga.bls12_381_set_data_slot(g1_slot + 1, data); fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); + rc = zfpga.bls12_381_set_data_slot(g1_slot + 1, data); + fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); data.point_type = zcash_fpga::SCALAR; @@ -164,36 +165,51 @@ int main(int argc, char **argv) { inst.code = zcash_fpga::SEND_INTERRUPT; inst.a = 0; inst.b = 123; - rc = zfpga.bls12_381_set_inst_slot(1, inst); + rc = zfpga.bls12_381_set_inst_slot(5, inst); fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); inst.code = zcash_fpga::SEND_INTERRUPT; inst.a = 1; inst.b = 456; - rc = zfpga.bls12_381_set_inst_slot(2, inst); + rc = zfpga.bls12_381_set_inst_slot(6, inst); fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); - inst.code = zcash_fpga::POINT_MULT; - inst.a = 0; - inst.b = g1_slot; + + // Multi pairing of e(G1, G2) . e(G1, G2) + inst.code = zcash_fpga::MILLER_LOOP; + inst.a = g1_slot; + inst.b = g2_slot; inst.c = 1; rc = zfpga.bls12_381_set_inst_slot(1, inst); fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); - // Multi pairing inst.code = zcash_fpga::MILLER_LOOP; - inst.a = 1; + inst.a = g1_slot; inst.b = g2_slot; + inst.c = 13; + rc = zfpga.bls12_381_set_inst_slot(2, inst); + fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); + + inst.code = zcash_fpga::MUL_ELEMENT; + inst.a = 1; + inst.b = 12; inst.c = 1; - rc = zfpga.bls12_381_set_inst_slot(2, inst); fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); + rc = zfpga.bls12_381_set_inst_slot(3, inst); + fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); + inst.code = zcash_fpga::FINAL_EXP; + inst.a = 1; + inst.b = 1; + inst.c = 0; + rc = zfpga.bls12_381_set_inst_slot(4, inst); + fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); // Start the test rc = zcash.bls12_381_set_curr_inst_slot(1); fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); // Wait for interrupts - // Try read reply - should be our scalar value + // Try read reply - should be our scalar value - not using right now, could be used for point multiplication timeout = 0; read_len = 0; @@ -211,11 +227,25 @@ int main(int argc, char **argv) { for (int i = read_len-1; i>=0; i--) printf("%x", reply[i]); printf("\n"); - // Try read second reply - should be point value - 6 slots - memset(reply, 0, 512); + zcash_fpga::bls12_381_interrupt_rpl_t bls12_381_interrupt_rpl; + + // Check it matches the expected values + bls12_381_interrupt_rpl = &(zcash_fpga::bls12_381_interrupt_rpl_t*)&reply; + if (bls12_381_interrupt_rpl.data_type != zcash_fpga::SCALAR) { + printf("ERROR: Interrupt data type was wrong, expected SCALAR, was [%d]\n", bls12_381_interrupt_rpl.data_type); + } + if (bls12_381_interrupt_rpl.index != 123) { + printf("ERROR: Interrupt index was wrong, expected 123, was [%d]\n", bls12_381_interrupt_rpl.index); + } + if (reply[sizeof(zcash_fpga::bls12_381_interrupt_rpl_t)] != 10) { + printf("ERROR: Interrupt data was wrong, expected 10, was [%d]\n", reply[sizeof(zcash_fpga::bls12_381_interrupt_rpl_t)]); + } + + // Try read second reply - should be point value - 12 slots = 576 bytes + memset(reply, 0, 640); timeout = 0; read_len = 0; - while ((read_len = zfpga.read_stream(reply, 512)) == 0) { + while ((read_len = zfpga.read_stream(reply, 640)) == 0) { usleep(1); timeout++; if (timeout > 1000) { @@ -228,6 +258,36 @@ int main(int argc, char **argv) { for (int i = read_len-1; i>=0; i--) printf("%x", reply[i]); printf("\n"); + // Check it matches the expected values + bls12_381_interrupt_rpl = &(zcash_fpga::bls12_381_interrupt_rpl_t*)&reply; + if (bls12_381_interrupt_rpl.data_type != zcash_fpga::FE12) { + printf("ERROR: Interrupt data type was wrong, expected FE12, was [%d]\n", bls12_381_interrupt_rpl.data_type); + } + if (bls12_381_interrupt_rpl.index != 456) { + printf("ERROR: Interrupt index was wrong, expected 456, was [%d]\n", bls12_381_interrupt_rpl.index); + } + + // Check it matches the value expected from our software model + uint8_t exp_res[640]; + memset(exp_res, 0, 640); + string_to_hex("04fb0f149dd925d2c590a960936763e519c2b62e14c7759f96672cd852194325904197b0b19c6b528ab33566946af39b", (unsigned char *)&exp_res[0]); + string_to_hex("185ef728cf41a1b7b700b7e445f0b372bc29e370bc227d443c70ae9dbcf73fee8acedbd317a286a53266562d817269c0", (unsigned char *)&exp_res[48]); + string_to_hex("03a3734dbeb064bf4bc4a03f945a4921e49d04ab8d45fd753a28b8fa082616b4b17bbcb685e455ff3bf8f60c3bd32a0c", (unsigned char *)&exp_res[2*48]); + string_to_hex("1409cebef9ef393aa00f2ac64673675521e8fc8fddaf90976e607e62a740ac59c3dddf95a6de4fba15beb30c43d4e3f8", (unsigned char *)&exp_res[3*48]); + string_to_hex("1692a61ce5f4d7a093b2c46aa4bca6c4a66cf873d405ebc9c35d8aa639763720177b23beffaf522d5e41d3c5310ea333", (unsigned char *)&exp_res[4*48]); + string_to_hex("081abd33a78d31eb8d4c1bb3baab0529bb7baf1103d848b4cead1a8e0aa7a7b260fbe79c67dbe41ca4d65ba8a54a72b6", (unsigned char *)&exp_res[5*48]); + string_to_hex("0900410bb2751d0a6af0fe175dcf9d864ecaac463c6218745b543f9e06289922434ee446030923a3e4c4473b4e3b1914", (unsigned char *)&exp_res[6*48]); + string_to_hex("113286dee21c9c63a458898beb35914dc8daaac453441e7114b21af7b5f47d559879d477cf2a9cbd5b40c86becd07128", (unsigned char *)&exp_res[7*48]); + string_to_hex("06d8046c6b3424c4cd2d72ce98d279f2290a28a87e8664cb0040580d0c485f34df45267f8c215dcbcd862787ab555c7e", (unsigned char *)&exp_res[8*48]); + string_to_hex("0f6b8b52b2b5d0661cbf232820a257b8c5594309c01c2a45e64c6a7142301e4fb36e6e16b5a85bd2e437599d103c3ace", (unsigned char *)&exp_res[9*48]); + string_to_hex("017f1c95cf79b22b459599ea57e613e00cb75e35de1f837814a93b443c54241015ac9761f8fb20a44512ff5cfc04ac7f", (unsigned char *)&exp_res[10*48]); + string_to_hex("079ab7b345eb23c944c957a36a6b74c37537163d4cbf73bad9751de1dd9c68ef72cb21447e259880f72a871c3eda1b0c", (unsigned char *)&exp_res[11*48]); + + if (memcmp((void*)reply[sizeof(zcash_fpga::bls12_381_interrupt_rpl_t)], (void*)exp_res, 576) != 0) { + printf("ERROR: Interrupt data was wrong (check data slot 1-13)!"); + } + + // Read current instruction rc = zfpga.bls12_381_get_curr_inst_slot(slot_id); fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); @@ -235,14 +295,13 @@ int main(int argc, char **argv) { printf("Data slot is now %d\n", slot_id); // Print out data slots - for(int i = 0; i < 10; i++) { + for(int i = 0; i < 14; i++) { zfpga.bls12_381_get_data_slot(i, data); printf("slot %d, pt: %d, data:0x", i, data.point_type); for(int j = 47; j >= 0; j--) printf("%02x", data.dat[j]); printf("\n"); } - return rc; out: return 1; diff --git a/aws/cl_zcash/software/runtime/zcash_fpga.hpp b/aws/cl_zcash/software/runtime/zcash_fpga.hpp index 961355b..e1c7915 100644 --- a/aws/cl_zcash/software/runtime/zcash_fpga.hpp +++ b/aws/cl_zcash/software/runtime/zcash_fpga.hpp @@ -134,6 +134,13 @@ class zcash_fpga { fpga_state_t fpga_state; } fpga_status_rpl_t; + typedef struct __attribute__((__packed__)) { + header_t hdr; + uint32_t index; + point_type_t data_type; + uint8_t padding[3]; + } bls12_381_interrupt_rpl_t; + private: static const uint16_t s_pci_vendor_id = 0x1D0F; /* Amazon PCI Vendor ID */ static const uint16_t s_pci_device_id = 0xF000; /* PCI Device ID preassigned by Amazon for F1 applications */