1 // Pairing-Based Calculator.
2 // Mainly for demonstration purposes.
4 // It's times like these I wish C had garbage collection.
9 #include <unistd.h> //for getopt
14 #include "misc/darray.h"
15 #include "misc/symtab.h"
17 char *pbc_getline(const char *);
42 pe_expect_factor
= 100,
54 static int option_echo
= 0;
59 //TODO: dynamic allocation:
60 static char word
[1024];
66 typedef struct id_s
*id_ptr
;
68 id_ptr
id_new(char *id
) {
69 id_ptr res
= pbc_malloc(sizeof(struct id_s
));
70 res
->alloc
= strlen(id
) + 1;
71 res
->data
= pbc_malloc(res
->alloc
);
72 strcpy(res
->data
, id
);
76 void id_delete(id_ptr id
) {
86 typedef struct tree_s
*tree_ptr
;
88 tree_ptr
tree_new(int type
, void *data
) {
89 tree_ptr res
= pbc_malloc(sizeof(struct tree_s
));
92 darray_init(res
->child
);
96 static void delete_child(void *p
) {
100 void tree_delete(tree_ptr t
) {
101 darray_forall(t
->child
, delete_child
);
102 darray_clear(t
->child
);
114 static char *currentline
;
118 static void lex(void) {
127 if (!strchr(" \t\r\n", c
)) break;
135 //comments start with '#' and end at a newline
143 if (c
== '\n') break;
155 //string continues on next line
157 pbc_free(currentline
);
158 currentline
= pbc_getline(NULL
);
159 if (!currentline
) break;
160 if (option_echo
) puts(currentline
);
191 if (isalpha(c
) || c
== '_') {
198 if (isalnum(c
) || c
== '_') {
243 static int lastparseerror
;
244 static void setparseerror(int i
) {
248 static tree_ptr
parsesetexpr(void);
250 static tree_ptr
parseexprlist(tree_ptr t
) {
252 lex(); // expect lparen
253 if (tok_type
== t_rparen
) {
259 darray_append(t
->child
, c
);
261 if (tok_type
== t_rparen
) {
265 if (tok_type
!= t_comma
) {
266 setparseerror(pe_arglist
);
269 lex(); //expect comma
272 darray_append(t
->child
, c
);
276 static tree_ptr
parseprimitive(void) {
283 if (tok_type
== t_lparen
) {
284 if (parseexprlist(t
= tree_new(t_function
, id
))) {
290 return tree_new(t_id
, id
);
294 return tree_new(t_string
, id_new(word
));
299 if (tok_type
!= t_rparen
) {
301 setparseerror(pe_expect_rparen
);
309 return tree_new(t_int
, id
);
311 setparseerror(pe_expect_factor
);
316 static tree_ptr
parsepow(void) {
318 t1
= parseprimitive();
319 if (tok_type
== t_pow
) {
322 t2
= parseprimitive();
327 res
= tree_new(t_function
, id_new("pow"));
328 darray_append(res
->child
, t1
);
329 darray_append(res
->child
, t2
);
335 static tree_ptr
parsefactor(void) {
337 if (tok_type
== t_sub
) {
341 tree_ptr t1
= tree_new(t_function
, id_new("neg"));
342 darray_append(t1
->child
, t
);
350 static tree_ptr
parseterm(void) {
351 tree_ptr t1
, t2
, res
;
353 if (!res
) return NULL
;
363 t1
= tree_new(t_function
, id_new("mul"));
364 darray_append(t1
->child
, res
);
365 darray_append(t1
->child
, t2
);
375 t1
= tree_new(t_function
, id_new("div"));
376 darray_append(t1
->child
, res
);
377 darray_append(t1
->child
, t2
);
386 static tree_ptr
parseexpr(void) {
387 tree_ptr t1
, t2
, res
;
401 //t1 = tree_new(t_add, NULL);
402 t1
= tree_new(t_function
, id_new("add"));
403 darray_append(t1
->child
, res
);
404 darray_append(t1
->child
, t2
);
414 //t1 = tree_new(t_sub, NULL);
415 t1
= tree_new(t_function
, id_new("sub"));
416 darray_append(t1
->child
, res
);
417 darray_append(t1
->child
, t2
);
426 static tree_ptr
parsesetexpr(void) {
427 tree_ptr t1
, t2
, res
;
429 if (!t1
) return NULL
;
430 if (tok_type
== t_set
) {
437 res
= tree_new(t_set
, NULL
);
438 darray_append(res
->child
, t1
);
439 darray_append(res
->child
, t2
);
445 static void print_tree(tree_ptr t
) {
454 print_tree(t
->child
->item
[0]);
456 print_tree(t
->child
->item
[1]);
460 printf("%s", id
->data
);
464 printf("%s(", id
->data
);
465 for (i
=0; i
<t
->child
->count
; i
++) {
466 print_tree(t
->child
->item
[i
]);
467 if (i
< t
->child
->count
- 1) printf(", ");
478 static symtab_t builtin
;
484 typedef struct val_s
*val_ptr
;
486 static int lastruntimeerror
;
487 static val_ptr
newruntimeerror(int i
) {
488 val_ptr res
= pbc_malloc(sizeof(struct val_s
));
489 lastruntimeerror
= i
;
491 res
->data
= int_to_voidp(i
);
495 val_ptr
val_new(int type
, void *data
) {
496 val_ptr res
= pbc_malloc(sizeof(struct val_s
));
502 static void val_print(val_ptr v
) {
509 element_out_str(stdout
, 0, e
);
514 printf("pairing: G1bits=%d G2bits=%d GTbits=%d\n",
515 pairing_length_in_bytes_x_only_G1(pairing
) * 8,
516 pairing_length_in_bytes_x_only_G2(pairing
) * 8,
517 pairing_length_in_bytes_GT(pairing
) * 8);
521 field_out_info(stdout
, field
);
524 printf("%s", (char *) v
->data
);
527 printf("val type %d unknown\n", v
->type
);
532 val_ptr
val_copy(val_ptr v
) {
533 val_ptr res
= pbc_malloc(sizeof(struct val_s
));
535 if (v
->type
== t_element
) {
536 //current policy: always clear elements, always copy elements
537 res
->data
= pbc_malloc(sizeof(element_t
));
538 element_ptr e
= v
->data
;
539 element_init(res
->data
, e
->field
);
540 element_set(res
->data
, e
);
541 } else if (v
->type
== t_string
) {
542 res
->data
= pbc_strdup(v
->data
);
550 void val_delete(val_ptr v
) {
553 //current policy: always clear elements, always copy elements
554 element_clear(v
->data
);
567 printf("val_delete: case %d not handled: memory leak\n", v
->type
);
574 val_ptr (*f
)(darray_ptr
);
576 int type
[32]; //TODO: replace with darray? who needs more than 32 args?
579 typedef val_ptr (*fun
)(darray_ptr
);
581 static val_ptr
check_arg(darray_ptr arg
, int n
, ...) {
587 if (arg
->count
!= n
) {
588 printf("expect %d argument(s)\n", n
);
589 res
= newruntimeerror(re_badargcount
);
590 } else for (i
=0; i
<n
; i
++) {
591 int t
= va_arg(ap
, int);
592 val_ptr vp
= arg
->item
[i
];
594 printf("arg not type %d\n", t
);
595 return newruntimeerror(re_badarg
);
604 static val_ptr
f_pairing_get_group(
605 field_ptr (*get_group
)(pairing_ptr p
), darray_ptr arg
) {
607 res
= check_arg(arg
, 1, t_pairing
);
609 val_ptr a0
= arg
->item
[0];
610 pairing_ptr pairing
= a0
->data
;
611 res
= val_new(t_field
, get_group(pairing
));
615 static val_ptr
f_pairing_G1(darray_ptr arg
) {
616 field_ptr
getG1(pairing_ptr p
) { return p
->G1
; }
617 return f_pairing_get_group(getG1
, arg
);
620 static val_ptr
f_pairing_G2(darray_ptr arg
) {
621 field_ptr
getG2(pairing_ptr p
) { return p
->G2
; }
622 return f_pairing_get_group(getG2
, arg
);
625 static val_ptr
f_pairing_GT(darray_ptr arg
) {
626 field_ptr
getGT(pairing_ptr p
) { return p
->GT
; }
627 return f_pairing_get_group(getGT
, arg
);
630 static val_ptr
f_pairing_Zr(darray_ptr arg
) {
631 field_ptr
getZr(pairing_ptr p
) { return p
->Zr
; }
632 return f_pairing_get_group(getZr
, arg
);
635 static val_ptr
f_random(darray_ptr arg
) {
637 res
= check_arg(arg
, 1, t_field
);
639 val_ptr a0
= arg
->item
[0];
640 field_ptr f
= a0
->data
;
641 element_ptr e
= pbc_malloc(sizeof(element_t
));
644 res
= val_new(t_element
, e
);
648 static val_ptr
f_order(darray_ptr arg
) {
650 res
= check_arg(arg
, 1, t_field
);
652 val_ptr a0
= arg
->item
[0];
653 field_ptr f
= a0
->data
;
655 element_ptr e
= pbc_malloc(sizeof(element_t
));
657 element_set_mpz(e
, f
->order
);
658 res
= val_new(t_element
, e
);
662 static val_ptr
f_unary(
663 void (*unary
)(element_ptr
, element_ptr
), darray_ptr arg
) {
665 res
= check_arg(arg
, 1, t_element
);
667 val_ptr a0
= arg
->item
[0];
668 element_ptr e0
= a0
->data
;
669 element_ptr e
= pbc_malloc(sizeof(element_t
));
670 element_init(e
, e0
->field
);
672 res
= val_new(t_element
, e
);
676 static val_ptr
f_bin_op(
677 void (*binop
)(element_ptr
, element_ptr
, element_ptr
),
680 res
= check_arg(arg
, 2, t_element
, t_element
);
682 val_ptr a0
= arg
->item
[0];
683 val_ptr a1
= arg
->item
[1];
684 element_ptr e0
= a0
->data
;
685 element_ptr e1
= a1
->data
;
686 if (e0
->field
!= e1
->field
) {
687 printf("field mismatch!\n");
688 return newruntimeerror(re_fieldmismatch
);
690 element_ptr e
= pbc_malloc(sizeof(element_t
));
691 element_init(e
, e0
->field
);
693 res
= val_new(t_element
, e
);
698 static val_ptr
f_add(darray_ptr arg
) {
699 return f_bin_op(element_add
, arg
);
702 static val_ptr
f_mul(darray_ptr arg
) {
703 return f_bin_op(element_mul
, arg
);
706 static val_ptr
f_sub(darray_ptr arg
) {
707 return f_bin_op(element_sub
, arg
);
710 static val_ptr
f_div(darray_ptr arg
) {
711 return f_bin_op(element_div
, arg
);
714 static val_ptr
f_inv(darray_ptr arg
) {
715 return f_unary(element_invert
, arg
);
718 static val_ptr
f_neg(darray_ptr arg
) {
719 return f_unary(element_neg
, arg
);
722 static val_ptr
f_pow(darray_ptr arg
) {
724 res
= check_arg(arg
, 2, t_element
, t_element
);
726 val_ptr a0
= arg
->item
[0];
727 val_ptr a1
= arg
->item
[1];
728 element_ptr e0
= a0
->data
;
729 element_ptr e1
= a1
->data
;
730 element_ptr e
= pbc_malloc(sizeof(element_t
));
733 element_to_mpz(z
, e1
);
734 element_init(e
, e0
->field
);
735 element_pow_mpz(e
, e0
, z
);
736 res
= val_new(t_element
, e
);
741 static pairing_ptr current_pairing
;
742 static val_ptr
f_pairing(darray_ptr arg
) {
744 if (arg
->count
!= 2) {
745 printf("expect two arguments\n");
746 return newruntimeerror(re_badargcount
);
748 val_ptr a0
= arg
->item
[0];
749 val_ptr a1
= arg
->item
[1];
750 if (a0
->type
!= t_element
) {
751 printf("arg 1 not element!\n");
752 return newruntimeerror(re_badarg
);
754 if (a1
->type
!= t_element
) {
755 printf("arg 2 not element!\n");
756 return newruntimeerror(re_badarg
);
759 element_ptr e0
= a0
->data
;
760 element_ptr e1
= a1
->data
;
761 p
= e0
->field
->pairing
;
762 if (e0
->field
!= p
->G1
) {
763 printf("arg 1 not from G1!\n");
764 return newruntimeerror(re_badarg
);
766 if (e1
->field
!= p
->G2
) {
767 printf("arg 2 not from G2!\n");
768 return newruntimeerror(re_badarg
);
770 element_ptr e
= pbc_malloc(sizeof(element_t
));
771 element_init(e
, p
->GT
);
772 pairing_apply(e
, e0
, e1
, p
);
773 res
= val_new(t_element
, e
);
777 static val_ptr
execute_tree(tree_ptr t
) {
788 v
= symtab_at(var
, id
->data
);
790 return newruntimeerror(re_varnotfound
);
794 t1
= t
->child
->item
[0];
795 if (t1
->type
!= t_id
) {
796 return newruntimeerror(re_badlvalue
);
798 t2
= t
->child
->item
[1];
799 v
= execute_tree(t2
);
800 if (v
->type
== t_err
) return v
;
802 // clear what's there first
803 if ((res
= symtab_at(var
, id
->data
))) {
806 symtab_put(var
, v
, id
->data
);
807 v
= symtab_at(var
, id
->data
);
811 fn
= symtab_at(builtin
, id
->data
);
813 return newruntimeerror(re_funnotfound
);
816 for (i
=0; i
<t
->child
->count
; i
++) {
817 v
= execute_tree(t
->child
->item
[i
]);
818 if (v
->type
== t_err
) {
819 darray_forall(arg
, (void (*)(void *)) val_delete
);
822 darray_append(arg
, v
);
825 for (i
=0; i
<arg
->count
; i
++) {
826 val_delete(arg
->item
[i
]);
835 for (cp
= id
->data
; *cp
; cp
++) {
836 mpz_mul_ui(z
, z
, 10);
837 mpz_add_ui(z
, z
, *cp
- '0');
839 element_ptr e
= pbc_malloc(sizeof(element_t
));
841 element_set_mpz(e
, z
);
843 return val_new(t_element
, e
);
846 return val_new(t_string
, pbc_strdup(id
->data
));
848 return newruntimeerror(re_unimplemented
);
852 static void parseline(void) {
857 if (tok_type
== t_none
) return;
866 if (v
->type
== t_err
) {
867 printf("runtime error (error code = %d)\n", lastruntimeerror
);
869 if (t
->type
!= t_set
) val_print(v
);
875 printf("parse error (error code = %d)\n", lastparseerror
);
879 static char *aparam
=
881 "q 8780710799663312522437781984754049815806883199414208211028653399266475630880222957078625179422662221423155858769582317459277713367317481324925129998224791\n"
882 "h 12016012264891146079388821366740534204802954401251311822919615131047207289359704531102844802183906537786776\n"
883 "r 730750818665451621361119245571504901405976559617\n"
889 static char *dparam
=
891 "q 625852803282871856053922297323874661378036491717\n"
892 "n 625852803282871856053923088432465995634661283063\n"
894 "r 208617601094290618684641029477488665211553761021\n"
895 "a 581595782028432961150765424293919699975513269268\n"
896 "b 517921465817243828776542439081147840953753552322\n"
898 "nk 60094290356408407130984161127310078516360031868417968262992864809623507269833854678414046779817844853757026858774966331434198257512457993293271849043664655146443229029069463392046837830267994222789160047337432075266619082657640364986415435746294498140589844832666082434658532589211525696\n"
899 "hk 1380801711862212484403205699005242141541629761433899149236405232528956996854655261075303661691995273080620762287276051361446528504633283152278831183711301329765591450680250000592437612973269056\n"
900 "coeff0 472731500571015189154958232321864199355792223347\n"
901 "coeff1 352243926696145937581894994871017455453604730246\n"
902 "coeff2 289113341693870057212775990719504267185772707305\n"
903 "nqr 431211441436589568382088865288592347194866189652\n";
905 static char *eparam
=
907 "q 7245986106510086080714203333362098431608853335867425877960916928496629182991629664903654100214900946450053872786629995869445693724001299041657434948257845644905153122838458864000479326695430719258600053239930483226650953770354174712511646273516974069245462534034085895319225452125649979474047163305307830001\n"
908 "r 730750862221594424981965739670091261094297337857\n"
909 "h 13569343110918781839835249021482970252603216587988030044836106948825516930173270978617489032334001006615524543925753725725046733884363846960470444404747241287743773746682188521738728797153760275116924829183670000\n"
910 "a 7130970454025799000067946137594446075551569949583815943390108723282396973737794273397246892274981883807989525599540630855644968426794929215599380425269625872763801485968007136000471718335185787206876242871042697778608875139078711621836858237429403052273312335081163896980825048123655535355411494046493419999\n"
911 "b 7169309004853894693616698536183663527570664411678352588247044791687141043489072737232715961588288238022010974661903752526911876859197052490952065266265699130144252031591491045333807587788600764557450846327338626261289568016170532652061787582791926724597362401398804563093625182790987016728290050466098223333\n"
917 static char *fparam
=
919 "q 205523667896953300194896352429254920972540065223\n"
920 "r 205523667896953300194895899082072403858390252929\n"
921 "b 40218105156867728698573668525883168222119515413\n"
922 "beta 115334401956802802075595682801335644058796914268\n"
923 "alpha0 191079354656274778837764015557338301375963168470\n"
924 "alpha1 71445317903696340296199556072836940741717506375\n";
926 static char *gparam
=
928 "q 503189899097385532598615948567975432740967203\n"
929 "n 503189899097385532598571084778608176410973351\n"
931 "r 503189899097385532598571084778608176410973351\n"
932 "a 465197998498440909244782433627180757481058321\n"
933 "b 463074517126110479409374670871346701448503064\n"
935 "nk 1040684643531490707494989587381629956832530311976146077888095795458709511789670022388326295177424065807612879371896982185473788988016190582073591316127396374860265835641044035656044524481121528846249501655527462202999638159773731830375673076317719519977183373353791119388388468745670818193868532404392452816602538968163226713846951514831917487400267590451867746120591750902040267826351982737642689423713163967384383105678367875981348397359466338807\n"
936 "hk 4110127713690841149713310614420858884651261781185442551927080083178682965171097172366598236129731931693425629387502221804555636704708008882811353539555915064049685663790355716130262332064327767695339422323460458479884756000782939428852120522712008037615051139080628734566850259704397643028017435446110322024094259858170303605703280329322675124728639532674407\n"
937 "coeff0 67343110967802947677845897216565803152319250\n"
938 "coeff1 115936772834120270862756636148166314916823221\n"
939 "coeff2 87387877425076080433559927080662339215696505\n"
940 "coeff3 433223145899090928132052677121692683015058909\n"
941 "coeff4 405367866213598664862417230702935310328613596\n"
942 "nqr 22204504160560785687198080413579021865783099\n";
944 static pairing_t pairing_A
, pairing_D
, pairing_E
, pairing_F
, pairing_G
;
946 static void set_pairing_groups(pairing_ptr p
) {
947 symtab_put(var
, val_new(t_field
, p
->G1
), "G1");
948 symtab_put(var
, val_new(t_field
, p
->G2
), "G2");
949 symtab_put(var
, val_new(t_field
, p
->GT
), "GT");
950 symtab_put(var
, val_new(t_field
, p
->Zr
), "Zr");
951 symtab_put(var
, val_new(t_pairing
, p
), "current_pairing");
955 static val_ptr
f_init_pairing(darray_ptr arg
) {
958 res
= check_arg(arg
, 1, t_pairing
);
961 val_ptr a0
= arg
->item
[0];
962 pairing_ptr p
= a0
->data
;
963 set_pairing_groups(p
);
967 static val_ptr
f_nextprime(darray_ptr arg
) {
971 res
= check_arg(arg
, 1, t_element
);
973 val_ptr a0
= arg
->item
[0];
974 element_ptr e0
= a0
->data
;
975 if (e0
->field
!= Z
) {
976 printf("arg not integer!\n");
977 return newruntimeerror(re_badarg
);
979 element_ptr e
= pbc_malloc(sizeof(element_t
));
982 element_to_mpz(p
, e0
);
984 element_set_mpz(e
, p
);
985 res
= val_new(t_element
, e
);
990 static val_ptr
f_brute_force_dlog(darray_ptr arg
) {
992 res
= check_arg(arg
, 2, t_element
, t_element
);
994 val_ptr a0
= arg
->item
[0];
995 val_ptr a1
= arg
->item
[1];
996 element_ptr e0
= a0
->data
;
997 element_ptr e1
= a1
->data
;
998 if (e0
->field
!= e1
->field
) {
999 printf("arg field mismatch!\n");
1000 return newruntimeerror(re_badarg
);
1002 element_ptr e
= pbc_malloc(sizeof(element_t
));
1004 element_dlog_brute_force(e
, e0
, e1
);
1005 res
= val_new(t_element
, e
);
1008 static val_ptr
f_pollard_rho(darray_ptr arg
) {
1010 res
= check_arg(arg
, 3, t_element
, t_element
, t_field
);
1011 if (res
) return res
;
1012 val_ptr a0
= arg
->item
[0];
1013 val_ptr a1
= arg
->item
[1];
1014 val_ptr a2
= arg
->item
[2];
1015 element_ptr e0
= a0
->data
;
1016 element_ptr e1
= a1
->data
;
1017 if (e0
->field
!= e1
->field
) {
1018 printf("arg field mismatch!\n");
1019 return newruntimeerror(re_badarg
);
1021 field_ptr f
= a2
->data
;
1022 element_ptr e
= pbc_malloc(sizeof(element_t
));
1024 element_dlog_pollard_rho(e
, e0
, e1
);
1025 res
= val_new(t_element
, e
);
1029 static val_ptr
f_zz(darray_ptr arg
) {
1032 res
= check_arg(arg
, 1, t_element
);
1033 if (res
) return res
;
1034 val_ptr a0
= arg
->item
[0];
1035 element_ptr e0
= a0
->data
;
1036 if (e0
->field
!= Z
) {
1037 printf("arg not integer!\n");
1038 return newruntimeerror(re_badarg
);
1040 field_ptr f
= pbc_malloc(sizeof(field_t
));
1042 element_to_mpz(p
, e0
);
1043 field_init_fp(f
, p
);
1044 res
= val_new(t_field
, f
);
1049 static val_ptr
f_gen_A(darray_ptr arg
) {
1053 res
= check_arg(arg
, 2, t_element
, t_element
);
1054 if (res
) return res
;
1055 val_ptr a0
= arg
->item
[0];
1056 val_ptr a1
= arg
->item
[1];
1057 element_ptr e0
= a0
->data
;
1058 if (e0
->field
!= Z
) {
1059 printf("arg not integer!\n");
1060 return newruntimeerror(re_badarg
);
1062 element_ptr e1
= a1
->data
;
1063 if (e1
->field
!= Z
) {
1064 printf("arg not integer!\n");
1065 return newruntimeerror(re_badarg
);
1069 element_to_mpz(rbits
, e0
);
1070 element_to_mpz(qbits
, e1
);
1071 //TODO: check rbits and qbits aren't too big
1073 pbc_param_init_a_gen(param
, mpz_get_ui(rbits
), mpz_get_ui(qbits
));
1074 p
= pbc_malloc(sizeof(pairing_t
));
1075 pairing_init_pbc_param(p
, param
);
1076 res
= val_new(t_pairing
, p
);
1079 pbc_param_clear(param
);
1083 static val_ptr
f_fromZZ(darray_ptr arg
) {
1085 res
= check_arg(arg
, 2, t_element
, t_field
);
1086 if (res
) return res
;
1087 val_ptr a0
= arg
->item
[0];
1088 val_ptr a1
= arg
->item
[1];
1089 element_ptr e
= a0
->data
;
1090 field_ptr f
= a1
->data
;
1091 if (e
->field
!= Z
) {
1092 printf("arg not integer!\n");
1093 return newruntimeerror(re_badarg
);
1095 element_ptr e1
= pbc_malloc(sizeof(element_t
));
1096 element_init(e1
, f
);
1097 element_set_mpz(e1
, e
->data
);
1098 res
= val_new(t_element
, e1
);
1102 static val_ptr
f_fromstr(darray_ptr arg
) {
1104 res
= check_arg(arg
, 2, t_string
, t_field
);
1105 if (res
) return res
;
1106 val_ptr a0
= arg
->item
[0];
1107 val_ptr a1
= arg
->item
[1];
1108 field_ptr f
= a1
->data
;
1109 element_ptr e1
= pbc_malloc(sizeof(element_t
));
1110 element_init(e1
, f
);
1111 element_set_str(e1
, a0
->data
, 0);
1112 res
= val_new(t_element
, e1
);
1116 /* I'll probably never finish this :(
1117 static val_ptr f_index_calculus(darray_ptr arg) {
1119 res = check_arg(arg, 2, t_element, t_element);
1120 if (res) return res;
1121 val_ptr a0 = arg->item[0];
1122 val_ptr a1 = arg->item[1];
1123 element_ptr e0 = a0->data;
1124 element_ptr e1 = a1->data;
1125 element_ptr e = pbc_malloc(sizeof(element_t));
1128 //TODO: check e0, e1 are from an integer mod ring
1134 mpz_sub_ui(q1, e0->field->order, 1);
1137 element_to_mpz(g, e0);
1138 element_to_mpz(h, e1);
1139 pbc_mpz_index_calculus(x, g, h, q1);
1140 element_set_mpz(e, x);
1141 res = val_new(t_element, e);
1150 int main(int argc
, char **argv
) {
1152 int c
= getopt(argc
, argv
, "e");
1159 fprintf(stderr
, "unrecognized option: %c\n", c
);
1165 symtab_init(builtin
);
1167 pairing_init_set_str(pairing_A
, aparam
);
1168 pairing_init_set_str(pairing_D
, dparam
);
1169 pairing_init_set_str(pairing_E
, eparam
);
1170 pairing_init_set_str(pairing_F
, fparam
);
1171 pairing_init_set_str(pairing_G
, gparam
);
1172 symtab_put(var
, val_new(t_pairing
, pairing_A
), "A");
1173 symtab_put(var
, val_new(t_pairing
, pairing_D
), "D");
1174 symtab_put(var
, val_new(t_pairing
, pairing_E
), "E");
1175 symtab_put(var
, val_new(t_pairing
, pairing_F
), "F");
1176 symtab_put(var
, val_new(t_pairing
, pairing_G
), "G");
1178 set_pairing_groups(pairing_A
);
1180 symtab_put(builtin
, f_init_pairing
, "init_pairing");
1181 symtab_put(builtin
, f_pairing_G1
, "get_G1");
1182 symtab_put(builtin
, f_pairing_G2
, "get_G2");
1183 symtab_put(builtin
, f_pairing_GT
, "get_GT");
1184 symtab_put(builtin
, f_pairing_Zr
, "get_Zr");
1185 symtab_put(builtin
, f_random
, "random");
1186 symtab_put(builtin
, f_random
, "rand");
1187 symtab_put(builtin
, f_random
, "rnd");
1188 symtab_put(builtin
, f_order
, "order");
1189 symtab_put(builtin
, f_order
, "ord");
1190 symtab_put(builtin
, f_neg
, "neg");
1191 symtab_put(builtin
, f_sub
, "sub");
1192 symtab_put(builtin
, f_add
, "add");
1193 symtab_put(builtin
, f_pow
, "pow");
1194 symtab_put(builtin
, f_mul
, "mul");
1195 symtab_put(builtin
, f_inv
, "inv");
1196 symtab_put(builtin
, f_inv
, "invert");
1197 symtab_put(builtin
, f_div
, "div");
1198 symtab_put(builtin
, f_pairing
, "pairing");
1199 symtab_put(builtin
, f_nextprime
, "nextprime");
1200 symtab_put(builtin
, f_brute_force_dlog
, "element_dlog_brute_force");
1201 symtab_put(builtin
, f_pollard_rho
, "element_dlog_pollard_rho");
1202 //symtab_put(builtin, f_index_calculus, "index_calculus");
1203 symtab_put(builtin
, f_zz
, "ZZ");
1204 symtab_put(builtin
, f_gen_A
, "gen_A");
1205 symtab_put(builtin
, f_fromZZ
, "fromZZ");
1206 symtab_put(builtin
, f_fromstr
, "fromstr");
1210 fprintf(stderr
, "pbc\n");
1213 currentline
= pbc_getline(NULL
);
1214 if (!currentline
) break;
1215 if (option_echo
) puts(currentline
);
1216 lexcp
= currentline
;