| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| */ |
| /** |
| * @file test_fp_arithmetics.c |
| * @author Samuele Andreoli |
| * @brief Test for aritmetics with FP |
| * |
| */ |
| |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include "arch.h" |
| #include "amcl.h" |
| #include "utils.h" |
| #include "fp48_YYY.h" |
| |
| #define LINE_LEN 10000 |
| |
| /* |
| * Skips n closed brackets. |
| * Null terminates after the nth bracket and |
| * returns a pointer to the next char |
| */ |
| char* skip_cb(char* str, int n) |
| { |
| int i; |
| char* next=str; |
| |
| for(i=0; i<n; i++) |
| { |
| next = strchr(++next,']'); |
| if (next == NULL) |
| { |
| printf("ERROR unexpected test vector\n"); |
| exit(EXIT_FAILURE); |
| } |
| } |
| *(++next) = '\0'; |
| |
| return next++; |
| } |
| |
| void read_BIG_XXX(BIG_XXX A, char* string) |
| { |
| int len; |
| char support[LINE_LEN]; |
| BIG_XXX_zero(A); |
| len = strlen(string)+1; |
| amcl_hex2bin(string,support,len); |
| len = (len-1)/2; |
| BIG_XXX_fromBytesLen(A,support,len); |
| BIG_XXX_norm(A); |
| } |
| |
| void read_FP2_YYY(FP2_YYY *fp2, char* stringx) |
| { |
| char *stringy; |
| BIG_XXX x,y; |
| |
| stringy = strchr(++stringx,','); |
| if (stringy == NULL) |
| { |
| printf("ERROR unexpected test vector\n"); |
| exit(EXIT_FAILURE); |
| } |
| *(stringy)=0; |
| skip_cb(stringy++,1); |
| |
| read_BIG_XXX(x,stringx); |
| read_BIG_XXX(y,stringy); |
| |
| FP2_YYY_from_BIGs(fp2,x,y); |
| } |
| |
| void read_FP4_YYY(FP4_YYY *fp4, char* stringx) |
| { |
| char *stringy; |
| FP2_YYY x,y; |
| stringy = skip_cb(stringx++,1); |
| skip_cb(stringy++,1); |
| |
| read_FP2_YYY(&x,stringx); |
| read_FP2_YYY(&y,stringy); |
| |
| FP4_YYY_from_FP2s(fp4,&x,&y); |
| } |
| |
| void read_FP8_YYY(FP8_YYY *fp8, char* stringx) |
| { |
| char *stringy; |
| FP4_YYY x,y; |
| stringy = skip_cb(stringx++,3); |
| skip_cb(stringy++,3); |
| |
| read_FP4_YYY(&x,stringx); |
| read_FP4_YYY(&y,stringy); |
| |
| FP8_YYY_from_FP4s(fp8,&x,&y); |
| } |
| |
| void read_FP16_YYY(FP16_YYY *fp16, char* stringx) |
| { |
| char *stringy; |
| FP8_YYY x,y; |
| stringy = skip_cb(stringx++,7); |
| skip_cb(stringy++,7); |
| |
| read_FP8_YYY(&x,stringx); |
| read_FP8_YYY(&y,stringy); |
| |
| FP16_YYY_from_FP8s(fp16,&x,&y); |
| } |
| |
| void read_FP48_YYY(FP48_YYY *fp48, char *stringx) |
| { |
| char *stringy, *stringz; |
| FP16_YYY x,y,z; |
| |
| stringy = skip_cb(stringx++,15); |
| stringz = skip_cb(stringy++,15); |
| skip_cb(stringz++,15); |
| |
| read_FP16_YYY(&x,stringx); |
| read_FP16_YYY(&y,stringy); |
| read_FP16_YYY(&z,stringz); |
| |
| FP48_YYY_from_FP16s(fp48,&x,&y,&z); |
| } |
| |
| int main(int argc, char** argv) |
| { |
| |
| if (argc != 2) |
| { |
| printf("usage: ./test_fp48_arithmetics_ZZZ [path to test vector file]\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| int i = 0, j = 1, k, len = 0; |
| FILE *fp; |
| |
| char line[LINE_LEN]; |
| char * linePtr = NULL; |
| |
| BIG_XXX M, Fr_a, Fr_b; |
| FP2_YYY Frob; |
| FP16_YYY FP16aux1; |
| FP48_YYY FP48aux1, FP48aux2; |
| char octaux[48*MODBYTES_XXX]; |
| octet OCTaux = {0,sizeof(octaux),octaux}; |
| |
| FP48_YYY FP_48[3], FP_48_frobs[16]; |
| const char* FP48_lines[3] = |
| { |
| "FP48_1 = ", |
| "FP48_2 = ", |
| "FP48_c = " |
| }; |
| FP48_YYY FP_48_smul_y_dtype; |
| const char* FP48smul_y_dtypeline = "FP48smul_y_dtype = "; |
| FP48_YYY FP_48_smul_y_mtype; |
| const char* FP48smul_y_mtypeline = "FP48smul_y_mtype = "; |
| FP48_YYY FP48conj; |
| const char* FP48conjline = "FP48conj = "; |
| FP48_YYY FP48usquare; |
| const char* FP48usquareline = "FP48usquare = "; |
| FP48_YYY FP48square; |
| const char* FP48squareline = "FP48square = "; |
| FP48_YYY FP48mul; |
| const char* FP48mulline = "FP48mul = "; |
| FP48_YYY FP48smul_dtype; |
| const char* FP48smuldtypeline = "FP48smul_dtype = "; |
| FP48_YYY FP48smul_mtype; |
| const char* FP48smulmtypeline = "FP48smul_mtype = "; |
| FP48_YYY FP48inv; |
| const char* FP48invline = "FP48inv = "; |
| BIG_XXX BIGsc[18]; |
| const char* BIGsclines[18] = |
| { |
| "BIGsc1 = ", |
| "BIGsc2 = ", |
| "BIGsc3 = ", |
| "BIGsc4 = ", |
| "BIGsc5 = ", |
| "BIGsc6 = ", |
| "BIGsc7 = ", |
| "BIGsc8 = ", |
| "BIGsc9 = ", |
| "BIGsc10 = ", |
| "BIGsc11 = ", |
| "BIGsc12 = ", |
| "BIGsc13 = ", |
| "BIGsc14 = ", |
| "BIGsc15 = ", |
| "BIGsc16 = ", |
| "BIGscs = ", |
| "BIGsco = " |
| }; |
| FP48_YYY FP48pow; |
| const char* FP48powline = "FP48pow = "; |
| FP48_YYY FP48pinpow; |
| const char* FP48pinpowline = "FP48pinpow = "; |
| FP16_YYY FP48compows; |
| const char* FP48compowsline = "FP48compows = "; |
| FP16_YYY FP48compow; |
| const char* FP48compowline = "FP48compow = "; |
| FP48_YYY FP48pow16; |
| const char* FP48pow16line = "FP48pow16 = "; |
| FP48_YYY FP48frob; |
| const char* FP48frobline = "FP48frob = "; |
| FP16_YYY FP16trace; |
| const char* FP16traceline = "FP16trace = "; |
| |
| BIG_XXX_rcopy(M,Modulus_YYY); |
| BIG_XXX_rcopy(Fr_a,Fra_YYY); |
| BIG_XXX_rcopy(Fr_b,Frb_YYY); |
| FP2_YYY_from_BIGs(&Frob,Fr_a,Fr_b); |
| |
| // Set to one |
| FP48_YYY_one(&FP48aux1); |
| FP48_YYY_copy(&FP48aux2,&FP48aux1); |
| |
| // Testing equal function |
| if(!FP48_YYY_equals(&FP48aux1,&FP48aux2)) |
| { |
| printf("ERROR comparing equal FP48s or copying FP48\n"); |
| exit(EXIT_FAILURE); |
| } |
| FP16_YYY_zero(&FP16aux1); |
| FP48_YYY_from_FP16(&FP48aux1,&FP16aux1); |
| if(FP48_YYY_equals(&FP48aux1,&FP48aux2)) |
| { |
| printf("ERROR comparing different FP48s\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| if(!FP48_YYY_iszilch(&FP48aux1) || FP48_YYY_iszilch(&FP48aux2) || FP48_YYY_isunity(&FP48aux1) || !FP48_YYY_isunity(&FP48aux2)) |
| { |
| printf("ERROR checking iszilch/isunity functions\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| fp = fopen(argv[1], "r"); |
| if (fp == NULL) |
| { |
| printf("ERROR opening test vector file\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| while (fgets(line, LINE_LEN, fp) != NULL) |
| { |
| i++; |
| // Read first FP48 and perform some tests on it |
| if (!strncmp(line,FP48_lines[0], strlen(FP48_lines[0]))) |
| { |
| len = strlen(FP48_lines[0]); |
| linePtr = line + len; |
| read_FP48_YYY(FP_48,linePtr); |
| |
| // Test setting functions |
| FP48_YYY_from_FP16(&FP48aux1,&FP_48->a); |
| if(!FP16_YYY_equals(&FP48aux1.a,&FP_48->a) || !FP16_YYY_iszilch(&FP48aux1.b) || !FP16_YYY_iszilch(&FP48aux1.c)) |
| { |
| printf("ERROR setting FP48 from a FP16, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| FP48_YYY_from_FP16s(&FP48aux1,&FP_48->a,&FP_48->b,&FP_48->c); |
| if(!FP48_YYY_equals(&FP48aux1,FP_48)) |
| { |
| printf("ERROR setting FP48 from three FP16s, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| |
| // Test octet conversion consistency |
| FP48_YYY_toOctet(&OCTaux,FP_48); |
| FP48_YYY_fromOctet(&FP48aux1,&OCTaux); |
| if(!FP48_YYY_equals(&FP48aux1,FP_48)) |
| { |
| printf("ERROR octet conversion consistency, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| FP48_YYY_copy(FP_48_frobs,FP_48); |
| for (k=1; k<16; k++) |
| { |
| FP48_YYY_copy(FP_48_frobs+k,FP_48_frobs+k-1); |
| FP48_YYY_frob(FP_48_frobs+k,&Frob,1); |
| } |
| } |
| // Read other FP48s. |
| for(k = 1; k<3; k++) |
| { |
| if (!strncmp(line,FP48_lines[k], strlen(FP48_lines[k]))) |
| { |
| len = strlen(FP48_lines[k]); |
| linePtr = line + len; |
| read_FP48_YYY(FP_48+k,linePtr); |
| } |
| } |
| // Read y for M-TYPE smul test |
| if (!strncmp(line,FP48smul_y_mtypeline, strlen(FP48smul_y_mtypeline))) |
| { |
| len = strlen(FP48smul_y_mtypeline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP_48_smul_y_mtype,linePtr); |
| } |
| // Read y for D-TYPE smul test |
| if (!strncmp(line,FP48smul_y_dtypeline, strlen(FP48smul_y_dtypeline))) |
| { |
| len = strlen(FP48smul_y_dtypeline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP_48_smul_y_dtype,linePtr); |
| } |
| // Test FP48_YYY_conj |
| if (!strncmp(line,FP48conjline, strlen(FP48conjline))) |
| { |
| len = strlen(FP48conjline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48conj,linePtr); |
| FP48_YYY_conj(&FP48aux1,FP_48); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48conj)) |
| { |
| printf("ERROR computing conjugate of FP48, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test multiplication and commutativity |
| if (!strncmp(line,FP48mulline, strlen(FP48mulline))) |
| { |
| len = strlen(FP48mulline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48mul,linePtr); |
| FP48_YYY_copy(&FP48aux1,FP_48); |
| FP48_YYY_mul(&FP48aux1,FP_48+1); |
| FP48_YYY_copy(&FP48aux2,FP_48+1); |
| FP48_YYY_mul(&FP48aux2,FP_48); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48mul) || !FP48_YYY_equals(&FP48aux2,&FP48mul)) |
| { |
| printf("ERROR computing multiplication of two FP48s, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test squaring |
| if (!strncmp(line,FP48squareline, strlen(FP48squareline))) |
| { |
| len = strlen(FP48squareline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48square,linePtr); |
| FP48_YYY_sqr(&FP48aux1,FP_48); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48square)) |
| { |
| printf("ERROR computing square of FP48, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test usquaring |
| if (!strncmp(line,FP48usquareline, strlen(FP48usquareline))) |
| { |
| len = strlen(FP48usquareline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48usquare,linePtr); |
| FP48_YYY_usqr(&FP48aux1,FP_48); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48usquare)) |
| { |
| printf("ERROR computing usquare of FP48, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test s-multiplication for D-TYPE |
| if (!strncmp(line,FP48smuldtypeline, strlen(FP48smuldtypeline))) |
| { |
| len = strlen(FP48smuldtypeline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48smul_dtype,linePtr); |
| FP48_YYY_copy(&FP48aux1,FP_48); |
| FP48_YYY_smul(&FP48aux1,&FP_48_smul_y_dtype,D_TYPE); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48smul_dtype)) |
| { |
| printf("ERROR computing s-multiplication for D-TYPE, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test s-multiplication for M-TYPE |
| if (!strncmp(line,FP48smulmtypeline, strlen(FP48smulmtypeline))) |
| { |
| len = strlen(FP48smulmtypeline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48smul_mtype,linePtr); |
| FP48_YYY_copy(&FP48aux1,FP_48); |
| FP48_YYY_smul(&FP48aux1,&FP_48_smul_y_mtype,M_TYPE); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48smul_mtype)) |
| { |
| printf("ERROR computing s-multiplication for M-TYPE, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test inverse fuction |
| if (!strncmp(line,FP48invline, strlen(FP48invline))) |
| { |
| len = strlen(FP48invline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48inv,linePtr); |
| FP48_YYY_inv(&FP48aux1,FP_48); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48inv)) |
| { |
| printf("ERROR computing inverse of a FP48, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Read BIGS |
| for(k=0; k<18; k++) |
| { |
| if (!strncmp(line,BIGsclines[k], strlen(BIGsclines[k]))) |
| { |
| len = strlen(BIGsclines[k]); |
| linePtr = line + len; |
| read_BIG_XXX(BIGsc[k],linePtr); |
| } |
| } |
| // Test power by a BIG |
| if (!strncmp(line,FP48powline, strlen(FP48powline))) |
| { |
| len = strlen(FP48powline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48pow,linePtr); |
| FP48_YYY_pow(&FP48aux1,FP_48,BIGsc[0]); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48pow)) |
| { |
| printf("ERROR computing power of a FP48 by a BIG, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test power by a small integer |
| if (!strncmp(line,FP48pinpowline, strlen(FP48pinpowline))) |
| { |
| len = strlen(FP48pinpowline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48pinpow,linePtr); |
| FP48_YYY_copy(&FP48aux1,FP_48); |
| FP48_YYY_pinpow(&FP48aux1,j,10); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48pinpow)) |
| { |
| printf("ERROR computing power of a FP48 by a small integer, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| j++; |
| } |
| // Test fucntion FP48_YYY_compow with small integer [< Modulus mod Curve_Order] |
| if (!strncmp(line,FP48compowsline, strlen(FP48compowsline))) |
| { |
| len = strlen(FP48compowsline); |
| linePtr = line + len; |
| read_FP16_YYY(&FP48compows,linePtr); |
| FP48_YYY_copy(&FP48aux1,FP_48+2); |
| FP48_YYY_compow(&FP16aux1,&FP48aux1,BIGsc[16],BIGsc[17]); |
| if(!FP16_YYY_equals(&FP16aux1,&FP48compows)) |
| { |
| printf("ERROR testing function FP48_compow with small integer, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test fucntion FP48_YYY_compow with big integer [> Modulus mod Curve_Order] |
| if (!strncmp(line,FP48compowline, strlen(FP48compowline))) |
| { |
| len = strlen(FP48compowline); |
| linePtr = line + len; |
| read_FP16_YYY(&FP48compow,linePtr); |
| FP48_YYY_copy(&FP48aux1,FP_48+2); |
| FP48_YYY_compow(&FP16aux1,&FP48aux1,BIGsc[0],BIGsc[17]); |
| if(!FP16_YYY_equals(&FP16aux1,&FP48compow)) |
| { |
| printf("ERROR testing function FP48_compow with big integer, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test function FP48_YYY_pow16 |
| if (!strncmp(line,FP48pow16line, strlen(FP48pow16line))) |
| { |
| len = strlen(FP48pow16line); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48pow16,linePtr); |
| FP48_YYY_pow16(&FP48aux1,FP_48_frobs,BIGsc); |
| |
| if(!FP48_YYY_equals(&FP48aux1,&FP48pow16)) |
| { |
| printf("ERROR testing function FP48pow16, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Raises an FP48 to the power of the internal modulus p, using the Frobenius constant f |
| if (!strncmp(line,FP48frobline, strlen(FP48frobline))) |
| { |
| len = strlen(FP48frobline); |
| linePtr = line + len; |
| read_FP48_YYY(&FP48frob,linePtr); |
| FP48_YYY_copy(&FP48aux1,FP_48); |
| FP48_YYY_frob(&FP48aux1,&Frob,1); |
| if(!FP48_YYY_equals(&FP48aux1,&FP48frob) || !FP48_YYY_equals(FP_48_frobs+1,&FP48frob)) |
| { |
| printf("ERROR in raising FP48 by an internal modulus p, using the Frobenius constant f, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| // Test computing trace of FP48 |
| if (!strncmp(line,FP16traceline, strlen(FP16traceline))) |
| { |
| len = strlen(FP16traceline); |
| linePtr = line + len; |
| read_FP16_YYY(&FP16trace,linePtr); |
| FP48_YYY_copy(&FP48aux1,&FP_48[0]); |
| FP48_YYY_trace(&FP16aux1,&FP48aux1); |
| if(!FP16_YYY_equals(&FP16aux1,&FP16trace)) |
| { |
| printf("ERROR computing trace of FP48, line %d\n",i); |
| exit(EXIT_FAILURE); |
| } |
| } |
| } |
| |
| fclose(fp); |
| |
| printf("SUCCESS TEST ARITMETIC OF FP48 PASSED\n"); |
| exit(EXIT_SUCCESS); |
| } |