├── src ├── demo │ ├── dune-project │ ├── dune │ ├── Makefile │ ├── .merlin │ └── test.ml ├── Secp256k1.mli ├── dune ├── META ├── Ecdsa.mli ├── Ecdh.mli ├── Ecdh.ml ├── Makefile ├── Ecdsa.ml ├── EccPrimitives.mli ├── EccPrimitives.ml └── Secp256k1.ml ├── dune-project ├── report ├── add.png ├── .DS_Store ├── double.png ├── report.pdf ├── pyrforos.jpg ├── report.out ├── ocamldoc.sty ├── report.toc ├── report.pyg └── report.tex ├── doc ├── ocamldoc.pdf └── ocamldoc.tex ├── presentation ├── add.png ├── double.png ├── slides.pdf ├── ocaml_logo.png ├── random_number.png ├── ocamldoc.sty └── slides.tex ├── .gitignore ├── README.md ├── ecc.opam └── LICENSE /src/demo/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 1.6) 2 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 1.8) 2 | (name ecc) 3 | -------------------------------------------------------------------------------- /src/Secp256k1.mli: -------------------------------------------------------------------------------- 1 | open EccPrimitives 2 | 3 | module Secp256k1 : Curve 4 | -------------------------------------------------------------------------------- /src/demo/dune: -------------------------------------------------------------------------------- 1 | (tests 2 | (names test) 3 | (libraries ecc cryptokit)) 4 | -------------------------------------------------------------------------------- /report/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/report/add.png -------------------------------------------------------------------------------- /doc/ocamldoc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/doc/ocamldoc.pdf -------------------------------------------------------------------------------- /report/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/report/.DS_Store -------------------------------------------------------------------------------- /report/double.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/report/double.png -------------------------------------------------------------------------------- /report/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/report/report.pdf -------------------------------------------------------------------------------- /report/pyrforos.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/report/pyrforos.jpg -------------------------------------------------------------------------------- /src/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name ecc) 3 | (public_name ecc) 4 | (libraries zarith sha)) -------------------------------------------------------------------------------- /presentation/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/presentation/add.png -------------------------------------------------------------------------------- /presentation/double.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/presentation/double.png -------------------------------------------------------------------------------- /presentation/slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/presentation/slides.pdf -------------------------------------------------------------------------------- /presentation/ocaml_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/presentation/ocaml_logo.png -------------------------------------------------------------------------------- /presentation/random_number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgian/ECC-OCaml/HEAD/presentation/random_number.png -------------------------------------------------------------------------------- /src/META: -------------------------------------------------------------------------------- 1 | description = "Elliptic Curve Cryptography primitives" 2 | requires = "zarith sha" 3 | version = "1.0.0" 4 | archive(byte) = "ecc.cma" 5 | archive(native) = "ecc.cmxa" 6 | -------------------------------------------------------------------------------- /src/Ecdsa.mli: -------------------------------------------------------------------------------- 1 | open EccPrimitives 2 | 3 | module Ecdsa : 4 | functor (C : Curve) -> 5 | sig 6 | val sign : string -> Z.t -> Z.t * Z.t 7 | val verify : string -> Z.t * Z.t -> point -> bool 8 | end -------------------------------------------------------------------------------- /src/demo/Makefile: -------------------------------------------------------------------------------- 1 | default: test 2 | 3 | build: 4 | dune build test.exe --profile release 5 | test: 6 | dune runtest -f 7 | make clean 8 | clean: 9 | rm -f *.cm[iox] *~ .*~ *.o *.a #*# 10 | rm -rf _build 11 | dune clean 12 | -------------------------------------------------------------------------------- /src/Ecdh.mli: -------------------------------------------------------------------------------- 1 | open EccPrimitives 2 | 3 | module Ecdh : 4 | functor (C : Curve) -> 5 | sig 6 | val validate_pkey : point -> bool 7 | val create_keys : unit -> point * Z.t 8 | val create_session_key : point -> Z.t -> string 9 | val pubkey_of_seckey : Z.t -> point 10 | end -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | .merlin 3 | *.pk 4 | *.sk 5 | *.swp 6 | *.*.swp 7 | *.cmx 8 | *.cmi 9 | *.o 10 | *.log 11 | *.aux 12 | *.aux 13 | *.dvi 14 | *.gz 15 | *.pk 16 | *.sk 17 | *.msg 18 | *.nav 19 | *.out 20 | *.snm 21 | *.*.gz 22 | *.toc 23 | *.vrb 24 | *.sty 25 | *.a 26 | *.cma 27 | *.cmo 28 | *.o 29 | *.cmxa 30 | .depend.input 31 | .depend 32 | .DS_Store 33 | exchange_dh 34 | register_dh 35 | sign 36 | verify 37 | -------------------------------------------------------------------------------- /src/demo/.merlin: -------------------------------------------------------------------------------- 1 | EXCLUDE_QUERY_DIR 2 | B /Users/mb/.opam/default/lib/cryptokit 3 | B /Users/mb/.opam/default/lib/ecc 4 | B /Users/mb/.opam/default/lib/sha 5 | B /Users/mb/.opam/default/lib/zarith 6 | B /usr/local/lib/ocaml 7 | B _build/default/.test.eobjs 8 | S /Users/mb/.opam/default/lib/cryptokit 9 | S /Users/mb/.opam/default/lib/ecc 10 | S /Users/mb/.opam/default/lib/sha 11 | S /Users/mb/.opam/default/lib/zarith 12 | S /usr/local/lib/ocaml 13 | S . 14 | FLG -w @a-4-29-40-41-42-44-45-48-58-59-60-40 -strict-sequence -strict-formats -short-paths -keep-locs 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ECC-OCaml 2 | ========= 3 | 4 | Elliptic Curves Cryptography for OCaml. 5 | This library provides the basic arithmetic operations in elliptic curves over finite prime fields (over finite bit fields coming soon :) 6 | as well as functions for Elliptic Curve digital signature algorithm and Elliptic Curve Diffie-Hellman key exchange protocol. 7 | 8 | 9 | Dependencies 10 | ------------ 11 | * [*OCaml*](http://ocaml.org/install.html) version 4.0.0 or newer 12 | * [*Zarith*](http://forge.ocamlcore.org/projects/zarith) or via OPAM [here](http://opam.ocaml.org/pkg/zarith/1.2/) 13 | * [*SHA*](https://github.com/vincenthz/ocaml-sha) or via OPAM [here](http://opam.ocaml.org/pkg/sha/1.9/) 14 | 15 | To compile and install the library: 16 | ---------------------------------- 17 | 18 | $ cd src 19 | $ make 20 | $ make install 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ecc.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | name: "ecc" 3 | version: "1.0.0" 4 | maintainer: "jose.pascoal@ubi.pt" 5 | authors: "Nick Giannarakis 6 | Zoe Paraskevopoulou " 7 | homepage: "https://github.com/jcfpascoal10/ECC-OCaml" 8 | dev-repo: "git+https://github.com/jcfpascoal10/ECC-OCaml.git" 9 | bug-reports: "https://github.com/nickgian/ECC-OCaml/issues" 10 | license: "MIT" 11 | doc: "https://github.com/jcfpascoal10/ECC-OCaml/tree/master/doc" 12 | 13 | build: [ 14 | ["dune" "subst"] {pinned} 15 | ["dune" "build" "-p" name "-j" jobs] 16 | ["dune" "runtest" "-p" name "-j" jobs] {with-test} 17 | ] 18 | 19 | depends: [ 20 | "dune" {build} 21 | "ocaml" {>= "4.02.3"} 22 | "zarith" 23 | "sha" 24 | ] 25 | 26 | synopsis: "Elliptic Curves Cryptography for OCaml" 27 | 28 | description: """ 29 | Elliptic Curves Cryptography for OCaml. This library provides the basic 30 | arithmetic operations in elliptic curves over finite prime fields, 31 | as well as functions for Elliptic Curve digital signature algorithm and 32 | Elliptic Curve Diffie-Hellman key exchange protocol. 33 | """ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Nick Giannarakis and Zoe Paraskevopoulou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | -------------------------------------------------------------------------------- /src/Ecdh.ml: -------------------------------------------------------------------------------- 1 | open EccPrimitives 2 | 3 | module Ecdh = 4 | functor (C: Curve) -> 5 | struct 6 | open C 7 | (* Check that the public key is a valid public key*) 8 | let validate_pkey pk = 9 | match pk with 10 | | Infinity -> false 11 | | Point (pk_x, pk_y) -> 12 | let curve_p = get_field in 13 | if (verify_range pk_x Z.zero Z.(curve_p - one)) && 14 | (verify_range pk_y Z.zero Z.(curve_p - one)) && 15 | is_point pk && 16 | (multiply_point pk get_n ) = Infinity 17 | then 18 | true 19 | else false 20 | 21 | (*Create public and secret key*) 22 | let rec create_keys() = 23 | let sk = random_big_int get_n in 24 | let pk = multiply_point get_g sk in 25 | if validate_pkey pk then 26 | (pk, sk) 27 | else 28 | create_keys() 29 | 30 | (* Creates a session key from the other party's public key and the user's 31 | * secret key *) 32 | 33 | let create_session_key pk sk = 34 | let common = multiply_point pk sk in 35 | match common with 36 | | Infinity -> raise Error 37 | | Point(x, _) -> 38 | Sha1.to_hex (Sha1.string (Z.to_string x)) 39 | 40 | (* Creates public key from secret key *) 41 | let pubkey_of_seckey sk = 42 | multiply_point get_g sk 43 | end;; 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | PACKAGES = zarith,sha 2 | MLFILES = EccPrimitives.ml Secp256k1.ml Ecdsa.ml Ecdh.ml 3 | MLIFILES = EccPrimitives.mli Secp256k1.mli Ecdsa.mli Ecdh.mli 4 | OCAMLC = ocamlc 5 | OCAMLOPT = ocamlopt 6 | OCAMLDEP = ocamldep 7 | OCAMLFIND = ocamlfind 8 | NAME = ecc 9 | 10 | OBJS = $(MLFILES:.ml=.cmo) 11 | CMIS = $(MLIFILES:.mli=.cmi) 12 | CMAS = $(MLFILES:.ml=.cma) 13 | OPTOBJS = $(MLFILES:.ml=.cmx) 14 | INSTALL= META $(NAME).a $(NAME).cma $(NAME).cmxa $(CMIS) $(MLIS) $(OPTOBJS) 15 | 16 | default: depend $(NAME) 17 | 18 | $(NAME): $(OBJS) $(OPTOBJS) 19 | $(OCAMLC) -a -o $@.cma $(OBJS) 20 | $(OCAMLOPT) -a -o $@.cmxa $(OPTOBJS) 21 | 22 | %.cmi: %.mli 23 | $(OCAMLFIND) $(OCAMLC) -package $(PACKAGES) -c $< -o $@ 24 | 25 | %.cmo: %.ml 26 | $(OCAMLFIND) $(OCAMLC) -package $(PACKAGES) -c $< -o $@ 27 | 28 | %.cmx: %.ml 29 | $(OCAMLFIND) $(OCAMLOPT) -package $(PACKAGES) -c $< -o $@ 30 | 31 | 32 | clean: 33 | rm -f *.cm[ioxa] *~ .*~ *.o *.a #*# 34 | rm -f *.cmxa 35 | rm -rf _build 36 | dune clean 37 | 38 | -include .depend 39 | 40 | depend: $(MLFILES) $(MLIFILES) 41 | $(OCAMLDEP) $^ > .depend 42 | 43 | install: $(INSTALL) 44 | $(OCAMLFIND) install $(NAME) $(INSTALL) 45 | 46 | uninstall: 47 | $(OCAMLFIND) remove $(NAME) 48 | 49 | test: 50 | make 51 | make uninstall 52 | make install 53 | cd demo && make build 54 | cd demo && make test 55 | make clean 56 | make uninstall 57 | -------------------------------------------------------------------------------- /src/Ecdsa.ml: -------------------------------------------------------------------------------- 1 | open EccPrimitives 2 | 3 | module Ecdsa = 4 | functor (C : Curve) -> 5 | struct 6 | open C 7 | 8 | let rec sign m sk = 9 | let curve_n = get_n in 10 | let curve_g = get_g in 11 | let k = random_big_int curve_n in (* do we need to check that k is invertible ? *) 12 | match multiply_point curve_g k with 13 | | Infinity -> sign m sk 14 | | Point (x1, _) -> 15 | let r = Z.(x1 mod curve_n) in 16 | if r = Z.zero then sign m sk 17 | else 18 | let inv_k = (Z.invert k curve_n) in 19 | let hash_m = Sha1.to_hex (Sha1.string m) in 20 | let e = Z.of_string_base 16 hash_m in 21 | let s = Z.((inv_k * (e + sk * r)) mod (curve_n)) in 22 | if s = Z.zero then sign m sk 23 | else (r, s) 24 | 25 | let verify m (r, s) pk = 26 | let curve_n = get_n in 27 | let curve_g = get_g in 28 | let upper = Z.(curve_n - one) in 29 | match (verify_range r Z.one upper, verify_range r Z.one upper) with 30 | | (true, true) -> 31 | let hash_m = Sha1.to_hex (Sha1.string m) in 32 | let e = Z.of_string_base 16 hash_m in 33 | let w = Z.invert s curve_n in 34 | let u1 = Z.((e*w) mod curve_n) in 35 | let u2 = Z.((r*w) mod curve_n) in 36 | let u1G = multiply_point curve_g u1 in 37 | let u2Q = multiply_point pk u2 in 38 | let x = add_point u1G u2Q in 39 | (match x with 40 | | Infinity -> false 41 | | Point (x1, _) -> Z.((x1 mod curve_n) = r)) 42 | | (_, _) -> false 43 | end 44 | -------------------------------------------------------------------------------- /src/EccPrimitives.mli: -------------------------------------------------------------------------------- 1 | exception Invalid_point 2 | exception Error 3 | 4 | type point = Infinity | Point of Z.t * Z.t 5 | type octet = string 6 | 7 | val point_to_string : point -> string 8 | val integer_of_octet : string -> Z.t 9 | val of_octet : string -> Z.t -> Z.t -> Z.t -> point 10 | val inverse : Z.t -> Z.t -> Z.t 11 | val int_pow : int -> int -> int 12 | val neg_mod : Z.t -> Z.t -> Z.t 13 | val random_big_int : Z.t -> Z.t 14 | val verify_range : Z.t -> Z.t -> Z.t -> bool 15 | 16 | val hexstring_to_string : string -> string 17 | val hexstring_of_string : string -> string 18 | 19 | val string_of_point_uncompressed : point -> string 20 | val string_of_point_compressed : point -> string 21 | 22 | val bytes_of_point_uncompressed : point -> string 23 | val bytes_of_point_compressed : point -> string 24 | 25 | module type Specs = 26 | sig 27 | type t 28 | val curve : t 29 | val field : Z.t 30 | val g : point 31 | val n : Z.t 32 | val a : Z.t 33 | val b : Z.t 34 | val points : point list 35 | end 36 | 37 | module type Curve = 38 | sig 39 | val get_field : Z.t 40 | val get_g : point 41 | val get_n : Z.t 42 | val get_a : Z.t 43 | val get_b : Z.t 44 | val get_points : point list 45 | val is_point : point -> bool 46 | val inverse_point : point -> point 47 | val double_point : point -> point 48 | val add_point : point -> point -> point 49 | val double_and_add : point -> Z.t -> point 50 | val montogomery_ladders : point -> Z.t -> point 51 | val multiply_point : point -> Z.t -> point 52 | val multiscalar_mul : point -> Z.t list -> point list -> point 53 | end 54 | 55 | module Make_Curve : functor (S : Specs) -> Curve 56 | -------------------------------------------------------------------------------- /report/report.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [1][-]{section.1}{Ελλειπτικές καμπύλες}{}% 1 2 | \BOOKMARK [2][-]{subsection.1.1}{Εισαγωγή}{section.1}% 2 3 | \BOOKMARK [2][-]{subsection.1.2}{Ελλειπτικές καμπύλες στο R}{section.1}% 3 4 | \BOOKMARK [3][-]{subsubsection.1.2.1}{Ορισμένες πράξεις σε ελλειπτικές καμπύλες πάνω στο R}{subsection.1.2}% 4 5 | \BOOKMARK [2][-]{subsection.1.3}{Ελλειπτικές καμπύλες πάνω από το σώμα Fp.}{section.1}% 5 6 | \BOOKMARK [3][-]{subsubsection.1.3.1}{Ορισμένες πράξεις σε σε ελλειπτικές καμπύλες πάνω στο Fp}{subsection.1.3}% 6 7 | \BOOKMARK [2][-]{subsection.1.4}{Ελλειπτικές καμπύλες πάνω από το σώμα F2m.}{section.1}% 7 8 | \BOOKMARK [1][-]{section.2}{Το πρόβλημα του διακριτού λογαρίθμου σε ελλειπτικές καμπύλες \(ECDLP\)}{}% 8 9 | \BOOKMARK [2][-]{subsection.2.1}{Βαθμωτός Πολλαπλασιασμός}{section.2}% 9 10 | \BOOKMARK [2][-]{subsection.2.2}{ECDLP}{section.2}% 10 11 | \BOOKMARK [2][-]{subsection.2.3}{Elliptic\040curve\040Diffie-Hellman\040\(ECDH\)}{section.2}% 11 12 | \BOOKMARK [2][-]{subsection.2.4}{Elliptic\040curve\040digital\040signature\040algorithm\040\(ECDSA\)}{section.2}% 12 13 | \BOOKMARK [1][-]{section.3}{Υλοποίηση ενός συστήματος κρυπτογραφίας βασισμένο σε ελλειπτικές καμπύλες}{}% 13 14 | \BOOKMARK [2][-]{subsection.3.1}{Πλεονεκτήματα χρήσης}{section.3}% 14 15 | \BOOKMARK [2][-]{subsection.3.2}{Επιλογή παραμέτρων}{section.3}% 15 16 | \BOOKMARK [2][-]{subsection.3.3}{Επίπεδα υλοποίησης}{section.3}% 16 17 | \BOOKMARK [2][-]{subsection.3.4}{Αλγόριθμοι υλοποίησης βαθμωτού πολλαπλασιασμού}{section.3}% 17 18 | \BOOKMARK [1][-]{section.4}{Υλοποίηση στη γλώσσα OCaml}{}% 18 19 | \BOOKMARK [2][-]{subsection.4.1}{Υλοποίηση βιβλιοθήκης}{section.4}% 19 20 | \BOOKMARK [3][-]{subsubsection.4.1.1}{Modulo αριθμητική}{subsection.4.1}% 20 21 | \BOOKMARK [3][-]{subsubsection.4.1.2}{Υλοποίηση πράξεων ομάδας}{subsection.4.1}% 21 22 | \BOOKMARK [3][-]{subsubsection.4.1.3}{Υλοποίηση βαθμωτού πολλαπλασιασμού}{subsection.4.1}% 22 23 | \BOOKMARK [3][-]{subsubsection.4.1.4}{Ψηφιακή υπογραφή}{subsection.4.1}% 23 24 | \BOOKMARK [2][-]{subsection.4.2}{Προγράμματα επίδειξης}{section.4}% 24 25 | \BOOKMARK [3][-]{subsubsection.4.2.1}{Υλοποίηση ECDH}{subsection.4.2}% 25 26 | \BOOKMARK [3][-]{subsubsection.4.2.2}{ECDSA}{subsection.4.2}% 26 27 | \BOOKMARK [3][-]{subsubsection.4.2.3}{Πηγαίος κώδικας}{subsection.4.2}% 27 28 | \BOOKMARK [2][-]{subsection.4.3}{Τεκμηρίωση Βιβλιοθήκης}{section.4}% 28 29 | -------------------------------------------------------------------------------- /report/ocamldoc.sty: -------------------------------------------------------------------------------- 1 | 2 | %% Support macros for LaTeX documentation generated by ocamldoc. 3 | %% This file is in the public domain; do what you want with it. 4 | 5 | \NeedsTeXFormat{LaTeX2e} 6 | \ProvidesPackage{ocamldoc} 7 | [2001/12/04 v1.0 ocamldoc support] 8 | 9 | \newenvironment{ocamldoccode}{% 10 | \bgroup 11 | \leftskip\@totalleftmargin 12 | \rightskip\z@skip 13 | \parindent\z@ 14 | \parfillskip\@flushglue 15 | \parskip\z@skip 16 | %\noindent 17 | \@@par\smallskip 18 | \@tempswafalse 19 | \def\par{% 20 | \if@tempswa 21 | \leavevmode\null\@@par\penalty\interlinepenalty 22 | \else 23 | \@tempswatrue 24 | \ifhmode\@@par\penalty\interlinepenalty\fi 25 | \fi} 26 | \obeylines 27 | \verbatim@font 28 | \let\org@prime~% 29 | \@noligs 30 | \let\org@dospecials\dospecials 31 | \g@remfrom@specials{\\} 32 | \g@remfrom@specials{\{} 33 | \g@remfrom@specials{\}} 34 | \let\do\@makeother 35 | \dospecials 36 | \let\dospecials\org@dospecials 37 | \frenchspacing\@vobeyspaces 38 | \everypar \expandafter{\the\everypar \unpenalty}} 39 | {\egroup\par} 40 | 41 | \def\g@remfrom@specials#1{% 42 | \def\@new@specials{} 43 | \def\@remove##1{% 44 | \ifx##1#1\else 45 | \g@addto@macro\@new@specials{\do ##1}\fi} 46 | \let\do\@remove\dospecials 47 | \let\dospecials\@new@specials 48 | } 49 | 50 | \newenvironment{ocamldocdescription} 51 | {\list{}{\rightmargin0pt \topsep0pt}\raggedright\item\noindent\relax\ignorespaces} 52 | {\endlist\medskip} 53 | 54 | \newenvironment{ocamldoccomment} 55 | {\list{}{\leftmargin 2\leftmargini \rightmargin0pt \topsep0pt}\raggedright\item\noindent\relax} 56 | {\endlist} 57 | 58 | \let \ocamldocparagraph \paragraph 59 | \def \paragraph #1{\ocamldocparagraph {#1}\noindent} 60 | \let \ocamldocsubparagraph \subparagraph 61 | \def \subparagraph #1{\ocamldocsubparagraph {#1}\noindent} 62 | 63 | \let\ocamldocvspace\vspace 64 | 65 | \newenvironment{ocamldocindent}{\list{}{}\item\relax}{\endlist} 66 | \newenvironment{ocamldocsigend} 67 | {\noindent\quad\texttt{sig}\ocamldocindent} 68 | {\endocamldocindent\vskip -\lastskip 69 | \noindent\quad\texttt{end}\medskip} 70 | \newenvironment{ocamldocobjectend} 71 | {\noindent\quad\texttt{object}\ocamldocindent} 72 | {\endocamldocindent\vskip -\lastskip 73 | \noindent\quad\texttt{end}\medskip} 74 | 75 | \endinput 76 | -------------------------------------------------------------------------------- /presentation/ocamldoc.sty: -------------------------------------------------------------------------------- 1 | 2 | %% Support macros for LaTeX documentation generated by ocamldoc. 3 | %% This file is in the public domain; do what you want with it. 4 | 5 | \NeedsTeXFormat{LaTeX2e} 6 | \ProvidesPackage{ocamldoc} 7 | [2001/12/04 v1.0 ocamldoc support] 8 | 9 | \newenvironment{ocamldoccode}{% 10 | \bgroup 11 | \leftskip\@totalleftmargin 12 | \rightskip\z@skip 13 | \parindent\z@ 14 | \parfillskip\@flushglue 15 | \parskip\z@skip 16 | %\noindent 17 | \@@par\smallskip 18 | \@tempswafalse 19 | \def\par{% 20 | \if@tempswa 21 | \leavevmode\null\@@par\penalty\interlinepenalty 22 | \else 23 | \@tempswatrue 24 | \ifhmode\@@par\penalty\interlinepenalty\fi 25 | \fi} 26 | \obeylines 27 | \verbatim@font 28 | \let\org@prime~% 29 | \@noligs 30 | \let\org@dospecials\dospecials 31 | \g@remfrom@specials{\\} 32 | \g@remfrom@specials{\{} 33 | \g@remfrom@specials{\}} 34 | \let\do\@makeother 35 | \dospecials 36 | \let\dospecials\org@dospecials 37 | \frenchspacing\@vobeyspaces 38 | \everypar \expandafter{\the\everypar \unpenalty}} 39 | {\egroup\par} 40 | 41 | \def\g@remfrom@specials#1{% 42 | \def\@new@specials{} 43 | \def\@remove##1{% 44 | \ifx##1#1\else 45 | \g@addto@macro\@new@specials{\do ##1}\fi} 46 | \let\do\@remove\dospecials 47 | \let\dospecials\@new@specials 48 | } 49 | 50 | \newenvironment{ocamldocdescription} 51 | {\list{}{\rightmargin0pt \topsep0pt}\raggedright\item\noindent\relax\ignorespaces} 52 | {\endlist\medskip} 53 | 54 | \newenvironment{ocamldoccomment} 55 | {\list{}{\leftmargin 2\leftmargini \rightmargin0pt \topsep0pt}\raggedright\item\noindent\relax} 56 | {\endlist} 57 | 58 | \let \ocamldocparagraph \paragraph 59 | \def \paragraph #1{\ocamldocparagraph {#1}\noindent} 60 | \let \ocamldocsubparagraph \subparagraph 61 | \def \subparagraph #1{\ocamldocsubparagraph {#1}\noindent} 62 | 63 | \let\ocamldocvspace\vspace 64 | 65 | \newenvironment{ocamldocindent}{\list{}{}\item\relax}{\endlist} 66 | \newenvironment{ocamldocsigend} 67 | {\noindent\quad\texttt{sig}\ocamldocindent} 68 | {\endocamldocindent\vskip -\lastskip 69 | \noindent\quad\texttt{end}\medskip} 70 | \newenvironment{ocamldocobjectend} 71 | {\noindent\quad\texttt{object}\ocamldocindent} 72 | {\endocamldocindent\vskip -\lastskip 73 | \noindent\quad\texttt{end}\medskip} 74 | 75 | \endinput 76 | -------------------------------------------------------------------------------- /src/demo/test.ml: -------------------------------------------------------------------------------- 1 | open EccPrimitives 2 | open Ecdh 3 | open Ecdsa 4 | 5 | module DH = Ecdh (PrimeField) 6 | module DSA = Ecdsa (PrimeField) 7 | 8 | let curve = PrimeField.lookup_curve "secp256k1" 9 | 10 | 11 | let (bob_pk, bob_sk) = DH.create_keys curve 12 | let (alice_pk, alice_sk) = DH.create_keys curve 13 | 14 | let sign_message msg sk = 15 | DSA.sign msg sk curve 16 | 17 | let verify_signed_message msg sign pk_sender = 18 | if DSA.verify msg sign pk_sender curve then 19 | Printf.printf "message succesfully verified\n" 20 | else 21 | Printf.printf "Invalid signature\n" 22 | 23 | 24 | 25 | 26 | let main1 = 27 | let msg = "ECDSA demo!" in 28 | let signature = sign_message msg alice_sk in 29 | verify_signed_message msg signature alice_pk; 30 | ;; 31 | let main2 = 32 | let bobs_secret = DH.create_session_key alice_pk bob_sk curve in 33 | let alices_secret = DH.create_session_key bob_pk alice_sk curve in 34 | (* In a world without war alice and bob should share a secret *) 35 | if (bobs_secret = alices_secret) then 36 | Printf.printf "Bob and alice shared a secret\n" 37 | else 38 | Printf.printf "We failed bob and alice\n" 39 | ;; 40 | 41 | 42 | let ripemd160_hexdigest s = 43 | let hex s = Cryptokit.transform_string (Cryptokit.Hexa.encode()) s in 44 | hex (Cryptokit.hash_string (Cryptokit.Hash.ripemd160()) s) 45 | let sha256_hexdigest s = 46 | let hex s = Cryptokit.transform_string (Cryptokit.Hexa.encode()) s in 47 | hex (Cryptokit.hash_string (Cryptokit.Hash.sha256()) s) 48 | 49 | 50 | 51 | let main3 = 52 | 53 | let sk = Z.of_string_base 16 "18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725" in 54 | let pk = DH.pubkey_of_seckey curve sk in 55 | let pkb = EccPrimitives.bytes_of_point_compressed pk in 56 | let pks = EccPrimitives.hexstring_of_string pkb in 57 | 58 | (* let pkhash = (Sha256.to_hex (Sha256.string pkb)) in *) 59 | 60 | let pkhashb = (Sha256.to_bin (Sha256.string pkb)) in 61 | 62 | let pkhash = sha256_hexdigest pkb in 63 | 64 | let rp = ripemd160_hexdigest pkhashb in 65 | Printf.printf "--------------------------TESTS---------------------\n"; 66 | 67 | let rnd_str = "RANDOM STRING" in 68 | if EccPrimitives.hexstring_to_string 69 | (EccPrimitives.hexstring_of_string rnd_str) = rnd_str 70 | then Printf.printf "hexstring_to_string & hexstring_of_string OK\n" 71 | else Printf.printf "hexstring_to_string Fail %s\n" pks; 72 | 73 | if pks = 74 | "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352" 75 | then Printf.printf "ECC OK\n" 76 | else Printf.printf "ECC Fail %s\n" pks; 77 | 78 | if pkhash = 79 | "0b7c28c9b7290c98d7438e70b3d3f7c848fbd7d1dc194ff83f4f7cc9b1378e98" 80 | then Printf.printf "SHA256 OK\n" 81 | else Printf.printf "SHA256 Fail %s\n" pkhash; 82 | 83 | if rp = 84 | "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31" 85 | then Printf.printf "RIPEMD160 OK\n" 86 | else Printf.printf "RIPEMD160 Fail %s\n" rp; 87 | 88 | Printf.printf "----------------------END OF TESTS------------------\n"; 89 | ;; 90 | 91 | 92 | let main = main1 ;; main2 ;; main3 93 | -------------------------------------------------------------------------------- /report/report.toc: -------------------------------------------------------------------------------- 1 | \contentsline {section}{\numberline {1}Ελλειπτικές καμπύλες}{2}{section.1} 2 | \contentsline {subsection}{\numberline {1.1}Εισαγωγή}{2}{subsection.1.1} 3 | \contentsline {subsection}{\numberline {1.2}Ελλειπτικές καμπύλες στο $\mathcal {R}$}{2}{subsection.1.2} 4 | \contentsline {subsubsection}{\numberline {1.2.1}Ορισμένες πράξεις σε ελλειπτικές καμπύλες πάνω στο $\mathcal {R}$}{2}{subsubsection.1.2.1} 5 | \contentsline {paragraph}{Αντίθετο σημείο}{2}{section*.2} 6 | \contentsline {paragraph}{Πρόσθεση δύο σημείων}{2}{section*.3} 7 | \contentsline {paragraph}{Διπλασιασμός σημείου}{3}{section*.5} 8 | \contentsline {subsection}{\numberline {1.3}Ελλειπτικές καμπύλες πάνω από το σώμα $\mathbb {F}_p$.}{3}{subsection.1.3} 9 | \contentsline {subsubsection}{\numberline {1.3.1}Ορισμένες πράξεις σε σε ελλειπτικές καμπύλες πάνω στο $\mathbb {F}_p$}{3}{subsubsection.1.3.1} 10 | \contentsline {paragraph}{Αντίθετο σημείο}{3}{section*.7} 11 | \contentsline {paragraph}{Πρόσθεση δύο σημείων}{3}{section*.8} 12 | \contentsline {paragraph}{Διπλασιασμός σημείου}{4}{section*.9} 13 | \contentsline {subsection}{\numberline {1.4}Ελλειπτικές καμπύλες πάνω από το σώμα $F_{2^m}$.}{4}{subsection.1.4} 14 | \contentsline {section}{\numberline {2}Το πρόβλημα του διακριτού λογαρίθμου σε ελλειπτικές καμπύλες (ECDLP)}{5}{section.2} 15 | \contentsline {subsection}{\numberline {2.1}Βαθμωτός Πολλαπλασιασμός}{5}{subsection.2.1} 16 | \contentsline {subsection}{\numberline {2.2}ECDLP}{5}{subsection.2.2} 17 | \contentsline {subsection}{\numberline {2.3}Elliptic curve Diffie-Hellman (ECDH)}{5}{subsection.2.3} 18 | \contentsline {subsection}{\numberline {2.4}Elliptic curve digital signature algorithm (ECDSA)}{6}{subsection.2.4} 19 | \contentsline {paragraph}{Παραγωγή υπογραφής}{6}{section*.10} 20 | \contentsline {paragraph}{Επαλήθευση υπογραφής}{6}{section*.11} 21 | \contentsline {section}{\numberline {3}Υλοποίηση ενός συστήματος κρυπτογραφίας βασισμένο σε ελλειπτικές καμπύλες}{7}{section.3} 22 | \contentsline {subsection}{\numberline {3.1}Πλεονεκτήματα χρήσης}{7}{subsection.3.1} 23 | \contentsline {subsection}{\numberline {3.2}Επιλογή παραμέτρων}{7}{subsection.3.2} 24 | \contentsline {subsection}{\numberline {3.3}Επίπεδα υλοποίησης}{8}{subsection.3.3} 25 | \contentsline {subsection}{\numberline {3.4}Αλγόριθμοι υλοποίησης βαθμωτού πολλαπλασιασμού}{8}{subsection.3.4} 26 | \contentsline {section}{\numberline {4}Υλοποίηση στη γλώσσα OCaml}{9}{section.4} 27 | \contentsline {subsection}{\numberline {4.1}Υλοποίηση βιβλιοθήκης}{9}{subsection.4.1} 28 | \contentsline {subsubsection}{\numberline {4.1.1}Modulo αριθμητική}{9}{subsubsection.4.1.1} 29 | \contentsline {subsubsection}{\numberline {4.1.2}Υλοποίηση πράξεων ομάδας}{9}{subsubsection.4.1.2} 30 | \contentsline {subsubsection}{\numberline {4.1.3}Υλοποίηση βαθμωτού πολλαπλασιασμού}{9}{subsubsection.4.1.3} 31 | \contentsline {subsubsection}{\numberline {4.1.4}Ψηφιακή υπογραφή}{9}{subsubsection.4.1.4} 32 | \contentsline {subsection}{\numberline {4.2}Προγράμματα επίδειξης}{9}{subsection.4.2} 33 | \contentsline {subsubsection}{\numberline {4.2.1}Υλοποίηση ECDH}{9}{subsubsection.4.2.1} 34 | \contentsline {paragraph}{Register.}{9}{section*.14} 35 | \contentsline {paragraph}{Exchange.}{10}{section*.15} 36 | \contentsline {subsubsection}{\numberline {4.2.2}ECDSA}{10}{subsubsection.4.2.2} 37 | \contentsline {paragraph}{Sign.}{10}{section*.16} 38 | \contentsline {paragraph}{Verify.}{10}{section*.17} 39 | \contentsline {subsubsection}{\numberline {4.2.3}Πηγαίος κώδικας}{10}{subsubsection.4.2.3} 40 | \contentsline {subsection}{\numberline {4.3}Τεκμηρίωση Βιβλιοθήκης}{10}{subsection.4.3} 41 | -------------------------------------------------------------------------------- /doc/ocamldoc.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | \usepackage[latin1]{inputenc} 3 | \usepackage[T1]{fontenc} 4 | \usepackage{textcomp} 5 | \usepackage{fullpage} 6 | \usepackage{url} 7 | \usepackage{ocamldoc} 8 | \begin{document} 9 | \tableofcontents 10 | \section{Module {\tt{Ecc}} : An elliptic curve point.} 11 | \label{module:Ecc}\index{Ecc@\verb`Ecc`} 12 | It is either infinity or a point (x,y). 13 | 14 | 15 | 16 | \ocamldocvspace{0.5cm} 17 | 18 | 19 | 20 | \begin{ocamldoccode} 21 | {\tt{module }}{\tt{Ecc}}{\tt{ : }}\end{ocamldoccode} 22 | \label{module:Ecc.Ecc}\index{Ecc@\verb`Ecc`} 23 | 24 | \begin{ocamldocsigend} 25 | 26 | 27 | \label{type:Ecc.Ecc.point}\begin{ocamldoccode} 28 | type point = 29 | | Infinity 30 | | Point of Z.t * Z.t 31 | \end{ocamldoccode} 32 | \begin{ocamldoccomment} 33 | An elliptic curve point. It is either infinity or a point (x,y). 34 | \end{ocamldoccomment} 35 | \index{point@\verb`point`} 36 | 37 | 38 | \label{type:Ecc.Ecc.elliptic-underscorecurve}\begin{ocamldoccode} 39 | type elliptic_curve = {\char123} 40 | p : Z.t ; 41 | a : Z.t ; 42 | b : Z.t ; 43 | g : point ; 44 | n : Z.t ; 45 | h : Z.t ; 46 | {\char125} 47 | \end{ocamldoccode} 48 | \index{elliptic-underscorecurve@\verb`elliptic_curve`} 49 | \begin{ocamldocdescription} 50 | The type of domain parameters 51 | 52 | 53 | \end{ocamldocdescription} 54 | 55 | 56 | \label{val:Ecc.Ecc.inverse}\begin{ocamldoccode} 57 | val inverse : Z.t -> Z.t -> Z.t 58 | \end{ocamldoccode} 59 | \index{inverse@\verb`inverse`} 60 | \begin{ocamldocdescription} 61 | Ecc.inverse a n inverses the number a modulo n 62 | 63 | 64 | \end{ocamldocdescription} 65 | 66 | 67 | \label{val:Ecc.Ecc.verify-underscorerange}\begin{ocamldoccode} 68 | val verify_range : Z.t -> Z.t -> Z.t -> bool 69 | \end{ocamldoccode} 70 | \index{verify-underscorerange@\verb`verify_range`} 71 | \begin{ocamldocdescription} 72 | Ecc.verify\_range a l h returns true if l $\leq$ a $\leq$ h or false otherwise 73 | 74 | 75 | \end{ocamldocdescription} 76 | 77 | 78 | \label{val:Ecc.Ecc.is-underscorepoint}\begin{ocamldoccode} 79 | val is_point : point -> elliptic_curve -> bool 80 | \end{ocamldoccode} 81 | \index{is-underscorepoint@\verb`is_point`} 82 | \begin{ocamldocdescription} 83 | Returns true if a point belongs to an elliptic curve or false otherwise 84 | 85 | 86 | \end{ocamldocdescription} 87 | 88 | 89 | \label{val:Ecc.Ecc.double-underscorepoint}\begin{ocamldoccode} 90 | val double_point : point -> elliptic_curve -> point 91 | \end{ocamldoccode} 92 | \index{double-underscorepoint@\verb`double_point`} 93 | \begin{ocamldocdescription} 94 | Given a point P on an elliptic curve and the elliptic curve retuns the point 2P 95 | on that curve. 96 | 97 | 98 | \end{ocamldocdescription} 99 | 100 | 101 | \label{val:Ecc.Ecc.add-underscorepoint}\begin{ocamldoccode} 102 | val add_point : point -> point -> elliptic_curve -> point 103 | \end{ocamldoccode} 104 | \index{add-underscorepoint@\verb`add_point`} 105 | \begin{ocamldocdescription} 106 | Given two points P and Q, both on the same elliptic curve, and the elliptic curve returns 107 | P+Q on that curve. 108 | 109 | 110 | \end{ocamldocdescription} 111 | 112 | 113 | \label{val:Ecc.Ecc.multiply-underscorepoint}\begin{ocamldoccode} 114 | val multiply_point : point -> Z.t -> elliptic_curve -> point 115 | \end{ocamldoccode} 116 | \index{multiply-underscorepoint@\verb`multiply_point`} 117 | \begin{ocamldocdescription} 118 | Given a point P on an elliptic curve, an integer k and the elliptic curve returns 119 | the scalar multiplication kP on that curve. 120 | 121 | 122 | \end{ocamldocdescription} 123 | 124 | 125 | \label{val:Ecc.Ecc.integer-underscoreof-underscoreoctet}\begin{ocamldoccode} 126 | val integer_of_octet : string -> int 127 | \end{ocamldoccode} 128 | \index{integer-underscoreof-underscoreoctet@\verb`integer_of_octet`} 129 | 130 | 131 | \label{val:Ecc.Ecc.octList-underscoreof-underscoreoctStr}\begin{ocamldoccode} 132 | val octList_of_octStr : string -> string list 133 | \end{ocamldoccode} 134 | \index{octList-underscoreof-underscoreoctStr@\verb`octList_of_octStr`} 135 | 136 | 137 | \label{val:Ecc.Ecc.integer-underscoreof-underscoreoctStr}\begin{ocamldoccode} 138 | val integer_of_octStr : string -> Z.t 139 | \end{ocamldoccode} 140 | \index{integer-underscoreof-underscoreoctStr@\verb`integer_of_octStr`} 141 | 142 | 143 | \label{val:Ecc.Ecc.brainpool-underscoreP256-underscorer1}\begin{ocamldoccode} 144 | val brainpool_P256_r1 : elliptic_curve 145 | \end{ocamldoccode} 146 | \index{brainpool-underscoreP256-underscorer1@\verb`brainpool_P256_r1`} 147 | \begin{ocamldocdescription} 148 | An elliptic curve used for ECC as defined by Brainpool 149 | 150 | 151 | \end{ocamldocdescription} 152 | 153 | 154 | \label{val:Ecc.Ecc.test-underscorecurve}\begin{ocamldoccode} 155 | val test_curve : elliptic_curve 156 | \end{ocamldoccode} 157 | \index{test-underscorecurve@\verb`test_curve`} 158 | \begin{ocamldocdescription} 159 | An elliptic curve with small domain parameters for testing purposes 160 | 161 | 162 | \end{ocamldocdescription} 163 | 164 | 165 | \label{val:Ecc.Ecc.random-underscorebig-underscoreint}\begin{ocamldoccode} 166 | val random_big_int : Z.t -> Z.t 167 | \end{ocamldoccode} 168 | \index{random-underscorebig-underscoreint@\verb`random_big_int`} 169 | \begin{ocamldocdescription} 170 | Ecc.random\_big\_int bound returns a random integer in {\tt{1, bound-1}} 171 | 172 | 173 | \end{ocamldocdescription} 174 | 175 | 176 | \label{val:Ecc.Ecc.sign}\begin{ocamldoccode} 177 | val sign : string -> Z.t -> elliptic_curve -> Z.t * Z.t 178 | \end{ocamldoccode} 179 | \index{sign@\verb`sign`} 180 | \begin{ocamldocdescription} 181 | Ecc.sign message sk curve where sk is secret key of the user s and curve 182 | the public elliptic curve, returns the signature (r, s) of the message. 183 | 184 | 185 | \end{ocamldocdescription} 186 | 187 | 188 | \label{val:Ecc.Ecc.verify}\begin{ocamldoccode} 189 | val verify : string -> Z.t * Z.t -> point -> elliptic_curve -> bool 190 | \end{ocamldoccode} 191 | \index{verify@\verb`verify`} 192 | \begin{ocamldocdescription} 193 | Ecc.verify message (r, s) pk curve where pk is the public key of the user 194 | who signed the message, returns true if the (r, s) is a valid 195 | signature or false otherwise. 196 | 197 | 198 | \end{ocamldocdescription} 199 | 200 | 201 | \label{val:Ecc.Ecc.create-underscorekeys}\begin{ocamldoccode} 202 | val create_keys : elliptic_curve -> point * Z.t 203 | \end{ocamldoccode} 204 | \index{create-underscorekeys@\verb`create_keys`} 205 | \begin{ocamldocdescription} 206 | Creates a tuple (public\_key, secret\_key) where public\_key is a point of 207 | the curve and secret\_key an integer. 208 | 209 | 210 | \end{ocamldocdescription} 211 | \end{ocamldocsigend} 212 | 213 | 214 | 215 | 216 | \end{document} -------------------------------------------------------------------------------- /report/report.pyg: -------------------------------------------------------------------------------- 1 | 2 | \makeatletter 3 | \def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax% 4 | \let\PY@ul=\relax \let\PY@tc=\relax% 5 | \let\PY@bc=\relax \let\PY@ff=\relax} 6 | \def\PY@tok#1{\csname PY@tok@#1\endcsname} 7 | \def\PY@toks#1+{\ifx\relax#1\empty\else% 8 | \PY@tok{#1}\expandafter\PY@toks\fi} 9 | \def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{% 10 | \PY@it{\PY@bf{\PY@ff{#1}}}}}}} 11 | \def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}} 12 | 13 | \expandafter\def\csname PY@tok@gu\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}} 14 | \expandafter\def\csname PY@tok@gt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.64,0.00,0.00}{##1}}} 15 | \expandafter\def\csname PY@tok@gs\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 16 | \expandafter\def\csname PY@tok@gr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.94,0.16,0.16}{##1}}} 17 | \expandafter\def\csname PY@tok@cm\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.56,0.35,0.01}{##1}}} 18 | \expandafter\def\csname PY@tok@vg\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 19 | \expandafter\def\csname PY@tok@m\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.81}{##1}}} 20 | \expandafter\def\csname PY@tok@l\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 21 | \expandafter\def\csname PY@tok@go\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 22 | \expandafter\def\csname PY@tok@ge\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 23 | \expandafter\def\csname PY@tok@gd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.64,0.00,0.00}{##1}}} 24 | \expandafter\def\csname PY@tok@il\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.81}{##1}}} 25 | \expandafter\def\csname PY@tok@cs\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.56,0.35,0.01}{##1}}} 26 | \expandafter\def\csname PY@tok@cp\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.56,0.35,0.01}{##1}}} 27 | \expandafter\def\csname PY@tok@gi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}} 28 | \expandafter\def\csname PY@tok@gh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} 29 | \expandafter\def\csname PY@tok@ni\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.81,0.36,0.00}{##1}}} 30 | \expandafter\def\csname PY@tok@ld\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 31 | \expandafter\def\csname PY@tok@nl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.96,0.47,0.00}{##1}}} 32 | \expandafter\def\csname PY@tok@nn\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 33 | \expandafter\def\csname PY@tok@no\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 34 | \expandafter\def\csname PY@tok@na\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.77,0.63,0.00}{##1}}} 35 | \expandafter\def\csname PY@tok@nb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 36 | \expandafter\def\csname PY@tok@nc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 37 | \expandafter\def\csname PY@tok@nd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.36,0.21,0.80}{##1}}} 38 | \expandafter\def\csname PY@tok@ne\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.80,0.00,0.00}{##1}}} 39 | \expandafter\def\csname PY@tok@nf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 40 | \expandafter\def\csname PY@tok@nx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 41 | \expandafter\def\csname PY@tok@si\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 42 | \expandafter\def\csname PY@tok@s2\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 43 | \expandafter\def\csname PY@tok@vi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 44 | \expandafter\def\csname PY@tok@py\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 45 | \expandafter\def\csname PY@tok@nt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 46 | \expandafter\def\csname PY@tok@nv\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 47 | \expandafter\def\csname PY@tok@s1\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 48 | \expandafter\def\csname PY@tok@vc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 49 | \expandafter\def\csname PY@tok@gp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.56,0.35,0.01}{##1}}} 50 | \expandafter\def\csname PY@tok@sh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 51 | \expandafter\def\csname PY@tok@ow\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 52 | \expandafter\def\csname PY@tok@mf\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.81}{##1}}} 53 | \expandafter\def\csname PY@tok@bp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.20,0.40,0.64}{##1}}} 54 | \expandafter\def\csname PY@tok@x\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 55 | \expandafter\def\csname PY@tok@c1\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.56,0.35,0.01}{##1}}} 56 | \expandafter\def\csname PY@tok@o\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.81,0.36,0.00}{##1}}} 57 | \expandafter\def\csname PY@tok@kc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 58 | \expandafter\def\csname PY@tok@c\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.56,0.35,0.01}{##1}}} 59 | \expandafter\def\csname PY@tok@kr\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 60 | \expandafter\def\csname PY@tok@g\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 61 | \expandafter\def\csname PY@tok@err\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.64,0.00,0.00}{##1}}\def\PY@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{0.94,0.16,0.16}{1,1,1}{\strut ##1}}} 62 | \expandafter\def\csname PY@tok@mh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.81}{##1}}} 63 | \expandafter\def\csname PY@tok@ss\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 64 | \expandafter\def\csname PY@tok@sr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 65 | \expandafter\def\csname PY@tok@mo\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.81}{##1}}} 66 | \expandafter\def\csname PY@tok@kd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 67 | \expandafter\def\csname PY@tok@mi\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.81}{##1}}} 68 | \expandafter\def\csname PY@tok@kn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 69 | \expandafter\def\csname PY@tok@sx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 70 | \expandafter\def\csname PY@tok@n\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 71 | \expandafter\def\csname PY@tok@p\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} 72 | \expandafter\def\csname PY@tok@s\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 73 | \expandafter\def\csname PY@tok@kp\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 74 | \expandafter\def\csname PY@tok@w\endcsname{\let\PY@ul=\underline\def\PY@tc##1{\textcolor[rgb]{0.97,0.97,0.97}{##1}}} 75 | \expandafter\def\csname PY@tok@kt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 76 | \expandafter\def\csname PY@tok@sc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 77 | \expandafter\def\csname PY@tok@sb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 78 | \expandafter\def\csname PY@tok@k\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.13,0.29,0.53}{##1}}} 79 | \expandafter\def\csname PY@tok@se\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.31,0.60,0.02}{##1}}} 80 | \expandafter\def\csname PY@tok@sd\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.56,0.35,0.01}{##1}}} 81 | 82 | \def\PYZbs{\char`\\} 83 | \def\PYZus{\char`\_} 84 | \def\PYZob{\char`\{} 85 | \def\PYZcb{\char`\}} 86 | \def\PYZca{\char`\^} 87 | \def\PYZam{\char`\&} 88 | \def\PYZlt{\char`\<} 89 | \def\PYZgt{\char`\>} 90 | \def\PYZsh{\char`\#} 91 | \def\PYZpc{\char`\%} 92 | \def\PYZdl{\char`\$} 93 | \def\PYZti{\char`\~} 94 | % for compatibility with earlier versions 95 | \def\PYZat{@} 96 | \def\PYZlb{[} 97 | \def\PYZrb{]} 98 | \makeatother 99 | 100 | -------------------------------------------------------------------------------- /src/EccPrimitives.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | exception Invalid_point 4 | exception Error 5 | 6 | type point = Infinity | Point of Z.t * Z.t 7 | type octet = string 8 | 9 | let point_to_string = function 10 | | Infinity -> sprintf "0" 11 | | Point(x,y) -> 12 | sprintf "Point(Z.of_string \"%s\", Z.of_string \"%s\")" 13 | (Z.to_string x) (Z.to_string y) 14 | 15 | let integer_of_octet oct = 16 | Z.of_string (String.concat "" ["0x"; oct]) 17 | 18 | (* assumes q : prime WON'T WORK WITH Binary fields *) 19 | let of_octet octstr q a b = 20 | if octstr = "00" then Infinity 21 | else 22 | begin 23 | let num_octets = (String.length octstr)/2 in 24 | let len = String.length @@ Z.format "%b" q in 25 | let octets = Z.(div (~$ len) (~$ 8)) in 26 | let tmp = Z.((~$ 2) * octets) in 27 | if Z.(tmp + one) = Z.(of_int num_octets) then 28 | let w = String.sub octstr 0 2 in 29 | let x = String.sub octstr 2 (Z.to_int tmp) in 30 | let y = String.sub octstr ((Z.to_int tmp) + 1) (Z.to_int tmp) in 31 | if w = "04" then 32 | let x_p = integer_of_octet x in 33 | let y_p = integer_of_octet y in 34 | let v1 = Z.((x_p ** 2) mod q) in 35 | let v2 = Z.(((x_p ** 3) + (a * x_p) + b) mod q) in 36 | if v1 = v2 then Point (x_p, y_p) 37 | else raise Error 38 | else raise Error 39 | else raise Error 40 | end 41 | 42 | let inverse (a : Z.t) (p : Z.t) = 43 | Z.(invert a p) 44 | 45 | let int_pow a b = 46 | truncate ((float_of_int a) ** (float_of_int b)) 47 | 48 | let neg_mod a p = 49 | let r = Z.(a mod p) in 50 | if Z.(r < zero) then 51 | Z.(r+p) 52 | else 53 | r 54 | 55 | (*Generating random ints with a maximum length of decimal numbers*) 56 | let rec random_big_int bound = 57 | let () = Random.self_init () in 58 | let rec aux i acc = 59 | if i = 0 then 60 | acc 61 | else 62 | let b = Random.int 2 in 63 | aux (i-1) (acc ^ string_of_int b) 64 | in 65 | let size = 66 | String.length (Z.format "%b" bound) 67 | in 68 | let num = Z.of_string (aux size "0b") in 69 | match num < bound || num = Z.zero with 70 | | true -> num 71 | | false -> random_big_int bound 72 | 73 | let verify_range (num : Z.t) (lowbound : Z.t) (upbound : Z.t) = 74 | num >= lowbound && num <= upbound 75 | 76 | 77 | let charlist_to_string cl = 78 | String.concat "" (List.map (String.make 1) cl) 79 | let charlist_of_string s = 80 | List.init (String.length s) (String.get s) 81 | 82 | let hexchar_to_int c = match c with 83 | | '0'..'9' -> int_of_char c - 48 84 | | 'a'..'f' -> int_of_char c - 87 85 | | 'A'..'F' -> int_of_char c - 55 86 | | _ -> raise Error 87 | 88 | let hexchar_of_int i = match i>9 with 89 | | false -> char_of_int (i + 48) 90 | | true -> char_of_int (i + 87) 91 | 92 | let hexstring_to_string s = 93 | let cl = charlist_of_string s in 94 | let rec go l = 95 | match l with 96 | | [] -> [] 97 | | [_] -> [] 98 | | x :: y :: xs -> char_of_int ((hexchar_to_int x * 16) + hexchar_to_int y) :: go xs 99 | in charlist_to_string (go cl) 100 | 101 | let hexstring_of_string s = 102 | let cl = charlist_of_string s in 103 | let rec go l = 104 | match l with 105 | | [] -> [] 106 | | x :: xs -> hexchar_of_int (int_of_char x / 16) :: hexchar_of_int (int_of_char x mod 16) :: go xs 107 | in charlist_to_string (go cl) 108 | 109 | let string_of_point_uncompressed p = match p with 110 | | Infinity -> "0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 111 | | Point (x, y) -> String.concat "" 112 | ["04" ; Z.format "%x" x ; Z.format "%x" y] 113 | (* test 114 | 18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725 -> 115 | 0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352 -> 116 | 0b7c28c9b7290c98d7438e70b3d3f7c848fbd7d1dc194ff83f4f7cc9b1378e98 -> 117 | *) 118 | let string_of_point_compressed p = match p with 119 | | Infinity -> "0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 120 | | Point (x, y) -> if (Z.rem y (Z.of_int 2)) = Z.zero 121 | then String.concat "" ["02" ; Z.format "%x" x] 122 | else String.concat "" ["03" ; Z.format "%x" x] 123 | 124 | 125 | let bytes_of_point_uncompressed p = 126 | hexstring_to_string (string_of_point_uncompressed p) 127 | let bytes_of_point_compressed p = 128 | hexstring_to_string (string_of_point_compressed p) 129 | 130 | (* Auxiliary fuction for m*) 131 | let mods k w = 132 | if Z.(k mod w) >= Z.( w / ~$2) then 133 | Z.((k mod w) - w) 134 | else 135 | Z.(k mod w) 136 | 137 | let w_naf k w = 138 | let rec aux d acc = 139 | if d <= Z.zero then 140 | acc 141 | else 142 | begin 143 | if Z.(d mod ~$2) = Z.one then 144 | let ki = mods d Z.(~$2 ** w) in 145 | aux Z.((d-ki) / ~$2) (ki :: acc) 146 | else 147 | aux Z.(d / ~$2) (Z.zero :: acc) 148 | end 149 | in 150 | aux k [] 151 | 152 | let return_point p pc_p ki = 153 | if ki = Z.one || ki = Z.minus_one then 154 | p 155 | else if ki = Z.(~$3) || ki = Z.(- ~$3) then 156 | pc_p.(0) 157 | else if ki = Z.(~$ 5) || ki = Z.(- ~$5) then 158 | pc_p.(1) 159 | else if ki = Z.(~$ 7) || ki = Z.(- ~$7) then 160 | pc_p.(2) 161 | else if ki = Z.(~$ 9) || ki = Z.(- ~$9) then 162 | pc_p.(3) 163 | else if ki = Z.(~$ 11) || ki = Z.(- ~$11) then 164 | pc_p.(4) 165 | else if ki = Z.(~$ 13) || ki = Z.(- ~$13) then 166 | pc_p.(5) 167 | else 168 | pc_p.(6) 169 | 170 | module type Specs = sig 171 | 172 | type t 173 | (* The eliptic curve type *) 174 | val curve : t 175 | (* The eliptic curve variable *) 176 | 177 | val field : Z.t 178 | (* Returns an integer specifying the finite field (i.e. p for the prime field 179 | Fp) *) 180 | val g : point 181 | (* Returns the base point *) 182 | val n : Z.t 183 | (* Returns the order of the base point *) 184 | val a : Z.t 185 | (* Returns the variable a of the eliptic curve equation *) 186 | val b : Z.t 187 | (* Returns the variable b of the eliptic curve equation *) 188 | val points : point list 189 | (* Returns the point list used to pre-compute points to use on 190 | multiply_point algorithm *) 191 | 192 | end 193 | 194 | module type Curve = sig 195 | 196 | val get_field : Z.t 197 | (* Returns an integer specifying the finite field (i.e. p for the prime field 198 | Fp) *) 199 | val get_g : point 200 | (* Returns the base point *) 201 | val get_n : Z.t 202 | (* Returns the order of the base point *) 203 | val get_a : Z.t 204 | (* Returns the variable a of the eliptic curve equation *) 205 | val get_b : Z.t 206 | (* Returns the variable b of the eliptic curve equation *) 207 | val get_points : point list 208 | (* Returns the point list used to pre-compute points to use on 209 | multiply_point algorithm *) 210 | val is_point : point -> bool 211 | (* Check if a point lies on an eliptic curve *) 212 | val inverse_point : point -> point 213 | (* Given a point P returns the point -P *) 214 | val double_point : point -> point 215 | (* Doubles a given point on a given eliptic curve *) 216 | val add_point : point -> point -> point 217 | (* Adds two given points on a given eliptic curve *) 218 | val double_and_add : point -> Z.t -> point 219 | (* Point multiplication with the double-and-add algorithm *) 220 | val montogomery_ladders : point -> Z.t -> point 221 | (* Point multiplication is implemented using montogomery ladders *) 222 | val multiply_point : point -> Z.t -> point 223 | (* Point multiplication is implemented using the 224 | w-ary non-adjacent form (wNAF) algorithm *) 225 | val multiscalar_mul : point -> Z.t list -> point list -> point 226 | (* inner product of a scalar vector and a point vector *) 227 | 228 | end 229 | 230 | module Make_Curve(S : Specs) : Curve = 231 | struct 232 | open S 233 | 234 | let get_field = field 235 | let get_g = g 236 | let get_n = n 237 | let get_a = a 238 | let get_b = b 239 | let get_points = points 240 | let computed_points = Hashtbl.create 130 241 | 242 | (*Elliptic Curve Functions*) 243 | 244 | let normalize (r : point) = 245 | let p = get_field in 246 | let rec normalize_aux (x : Z.t) = 247 | match x with 248 | | x when Z.(x < zero) -> normalize_aux Z.(p + x) 249 | | x -> x 250 | in 251 | match r with 252 | | Infinity -> Infinity 253 | | Point (x_r, y_r) -> 254 | Point (normalize_aux x_r, normalize_aux y_r) 255 | 256 | let is_point (r : point)= 257 | match r with 258 | | Infinity -> true 259 | | Point (x, y) -> 260 | let a = Z.((y ** 2) mod get_field) in 261 | let b = 262 | Z.(((x ** 3) + (get_a * x) + get_b) mod get_field) in 263 | a = b 264 | 265 | let inverse_point point = 266 | match point with 267 | Infinity -> Infinity 268 | | Point(x,y) -> normalize (Point(x, Z.(-y))) 269 | 270 | let double_point (r : point) = 271 | if not (is_point r) then raise Invalid_point; 272 | let p = get_field in 273 | match r with 274 | | Infinity -> Infinity 275 | | Point (_,y) when y = Z.zero -> Infinity 276 | | Point (x, y) -> 277 | let a = Z.(((((~$ 3) * (x ** 2))) + get_a) mod p) in 278 | let b = Z.((inverse (y + y) p) mod p) in 279 | let s = Z.(a * b mod p) in 280 | let x_r = Z.(((s ** 2) - (x + x)) mod p) in 281 | let y_r = Z.((-y + (s * (x - x_r))) mod p) in 282 | normalize (Point (x_r, y_r)) 283 | 284 | let add_point (r1 : point) (r2 : point) = 285 | if not ((is_point r1) && (is_point r2)) then raise Invalid_point; 286 | let p = get_field in 287 | match r1, r2 with 288 | | _, Infinity -> r1 289 | | Infinity, _ -> r2 290 | | r1, r2 when r1 = r2 -> double_point r1 291 | | Point (x1, _), Point (x2, _) when x1 = x2 -> Infinity 292 | | Point (x1, y1), Point (x2, y2) -> 293 | let s = Z.(((y2 - y1) * (inverse (x2 - x1) p)) mod p) in 294 | let xf = Z.(((s ** 2) - x1 - x2) mod p) in 295 | let yf = Z.((s * (x1 - xf) - y1) mod p) in 296 | normalize (Point (xf, yf)) 297 | 298 | let pre_computation (p : point) = 299 | let points = Array.make 7 Infinity in 300 | let p2 = double_point p in 301 | let p3 = add_point p p2 in 302 | let p5 = add_point p2 p3 in 303 | let p7 = add_point p2 p5 in 304 | let p9 = add_point p2 p7 in 305 | let p11 = add_point p2 p9 in 306 | let p13 = add_point p2 p11 in 307 | let p15 = add_point p2 p13 in 308 | 309 | let () = 310 | points.(0) <- p3; 311 | points.(1) <- p5; 312 | points.(2) <- p7; 313 | points.(3) <- p9; 314 | points.(4) <- p11; 315 | points.(5) <- p13; 316 | points.(6) <- p15 317 | in 318 | Hashtbl.add computed_points p points 319 | 320 | let () = 321 | pre_computation get_g; 322 | List.iter ( fun p -> pre_computation p) points 323 | (* pre-compute points for the point multiplication, 324 | implemented with the algorithm wNAF. 325 | For window = 5 pre-compute the points {1,3,5,7,9,11,13,15} *) 326 | 327 | let double_and_add (p : point) (d : Z.t) = 328 | let d_bits = Z.format "%b" (neg_mod d get_n) in 329 | let q = ref Infinity in 330 | String.iter (fun di -> 331 | q := double_point !q ; 332 | if di = '1' then 333 | q := add_point !q p 334 | else ()) d_bits; 335 | !q 336 | 337 | let montogomery_ladders (p : point) (d : Z.t) = 338 | let d_bits = Z.format "%b" (neg_mod d get_n) in 339 | let r_0 = ref Infinity in 340 | let r_1 = ref p in 341 | String.iter (fun di -> 342 | if di = '0' then 343 | begin 344 | r_1 := add_point !r_0 !r_1 ; 345 | r_0 := double_point !r_0 346 | end 347 | else 348 | begin 349 | r_0 := add_point !r_0 !r_1 ; 350 | r_1 := double_point !r_1 351 | end) d_bits; 352 | (!r_0) 353 | 354 | let multiply_point (p : point) (d : Z.t) = 355 | let rec aux q pc_points = function 356 | | [] -> q 357 | | ki :: t -> 358 | let q2 = double_point q in 359 | if ki <> Z.zero then 360 | let ki_p = 361 | return_point p pc_points ki 362 | in 363 | if ki > Z.zero then 364 | aux (add_point q2 ki_p) pc_points t 365 | else 366 | aux (add_point q2 (inverse_point ki_p ) ) 367 | pc_points t 368 | else aux q2 pc_points t 369 | in 370 | let d = neg_mod d get_n in 371 | let w_naf_list = w_naf d 5 in 372 | try 373 | let pc_points = Hashtbl.find computed_points p in 374 | aux Infinity pc_points w_naf_list 375 | with Not_found -> 376 | pre_computation p; 377 | let pc_points = Hashtbl.find computed_points p in 378 | aux Infinity pc_points w_naf_list 379 | 380 | let multiscalar_mul = 381 | List.fold_left2 (fun acc s p -> 382 | add_point (multiply_point p s ) acc ) 383 | 384 | end 385 | 386 | -------------------------------------------------------------------------------- /presentation/slides.tex: -------------------------------------------------------------------------------- 1 | \documentclass{beamer} 2 | \usetheme{Dresden} % My favorite! 3 | \usecolortheme{beaver} % Simple and clean template 4 | \usepackage{amssymb,latexsym} 5 | \usepackage{xltxtra, xgreek} 6 | \usepackage[boxed]{algorithm2e} 7 | \usepackage{float} 8 | \usepackage{textcomp} 9 | \usepackage{url} 10 | \usepackage{ocamldoc} 11 | \setsansfont[Mapping=tex-text]{CMU Concrete} 12 | \setmonofont{Courier New} 13 | \SetKw{Kwdto}{downto} 14 | 15 | %\usetheme{Boadilla} % Pretty neat, soft color. 16 | %\usetheme{default} 17 | %\usetheme{Warsaw} 18 | %\usetheme{Bergen} % This template has nagivation on the left 19 | %\usetheme{Frankfurt} % Similar to the default 20 | %with an extra region at the top. 21 | %\usecolortheme{seahorse} % Simple and clean template 22 | %\usetheme{Darmstadt} % not so good 23 | % Uncomment the following line if you want % 24 | % page numbers and using Warsaw theme% 25 | % \setbeamertemplate{footline}[page number] 26 | \setbeamercovered{transparent} 27 | %\setbeamercovered{invisible} 28 | % To remove the navigation symbols from 29 | % the bottom of slides% 30 | \setbeamertemplate{navigation symbols}{} 31 | \expandafter\def\expandafter\insertshorttitle\expandafter{% 32 | \insertshorttitle\hfill\insertframenumber\,/\,\inserttotalframenumber} 33 | 34 | 35 | 36 | 37 | 38 | %\usepackage{bm} % For typesetting bold math (not \mathbold) 39 | %\logo{\includegraphics[height=0.6cm]{yourlogo.eps}} 40 | % 41 | \title[Elliptic Curve Cryptography]{Υλοποίηση ανταλλαγής κλειδιού DH και ψηφιακών υπογραφών βασισμένη σε ελλειπτικές καμπύλες} 42 | \author{Νίκος Γιανναράκης \\ \and Ζωή Παρασκευοπούλου} 43 | 44 | \institute[] 45 | { 46 | Σχολή Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών\\ 47 | Εθνικό Μετσόβιο Πολυτεχνείο 48 | } 49 | \date{\today} 50 | \begin{document} 51 | 52 | \begin{frame} 53 | \titlepage 54 | \end{frame} 55 | \begin{frame} 56 | \frametitle{Κρυπτογραφία με ελλειπτικές καμπύλες} 57 | \begin{block} 58 | {Why elliptic curve cryptography?} 59 | \begin{itemize} 60 | \item Αυξημένη ασφάλεια με μικρότερα μήκη κλειδιών 61 | \item Μειωμένο υπολογιστικό κόστος και bandwitdh 62 | \item Ιδανικές για φορητές συσκευές λόγω ενεργειακών απαιτήσεων (κινητά κλπ.) 63 | \item ECC σε secure web servers, επιτάχυνση εως και $280\%$ \cite{SUN} 64 | \end{itemize} 65 | \end{block} 66 | \end{frame} 67 | 68 | % 69 | \begin{frame} 70 | \frametitle{Σύγκριση μήκους κλειδιού} 71 | \begin{figure} 72 | \begin{center} 73 | \begin{tabular}{|l|l|l|l|} \hline 74 | \textbf{ECC} & \textbf{RSA} & \textbf{Αναλογία} & \textbf{AES} \\ \hline 75 | 160 & 1024 & 1:6 & \\ \hline 76 | 256 & 3072 & 1:12 & 128 \\ \hline 77 | 384 & 7680 & 1:20 & 192 \\ \hline 78 | 512 & 15360 & 1:30 & 256 \\ \hline 79 | \end{tabular} 80 | \end{center} 81 | \caption{Σύγκριση μήκους κλειδιού σε bits} 82 | \end{figure} 83 | 84 | \begin{figure} 85 | \begin{center} 86 | \begin{small} 87 | \begin{tabular}{|l|l|l|} \hline 88 | & \textbf{ECC-160 \hspace{1em} RSA-1024} & \textbf{ECC-224 \hspace{1em} RSA-2048}\\ \hline 89 | Time(ms) & \hspace{1em} 3.69 \hspace{4.5em} 8.75 & \hspace{1em} 5.12 \hspace{4.5em} 56.18 \\ \hline 90 | Ops/Sec & \hspace{1em} 271.3 \hspace{4em} 114.3 & \hspace{1em} 195.5 \hspace{4.3em} 17.8 \\ \hline 91 | Perf ratio & \hspace{3.5em} 2.4 : 1.0 & \hspace{3.5em} 11.0 : 1.0 \\ \hline 92 | Key ratio & \hspace{3.5em} 1.0 : 6.4 & \hspace{3.5em} 1.0 : 9.1 \\ \hline 93 | \end{tabular} 94 | \end{small} 95 | \end{center} 96 | \caption{Σύγκριση απόδοσης ανάλογα με το μήκος κλειδιού \cite{SUN}} 97 | \end{figure} 98 | 99 | \end{frame} 100 | 101 | \begin{frame} 102 | \frametitle{Ελλειπτικές καμπύλες στο $\mathcal{R}$} 103 | \begin{block} 104 | {Ορισμός} 105 | Μία ελλειπτική καμπύλη στο $\mathcal{R}$ μπορεί να οριστεί ως το σύνολο των σημείων (x,y) που ικανοποιούν μία εξίσωση ελλειπτικής καμπύλης της μορφής: 106 | $$y^2 = x^3 + a \cdot x + b \; , \; x,y,a,b \in \mathcal{R}$$ 107 | μαζί με ένα σημείο $\mathcal{O}$, το οποίο ονομάζουμε σημείο στο άπειρο. 108 | \end{block} 109 | \begin{block} 110 | {Ορισμός πράξεων} 111 | \begin{itemize} 112 | \item Πρόσθεση δύο σημείων $P,Q$ 113 | \item Διπλασιασμός ενός σημείου $P$ 114 | \end{itemize} 115 | \end{block} 116 | \end{frame} 117 | 118 | 119 | % 120 | \begin{frame} 121 | \frametitle{Πρόσθεση δύο σημείων πάνω σε ελλειπτικές καμπύλες στο $\mathcal{R}$} 122 | H πρόσθεση δύο σημείων $P, Q$ μπορεί να οριστεί γεωμετρικά 123 | \begin{center} 124 | \includegraphics[scale=0.5]{add.png} 125 | 126 | \end{center}\end{frame} 127 | 128 | % 129 | \begin{frame} 130 | \frametitle{Διπλασιασμός σημείου πάνω σε ελλειπτικές καμπύλες στο $\mathcal{R}$} 131 | Ο διπλασιασμός ενός σημείου πάνω σε μία ελλειπτική καμπύλη ορίζεται γεωμετρικά σύμφωνα με το παρακάτω σχήμα 132 | \begin{center} 133 | \includegraphics[scale=0.5]{double.png} 134 | 135 | \end{center}\end{frame} 136 | 137 | % 138 | \begin{frame} 139 | \begin{block} 140 | {Προβλήματα} 141 | \begin{itemize} 142 | \item Αργές πράξεις σε πραγματικούς αριθμούς 143 | \item Έλλειψη ακρίβειας 144 | \end{itemize} 145 | \end{block} 146 | \end{frame} 147 | 148 | % 149 | \begin{frame} 150 | \frametitle{Ελλειπτικές καμπύλες πάνω από το $\mathbb{F}_p$ και το $\mathbb{F}_{2^m}$} 151 | \begin{block} 152 | {Ορισμός} 153 | Διαλέγοντας $a,b \in \mathbb{F}_p$ και υπολογίζοντας τα σημεία $(x,y)$ της καμπύλης $modulo \; p$ ορίζουμε μία ελλειπτική καμπύλη στο $\mathbb{F}_p$. 154 | \end{block} 155 | \end{frame} 156 | 157 | % 158 | \begin{frame} 159 | \frametitle{Πρόσθεση δύο σημείων πάνω σε ελλειπτικές καμπύλες στο $\mathbb{F}_p$} 160 | H πρόσθεση δύο σημείων $R = P + Q$ σε μία ελλειπτική καμπύλη στο $\mathbb{F}_p$ ορίζεται αλγεβρικά: 161 | \begin{align*} 162 | & s = \frac{(y_P - y_Q)}{(x_P - x_Q)} \pmod p \\ 163 | & x_R = s^2 - x_P - x_Q \pmod p \\ 164 | & y_R = -y_P + s \cdot (x_P - x_R) \pmod p 165 | \end{align*} 166 | \medskip 167 | Το $\mathcal{O}$ είναι το ουδέτερο στοιχείο της πρόσθεσης : $P + \mathcal{O} = P$. 168 | \end{frame} 169 | 170 | % 171 | \begin{frame} 172 | \frametitle{Διπλασιασμός σημείου πάνω σε ελλειπτικές καμπύλες στο $\mathbb{F}_p$} 173 | Ο διπλασιασμός σημείου $R = 2P$ σε μία ελλειπτική καμπύλη στο $\mathbb{F}_p$ ορίζεται αλγεβρικά: 174 | \begin{align*} 175 | & s = \frac{(3 \cdot x^2_P + a)}{2 \cdot y_P} \pmod p \\ 176 | & x_R = s^2 - 2 \cdot x _P \pmod p \\ 177 | & y_R = -y_p + s \cdot (x_P - x_R) \pmod p 178 | \end{align*} 179 | \end{frame} 180 | 181 | % 182 | \begin{frame} 183 | \frametitle{Βαθμωτός πολλαπλασιασμός πάνω σε ελλειπτικές καμπύλες στο $\mathbb{F}_p$} 184 | Με χρήση των παραπάνω πράξεων μπορούμε να ορίσουμε την πράξη του βαθμωτού πολλαπλασιασμού $R = k \cdot P$ όπου $l \in \mathbb{Z}$ και $P$ ένα σημείο ελλειπτικής καμπύλης. 185 | $P = \mathcal{O} \rightarrow k \cdot P = \mathcal{O}$ 186 | \begin{itemize} 187 | \item Naive $P + P \ldots + P$ 188 | \item Double-and-add (το ανάλογο του επαναλαμβανόμενου τετραγωνισμού) 189 | \item Windowed, Sliding-window, wNAF, \\ Montogomery ladder $\ldots$ \cite{BERN} 190 | \end{itemize} 191 | \end{frame} 192 | 193 | % 194 | \begin{frame} 195 | \frametitle{Double-and-add} 196 | \begin{algorithm}[H] 197 | \SetAlgoNoLine 198 | \KwIn{Elliptic curve $E$, elliptic curve point $P$, scalar $d$: $(d_0 d_1 \ldots d_{t-1})$ } 199 | \KwOut{$T = d \cdot P$ } 200 | $T \leftarrow P$ \\ 201 | \For{$i \leftarrow t -1$ \Kwdto $0$}{ 202 | $T \leftarrow T + T \pmod n$\\ 203 | \If{$d_i = 1$}{$T \leftarrow T + P \pmod n$} 204 | } 205 | \KwRet{T} 206 | \caption{Μέθοδος double-and-add} 207 | \end{algorithm} 208 | \end{frame} 209 | 210 | % 211 | \begin{frame} 212 | \frametitle{Το πρόβλημα του διακριτού λογαρίθμου σε ελλειπτικές καμπύλες (ECDLP)} 213 | \begin{block} 214 | {Ορισμός} 215 | 'Εστω ελλειπτική καμπύλη στο $\mathbb{F}_p$ και έστω δύο σημεία αυτής $P,Q$. Αν η τάξη του $P$ είναι $n$ τότε το πρόβλημα διακριτού λογαρίθμου ορίζεται ως η εύρεση ενός ακεραίου $ 0 \leq l \leq n -1$ τέτοιου ώστε $Q = l \cdot P$. 216 | \end{block} 217 | \end{frame} 218 | 219 | % 220 | \begin{frame} 221 | \frametitle{Ανταλλαγή κλειδιού με τη μέθοδο Diffie-Hellman για ελλειπτικές καμπύλες (ECDH)} 222 | \begin{itemize} 223 | \item Ο χρήστης Α και ο χρήστης Β επιλέγουν δημόσια τις παραμέτρους $D = (q, a, b, G, n, h)$ 224 | \item Ο χρήστης Α επιλέγει έναν τυχαίο αριθμό $1 \leq a \leq n -1$ ως ιδιωτικό κλειδί και υπολογίζει και στέλνει στον Β το δημόσιο κλειδί του $a \cdot G$. 225 | \item Ο χρήστης Β επιλέγει έναν τυχαίο αριθμό $1 \leq b \leq n -1$ ως ιδιωτικό κλειδί και υπολογίζει και στέλνει στον Α το δημόσιο κλειδί $b \cdot G$ και το στέλνει στον Α. 226 | \item Ο Α υπολογίζει το $a \cdot b \cdot G$ 227 | \item Ο Β υπολογίζει το $b \cdot a \cdot G$ 228 | \item Το κοινό κλειδί τους είναι το $a \cdot b \cdot G = b \cdot a \cdot G$ 229 | \end{itemize} 230 | \end{frame} 231 | 232 | % 233 | \begin{frame} 234 | \frametitle{Ψηφιακές υπογραφές με τον αλγόριθμο DSA για ελλειπτικές καμπύλες (ECDSA)} 235 | \begin{block} 236 | {Παραγωγή υπογραφής} 237 | Για να υπογράψει ένα μήνυμα $m$, ο χρήστης Α με παραμέτρους $D = (q, a, b, G, n, h)$ και ένα ζεύγος ιδιωτικού-δημόσιου κλειδιού $(d, Q)$ ακολουθεί τα παρακάτω βήματα 238 | \end{block} 239 | \end{frame} 240 | 241 | % 242 | \begin{frame} 243 | \frametitle{Ψηφιακές υπογραφές με τον αλγόριθμο DSA για ελλειπτικές καμπύλες (ECDSA)} 244 | \begin{block} 245 | {Παραγωγή υπογραφής} 246 | \begin{small} 247 | \begin{enumerate} 248 | \item Επιλέγει έναν τυχαίο αριθμό $k$ τέτοιο ώστε $1 \leq k \leq n-1$. 249 | \item Υπολογίζει το σημείο $k \cdot G = (x_1, y_1)$. 250 | \item Υπολογίζει το $r = x_1 \pmod n$. Αν $r = 0$ επιστρέφει στο βήμα $1$. 251 | \item Υπολογίζει το $k^{-1} \pmod n$. 252 | \item Υπολογίζει το $SHA-1(m)$ και μετατρέπει το αποτέλεσμα του bit-string σε έναν ακέραιο $e$. 253 | \item Υπολογίζει το $s = k^{-1} \cdot (e + d \cdot r) \pmod n$. Αν $s = 0$ επιστρέφει στο βήμα $1$. 254 | \item Η υπογραφή του A για το μήνυμα $m$ είναι $(r,s)$. 255 | \end{enumerate} 256 | \end{small} 257 | \end{block} 258 | \end{frame} 259 | 260 | % 261 | \begin{frame} 262 | \frametitle{Ψηφιακές υπογραφές με τον αλγόριθμο DSA για ελλειπτικές καμπύλες (ECDSA)} 263 | \begin{block} 264 | {Επαλήθευση υπογραφής} 265 | Για να επαληθεύσει μία υπογραφή $(r,s)$ σε ένα μήνυμα $m$, ο χρήστης Β παίρνει τις παραμέτρους $D = (q, FR, a, b, G, n, h)$ και το δημόσιο κλειδί $Q$ του Α και ακολουθεί τα παρακάτω βήματα: 266 | \end{block} 267 | \alert{Προσοχή! Ο Β θα πρέπει να ελέγξει ότι τα στοιχεία του Α δεν έχουν αλλοιωθεί, π.χ. αν το σημείο Q ανήκει στην καμπύλη που ορίζεται απο το D} 268 | \end{frame} 269 | 270 | % 271 | \begin{frame} 272 | \frametitle{Ψηφιακές υπογραφές με τον αλγόριθμο DSA για ελλειπτικές καμπύλες (ECDSA)} 273 | \begin{block} 274 | {Επαλήθευση υπογραφής} 275 | \begin{small} 276 | \begin{enumerate} 277 | \item Επιβεβαιώνει ότι τα $r,s$ είναι ακέραιοι στο διάστημα $[1, n-1]$. 278 | \item Υπολογίζει το $SHA-1(m)$ και μετατρέπει το αποτέλεσμα του bit-string σε έναν ακέραιο $e$. 279 | \item Υπολογίζει το $w = s^{-1} \pmod n$. 280 | \item Υπολογίζει το $u_1 = e \cdot w \pmod n$ και το $u_2 = r \cdot w \pmod n$. 281 | \item Υπολογίζει το $X = u_1 \cdot G + u_2 \cdot G$ 282 | \item Εάν $X = \mathcal{O}$ τότε απορρίπτει την υπογραφή. Αλλιώς υπολογίζει τo $u = x_1 \pmod n$ όπου $x_1$ η συντεταγμένη $x$ του $X$. 283 | \item Δέχεται την υπογραφή αν και μόνο αν $u = r$. 284 | \end{enumerate} 285 | \end{small} 286 | \end{block} 287 | \end{frame} 288 | 289 | % 290 | \begin{frame} 291 | \frametitle{Υλοποίηση} 292 | \begin{block} 293 | {Επιλογή παραμέτρων} 294 | \begin{figure}[!htbp] 295 | \begin{center} 296 | \begin{tabular}{|l|l|} \hline 297 | \textbf{Παράμετρος} & \textbf{Περιγραφή} \\ \hline 298 | p & Η χαρακτηριστική του πεπερασμένου σώματος $\mathbb{F}_p$ \\ \hline 299 | a & Ο συντελεστής a της ελλειπτικής καμπύλης \\ \hline 300 | b & Ο συντελεστής b της ελλειπτικής καμπύλης \\ \hline 301 | G & Ένα σημείο $G = (x_G, y_G)$ \\ \hline 302 | n & Η τάξη του στοιχείου $G$ \\ \hline 303 | h & $\sharp E(\mathbb{F}_p)/n$ \\ \hline 304 | \end{tabular} \\ 305 | \end{center} 306 | \caption{Domain Parameters} 307 | \end{figure} 308 | \alert{Απαιτείται πολύ προσεκτική επιλογή των παραμέτρων} \cite{ECDSA} \cite{SEC2} \cite{BPOOL} 309 | \end{block} 310 | \end{frame} 311 | 312 | % 313 | \begin{frame} 314 | \frametitle{Υλοποίηση} 315 | \begin{block} 316 | {Επίπεδα υλοποίησης} 317 | \begin{itemize} 318 | \item Αριθμητική modulo με υποστήριξη για μεγάλους αριθμούς 319 | \item Υλοποίηση των πράξεων που ορίζονται στην ομάδα (πρόσθεση, διπλασιασμός) 320 | \item Υλοποίηση του βαθμωτού πολλαπλασιασμού 321 | \item Υλοποίηση ενός κρυπτοσυστήματος π.χ. ECDH 322 | \end{itemize} 323 | \end{block} 324 | \end{frame} 325 | 326 | % 327 | \begin{frame} 328 | \frametitle{Υλοποίηση στη γλώσσα OCaml} 329 | \begin{block} 330 | {Why OCaml?} 331 | \begin{itemize} 332 | \item \textbf{Μείωση σφαλμάτων.} Έλεγχος τύπων κατά τη μεταγλώττιση. 333 | \item \textbf{Βιβλιοθήκες.} Αρκετές έτοιμες συναρτήσεις (για big numbers κ.α.) 334 | \item \textbf{Ταχύτητα.} Απόδοση αρκετά κοντά σε low-level γλώσσες όπως C. 335 | \item \textbf{Garbage collected.} Η διαχείριση μνήμης γίνεται αυτόματα, ένα πράγμα λιγότερο για να ανησυχούμε. 336 | \end{itemize} 337 | \end{block} 338 | \begin{flushright} 339 | \includegraphics[scale=0.7]{ocaml_logo.png} 340 | \end{flushright} 341 | \end{frame} 342 | 343 | % 344 | \begin{frame} 345 | \frametitle{Υλοποίηση στη γλώσσα OCaml} 346 | \begin{block} 347 | {Βασικοί τύποι} 348 | \label{type:Ecc.Ecc.point}\begin{ocamldoccode} 349 | type point = 350 | Infinity 351 | | Point of Z.t * Z.t 352 | \end{ocamldoccode} 353 | \begin{ocamldocdescription} 354 | An elliptic curve point. It is either infinity or a point (x,y). 355 | \end{ocamldocdescription} 356 | \index{point@\verb`point`} 357 | 358 | 359 | \label{type:Ecc.Ecc.elliptic-underscorecurve}\begin{ocamldoccode} 360 | type elliptic\_curve = {\char123}\\ 361 | p : Z.t ;\\ 362 | a : Z.t ;\\ 363 | b : Z.t ;\\ 364 | g : point ;\\ 365 | n : Z.t ;\\ 366 | h : Z.t ;\\ 367 | {\char125} 368 | \end{ocamldoccode} 369 | \index{elliptic-underscorecurve@\verb`elliptic_curve`} 370 | \begin{ocamldocdescription} 371 | The type of domain parameters 372 | \end{ocamldocdescription} 373 | \end{block} 374 | \end{frame} 375 | 376 | % 377 | \begin{frame} 378 | \frametitle{Υλοποίηση στη γλώσσα OCaml} 379 | \begin{block} 380 | {Modulo αριθμητική} 381 | Χρησιμοποιήθηκε η βιβλιοθήκη μεγάλων αριθμών Zarith, χρησιμοποιεί το GMP (C/C++). Διάφορες ετοιμες συναρτήσεις για βασικές πράξεις όπως εύρεση αντιστρόφου ενός αριθμού $modulo \; n$. 382 | \end{block} 383 | \end{frame} 384 | 385 | % 386 | \begin{frame} 387 | \frametitle{Υλοποίηση στη γλώσσα OCaml} 388 | \begin{block} 389 | {Υλοποίηση πράξεων ομάδας} 390 | \label{val:Ecc.Ecc.add-underscorepoint}\begin{ocamldoccode} 391 | val add\_point : point -> point -> elliptic\_curve -> point 392 | \end{ocamldoccode} 393 | \index{add-underscorepoint@\verb`add_point`} 394 | \begin{ocamldocdescription} 395 | Given two points P and Q, both on the same elliptic curve, and the elliptic curve returns P+Q on that curve. 396 | \end{ocamldocdescription} 397 | \label{val:Ecc.Ecc.double-underscorepoint}\begin{ocamldoccode} 398 | val double\_point : point -> elliptic\_curve -> point 399 | \end{ocamldoccode} 400 | \index{double-underscorepoint@\verb`double_point`} 401 | \begin{ocamldocdescription} 402 | Given a point P on an elliptic curve and the elliptic curve retuns the point 2P on that curve. 403 | \end{ocamldocdescription} 404 | \end{block} 405 | \end{frame} 406 | 407 | % 408 | \begin{frame} 409 | \frametitle{Υλοποίηση στη γλώσσα OCaml} 410 | \begin{block} 411 | {Υλοποίηση βαθμωτού πολλαπλασιασμού} 412 | \label{val:Ecc.Ecc.multiply-underscorepoint}\begin{ocamldoccode} 413 | val multiply\_point : point -> Z.t -> elliptic\_curve -> point 414 | \end{ocamldoccode} 415 | \index{multiply-underscorepoint@\verb`multiply_point`} 416 | \begin{ocamldocdescription} 417 | Given a point P on an elliptic curve, an integer k and the elliptic curve returns the scalar multiplication kP on that curve. 418 | \end{ocamldocdescription} 419 | \end{block} 420 | \end{frame} 421 | 422 | % 423 | \begin{frame} 424 | \frametitle{Υλοποίηση στη γλώσσα OCaml} 425 | \begin{block} 426 | {Υλοποίηση δημιουργίας ζεύγους κλειδιών} 427 | \label{val:Ecc.Ecc.create-underscorekeys}\begin{ocamldoccode} 428 | val create\_keys : elliptic\_curve -> point * Z.t 429 | \end{ocamldoccode} 430 | \index{create-underscorekeys@\verb`create_keys`} 431 | \begin{ocamldocdescription} 432 | Creates a tuple (public\_key, secret\_key) where public\_key is a point of the curve and secret\_key an integer. 433 | \end{ocamldocdescription} 434 | \end{block} 435 | \end{frame} 436 | 437 | 438 | % 439 | \begin{frame} 440 | \frametitle{Υλοποίηση στη γλώσσα OCaml} 441 | \begin{block} 442 | {Υλοποίηση ψηφιακής υπογραφής} 443 | \label{val:Ecc.Ecc.sign}\begin{ocamldoccode} 444 | val sign : string -> Z.t -> elliptic\_curve -> Z.t * Z.t 445 | \end{ocamldoccode} 446 | \index{sign@\verb`sign`} 447 | \begin{ocamldocdescription} 448 | \textbf{Ecc.sign message sk curve} where sk is secret key of the user s and curve the public elliptic curve, returns the signature (r, s) of the message. 449 | 450 | 451 | \end{ocamldocdescription} 452 | 453 | 454 | \label{val:Ecc.Ecc.verify}\begin{ocamldoccode} 455 | val verify : string -> Z.t * Z.t -> point -> elliptic\_curve -> bool 456 | \end{ocamldoccode} 457 | \index{verify@\verb`verify`} 458 | \begin{ocamldocdescription} 459 | \textbf{Ecc.verify message (r, s) pk curve} where pk is the public key of the user who signed the message, returns true if the (r, s) is a valid signature or false otherwise. 460 | \end{ocamldocdescription} 461 | 462 | \end{block} 463 | \end{frame} 464 | 465 | 466 | 467 | % 468 | \begin{frame} 469 | \frametitle{Βελτιστοποίησεις} 470 | \begin{block} 471 | {Βελτιστοποίηση αριθμητικής modulo} 472 | Το πιο χρονοβόρο κομμάτι είναι οι πράξεις με μεγάλους αριθμούς και η αριθμητική modulo. Η χρήση της βιβλιοθήκης Zarith μας λύνει το πρόβλημα βελτιστοποίησεις αυτού του κομματιού καθώς χρησιμοποιεί το GMP που έχει γρήγορες υλοποιήσεις πράξεων στη γλώσσα C. 473 | \end{block} 474 | \begin{block} 475 | {Βελτιστοποίηση πράξεων} 476 | Οι συναρτήσεις add\_point και double\_point δεν παρουσιάζουν ιδιαίτερα περιθώρια βελτιστοποίησης. Μπορούμε να βελτιστοποιήσουμε τη συνάρτηση multiply\_point χρησιμοποιώντας έναν καλύτερο αλγόριθμο από αυτούς που έχουν αναφερθεί (η υλοποίηση μας χρησιμοποιεί τη μέθοδο double-and-add) 477 | \end{block} 478 | \end{frame} 479 | 480 | % 481 | \begin{frame} 482 | \frametitle{Επιθέσεις} 483 | \begin{itemize} 484 | \item Επίλυση ECDLP (πρακτικά ανέφικτο με κατάλληλη επιλογή παραμέτρων) 485 | \item Επίθεση στη συνάρτηση κατακερματισμού (hash function) εαν χρησιμοποιείται. 486 | \item Κακή διαχείριση κλειδιών (private key, αριθμός $k$ στο ECDSA) κλπ. 487 | \end{itemize} 488 | \end{frame} 489 | 490 | % 491 | \begin{frame} 492 | \frametitle{Επίλυση του ECDLP} 493 | \begin{block} 494 | {Certicom ECC Challenge} 495 | \begin{itemize} 496 | \item Στόχος είναι να βρεθούν τα ιδιωτικά κλειδιά απο μία δοθείσα λίστα με δημόσια κλειδιά και τις αντίστοιχες παραμέτρους. 497 | \item Επίπεδο 1 : 109-bit, 131-bit 498 | \item Επίπεδο 2 : 163-bit, 191-bit, 239-bit, 359-bit 499 | \item Το 2004 λύθηκε το πρόβλημα για τα 109-bit από $10000$ υπολογιστές σε 549 μέρες χρησιμοποιώντας τη μέθοδο rho. Για τα 131-bit όμως θα χρειαστούν σημαντικά περισσότεροι πόροι. 500 | \item Τα προβλήματα στο επίπεδο 2 θεωρούνται υπολογιστικά ανέφτικα. 501 | \end{itemize} 502 | \end{block} 503 | \end{frame} 504 | 505 | % 506 | \begin{frame} 507 | \frametitle{Επίθεση στο ECDSA} 508 | \begin{block} 509 | {Sony Playstation 3} 510 | Το playstation 3 χρησιμοποιεί το σχήμα ψηφιακής υπογραφής ECDSA για ψηφιακές υπογραφές στα παιχνίδια και στις αναβαθμίσεις του firmware του έτσι ώστε να μην επιτρέπεται σε unsigned κώδικα να εκτελεστεί στην κονσόλα. 511 | \end{block} 512 | \end{frame} 513 | 514 | % 515 | \begin{frame} 516 | \frametitle{Επίθεση στο ECDSA} 517 | \begin{block} 518 | {Επιλογή τυχαίου αριθμού $k$} 519 | \begin{itemize} 520 | \item Ο τυχαίος αριθμός $k$ έχει τις ίδιες απαιτήσεις ασφάλειας με το ιδιωτικό κλειδί $d$. 521 | \item Αυτό συνεπάγεται απο το γεγονός οτι αν ο κακόβουλος χρήστης Ε ανακτήσει ένα $k$ που χρησιμοποιεί ο Α για να υπογράψει ένα μήνυμα $m$ τότε μπορεί να ανακτήσει το ιδιωτικό κλειδί του A αφού $d = r^{-1} \cdot (k \cdot s - e) \pmod n$. 522 | \item Συνεπώς το $k$ θα πρέπει να παράγεται με ασφαλή τρόπο και να αποθηκεύεται με ασφαλή τρόπο. 523 | \end{itemize} 524 | \end{block} 525 | \end{frame} 526 | 527 | % 528 | \begin{frame} 529 | \frametitle{Επίθεση στο ECDSA} 530 | \begin{block} 531 | {Sony Playstation 3 τρόπος επιλογής \textbf{τυχαίου} $k$} 532 | \begin{itemize} 533 | \item Η Sony δε παρήγαγε ποτέ τυχαίο $k$ αλλά χρησιμοποιούσε μία σταθερά για $k$ 534 | \item Με τον τρόπο που δείξαμε παραπάνω υπολογίστηκε το private key της Sony και δόθηκε η δυνατότητα να κάνουμε sign ότι κώδικα θέλουμε. \cite{PS3} 535 | \end{itemize} 536 | \end{block} 537 | \end{frame} 538 | 539 | \begin{frame} 540 | \frametitle{Παραγωγή τυχαίων αριθμών!} 541 | \includegraphics[scale=0.7]{random_number.png} 542 | \end{frame} 543 | 544 | \begin{frame} 545 | \frametitle{References} 546 | \footnotesize{ 547 | \begin{thebibliography}{99} 548 | \bibitem[1]{ECDSA} [1] Don Johnson, Alfred Menezes, Scott Vanstone, 549 | \newblock The Elliptic Curve Digital Signature Algorithm (ECDSA) 550 | \newblock \emph{Certicom Research} 551 | \bibitem[2]{SEC2} [2] Certicom Research 552 | \newblock SEC 2: Recommended Elliptic Curve Domain Parameters 553 | \newblock \emph{Certicom Research} 554 | \bibitem[3]{BERN} [3] Daniel J. Bernstein, Tanja Lange 555 | \newblock Analysis and optimization of elliptic-curve single-scalar multiplication 556 | \bibitem[4]{BPOOL} [4] Brainpool 557 | \newblock ECC Brainpool Standard Curves and Curve Generation v1.0 558 | \newblock \emph{Brainpool} 559 | \end{thebibliography} 560 | } 561 | \end{frame} 562 | 563 | \begin{frame} 564 | \frametitle{References} 565 | \footnotesize{ 566 | \begin{thebibliography}{99} 567 | \bibitem[5]{PAAR} [5] Chrisoft Paar, Jan pelzl, 568 | \newblock Understanding Cryptography: A textbook for Students and Practitioners 569 | \newblock \emph{Springer} 570 | \bibitem[6]{SUN} [6] Vipul Gupta, Douglas Stebila, Stephen Fung, Sheueling Chang, Nils Gura, Hans Eberle 571 | \newblock Speeding up secure web transactions using elliptic curve cryptography 572 | \newblock \emph{Sun Microsystems Labs} 573 | \bibitem[7]{PS3} [7] bushing, marcan, sgher, sven 574 | \newblock PS3 Epic Fail 575 | \newblock \emph{fail0verflow} 576 | \end{thebibliography} 577 | } 578 | \end{frame} 579 | 580 | 581 | \begin{frame} 582 | \begin{block} 583 | {Fork here!} 584 | https://github.com/zoep/ECC-OCaml 585 | \end{block} 586 | \bigskip 587 | \begin{block} 588 | {The end} 589 | \end{block} 590 | \end{frame} 591 | % End of slides 592 | \end{document} -------------------------------------------------------------------------------- /report/report.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass[12pt]{article} 3 | \usepackage[cm]{fullpage} 4 | \usepackage[usenames,dvipsnames]{color} 5 | \usepackage{sectsty} 6 | \usepackage{listings} 7 | \usepackage{color} 8 | \usepackage{textpos} 9 | \usepackage[usenames,dvipsnames,table]{xcolor} 10 | \usepackage[small, bf]{caption} 11 | \usepackage{amssymb,latexsym} 12 | \usepackage{amsmath} 13 | \usepackage{xltxtra,xunicode,xgreek} 14 | \usepackage[colorlinks=true, linkcolor = blue, citecolor=blue]{hyperref} 15 | \usepackage[ddmmyyyy]{datetime} 16 | \usepackage{multirow} 17 | \usepackage{tikz} 18 | \usepackage{qtree} 19 | \usepackage{float} 20 | \usepackage{minted} 21 | \usepackage[boxed]{algorithm2e} 22 | \usepackage{textcomp} 23 | \usepackage{fullpage} 24 | \usepackage{url} 25 | \usepackage{ocamldoc} 26 | 27 | 28 | \definecolor{lightgray}{gray}{0.95} 29 | \setmainfont[Mapping=tex-text]{CMU Concrete} 30 | \setmonofont{Courier New} 31 | \newcommand{\tab}{\hspace*{2em}} 32 | \newcommand{\rom}[1]{\uppercase\expandafter{\romannumeral #1\relax}} 33 | \setlength{\parindent}{0pt} 34 | \renewcommand\listingscaption{Κώδικας} 35 | 36 | \usemintedstyle{tango} 37 | \SetKw{Kwdto}{downto} 38 | 39 | \begin{document} 40 | \begin{titlepage} 41 | \begin{center} 42 | 43 | \includegraphics[scale=0.3]{pyrforos.jpg}\\ 44 | ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ \\ 45 | ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ KΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ \\ 46 | \vspace{0.5em} 47 | 48 | \medskip 49 | 50 | \def\doubleline{ 51 | 52 | \vspace{0.1em} 53 | \line(1,0){530}\ 54 | 55 | \vspace{-1.5em} 56 | \line(1,0){530} 57 | 58 | } 59 | \doubleline 60 | \vspace{1.3em} 61 | 62 | {\large \textbf{Στοιχεία Θεωρίας Αριθμών και Εφαρμογές στην Κρυπτογραφία}\\ 63 | \medskip 64 | 9ο εξάμηνο, Ακαδημαϊκή περίοδος 2012-2013 \\ \bigskip \medskip} 65 | 66 | \vspace{1.5em} 67 | {\LARGE \textbf{Υλοποίηση κρυπτοσυστήματος και ψηφιακής υπογραφής με χρήση ελλειπτικών καμπυλών\\}} 68 | \vspace{32em} 69 | 70 | \begin{tabular}{l l} 71 | Νίκος Γιανναράκης & 03108054 \\ 72 | Ζωή Παρασκευοπούλου & 03108152 \\ 73 | \end{tabular}\\ 74 | \bigskip 75 | \today 76 | \end{center} 77 | \end{titlepage} 78 | \tableofcontents 79 | 80 | \pagebreak 81 | 82 | \section{Ελλειπτικές καμπύλες} 83 | 84 | \subsection{Εισαγωγή} 85 | Πολλά συστήματα κρυπτογραφίας βασίζονται σε πράξεις πάνω σε κάποια αλγεβρική ομάδα. Μπορούμε να χρησιμοποιήσουμε μία ελλειπτική καμπύλη για να ορίσουμε μία ομάδα και έπειτα περιορίζοντας τα σημεία αυτής να ορίσουμε ένα σώμα. Θα δείξουμε αρχικά τις πράξεις που ορίζονται πάνω σε μία τέτοια ομάδα στο πεδίο των πραγματικών αριθμών και μετά στο $\mathcal{F}_p$. 86 | \subsection{Ελλειπτικές καμπύλες στο $\mathcal{R}$} 87 | Μία ελλειπτική καμπύλη στο $\mathcal{R}$ μπορεί να οριστεί ως ένα set σημείων (x,y) που ικανοποιούν μία εξίσωση ελλειπτικής καμπύλης της μορφής: 88 | $$y^2 = x^3 + a \cdot x + b \; , \; x,y,a,b \in \mathcal{R}$$ 89 | Ανάλογα με την επιλογή των a και b έχουμε μία διαφορετική ελλειπτική καμπύλη. Για να ορίσουμε μία ομάδα από μία τέτοια ελλειπτική καμπύλη θα πρέπει το $x^3 + a \cdot x + b$ να μην έχει πολλαπλές ρίζες, δηλαδή να ισχύει $4 \cdot a^3 + 27 \cdot b^2 \neq 0$. Σε αυτή την περίπτωση μία τέτοια ομάδα ορίζεται απο τα σημεία που αποτελούν την ελλειπτική καμπύλη μαζί με ένα ακόμα σημείο $\mathcal{O}$ που θεωρείται το σημείο στο άπειρο. 90 | \subsubsection{Ορισμένες πράξεις σε ελλειπτικές καμπύλες πάνω στο $\mathcal{R}$} 91 | \paragraph{Αντίθετο σημείο} 92 | Αν για δύο σημεία $P = (x_P, y_P)$ και $Q = (x_Q, y_Q)$ ισχύει ότι $Q = (x_P, -y_P)$ τότε λέμε ότι $P = -Q$. Γεωμετρικά αυτό σημαίνει οτι το $Q$ είναι συμμετρικό του $P$ ως προς τον άξονα x. 93 | \paragraph{Πρόσθεση δύο σημείων} 94 | Θα ορίσουμε την πρόσθεση δύο σημείων σε μία ελλειπτική καμπύλη γεωμετρικά. Έστω δύο σημεία $P$ και $Q$ για τα οποία ισχύει ότι $P \neq -Q$. Για να υπολογίσουμε το $R = P + Q$ φέρουμε μία ευθεία που τέμνει και τα δύο σημεία. Η ευθεία αυτή θα τέμνει την καμπύλη σε ακρίβως ένα σημείο ακόμα, το $-R$. Το αντίθετο αυτού είναι το άθροισμα $P+Q = R$. 95 | Για την περίπτωση όπου $P = -Q$ ισχύει $P + (-P) = \mathcal{O}$. 96 | Επίσης ισχύει ότι $P +\mathcal{O} = P$. 97 | 98 | \begin{figure}[H] 99 | \center 100 | \includegraphics[scale=0.7]{add.png} 101 | \caption{Πρόσθεση δύο σημείων \cite{PAAR}} 102 | \end{figure} 103 | 104 | \paragraph{Διπλασιασμός σημείου} 105 | Για την πρόσθεση ενός σημείου $P$ στον εαυτό του φέρουμε ευθεία εφαπτόμενη στο $P$. Αν $y_P \neq 0$ τότε αυτή θα τέμνει την καμπύλη σε ένα ακόμα σημείο, έστω $-R$. Ισχύει ότι $P + P = 2 \cdot P = R$. 106 | Στην περίπτωση που $y_p = 0$ τότε $P + P = 2 \cdot P = \mathcal{O}$. 107 | 108 | \begin{figure}[H] 109 | \center 110 | \includegraphics[scale=0.7]{double.png} 111 | \caption{Διπλασιασμός σημείου \cite{PAAR}} 112 | \end{figure} 113 | \subsection{Ελλειπτικές καμπύλες πάνω από το σώμα $\mathbb{F}_p$.} 114 | Οι πράξεις πάνω σε πραγματικούς αριθμούς είναι αργές και στερούνται ακρίβειας λόγω στρογγυλοποιήσεων. Καθώς οι εφαρμογές κρυπτογραφίας απαιτούν ταχύτητα και ακρίβεια στις πράξεις προτιμούνται ελλειπτικές καμπύλες στο σώμα $\mathbb{F}_p$ ή $F_{2^m}$. 115 | Για να ορίσουμε μία ελλειπτική καμπύλη στο $\mathbb{F}_p$ αρκεί να διαλέξουμε $a,b \in \mathbb{F}_p$. Όλα τα σημεία $(x,y)$ της καμπύλης θα ικανοποιούν την εξίσωση αυτής $modulo \; p$. 116 | 117 | \subsubsection{Ορισμένες πράξεις σε σε ελλειπτικές καμπύλες πάνω στο $\mathbb{F}_p$} 118 | Μία γεωμετρική προσέγγιση θα αποτύχει σε αυτή την περίπτωση λόγω του πεπερασμένου πλήθους σημείων. Για το λόγο αυτό θα χρησιμοποιήσουμε τις αντίστοιχες αλγεβρικές εξισώσεις. 119 | \paragraph{Αντίθετο σημείο} 120 | Αν για δύο σημεία $P = (x_P, y_P)$ και $Q = (x_Q, y_Q)$ ισχύει ότι $Q = (x_P, -y_P)$ τότε λέμε ότι $P = -Q$. 121 | \paragraph{Πρόσθεση δύο σημείων} 122 | Έστω δύο σημεία $P$ και $Q$ για τα οποία ισχύει ότι $P \neq -Q$. 123 | Έστω ο συντελέστης της ευθείας απο το $P$ στο $Q$ $$s = \frac{(y_P - y_Q)}{(x_P - x_Q)} \pmod p$$ 124 | Για το $R = P + Q$ θα ισχύει: 125 | \begin{align*} 126 | & x_R = s^2 - x_P - x_Q \pmod p \\ 127 | & y_R = -y_P + s \cdot (x_P - x_R) \pmod p 128 | \end{align*} 129 | \paragraph{Διπλασιασμός σημείου} 130 | Αν $y_P \neq 0$ τότε $P + P = 2 \cdot P = R$ όπου το $R$ υπολογίζεται από τις παρακάτω σχέσεις: 131 | \begin{align*} 132 | & s = \frac{(3 \cdot x^2_P + a)}{2 \cdot y_P} \pmod p \\ 133 | & x_R = s^2 - 2 \cdot x _P \pmod p \\ 134 | & y_R = -y_p + s \cdot (x_P - x_R) \pmod p 135 | \end{align*} 136 | \subsection{Ελλειπτικές καμπύλες πάνω από το σώμα $F_{2^m}$.} 137 | Τα στοχεία του σώματος $F_{2^m}$ είναι m-bit strings για το λόγο αυτό οι υπολογιστές μπορούν να εκτελέσουν αριθμητικές πράξεις πάνω σε αυτά πολύ αποδοτικά. Οι πράξεις δε διαφέρουν από αυτές που ορίσαμε παραπάνω. 138 | 139 | \pagebreak 140 | 141 | \section{Το πρόβλημα του διακριτού λογαρίθμου σε ελλειπτικές καμπύλες (ECDLP)} 142 | Κάθε σύστημα κρυπτογραφίας βασίζεται σε ένα υπολογιστικό πρόβλημα, συνήθως δύσκολο στον υπολογισμό του απουσία κάποιας πληροφορίας, π.χ. ενός secret key. Μπορούμε να φτιάξουμε συστήματα κρυπτογραφίας που βασίζονται στη δυσκολία υπολογισμού του διακριτού λογάριθμου σε ελλειπτικές καμπύλες (ECDLP). 143 | \subsection{Βαθμωτός Πολλαπλασιασμός} 144 | Ο βαθμωτός πολλαπλασιασμός ενός σημείου $P$ της ελλειπτικής καμπύλης πάνω στο $\mathbb{F}_p$ με έναν ακέραιο $k$ μικρότερο της τάξης του $P$ ορίζεται ώς ένα νέο σημείο $R = k \cdot P = P + P + \cdots + P$ και μπορεί να επιτευχθεί με τις πράξεις πρόσθεσης και διπλασιασμού σημείου που ορίζονται στην ομάδα που ορίζει μια ελλειπτική καμπύλη στο $\mathbb{F}_p$ 145 | \subsection{ECDLP} 146 | Με βάση λοιπόν τον βαθμωτό πολλαπλασιασμό ορίζουμε το διακριτό πρόβλημα του λογαρίθμου σε ελλειπτικές καμπύλες ως εξής: 147 | 148 | Έστω $Q = k \cdot P$ όπου $Q, P$ γνωστά σημεία της ελλειπτικής καμπύλης και $k$ ένας ακέραιος. Το $k$ ονομάζεται διακριτός λόγαριθμος του $Q$ στη βάση $P$ και ζητούμενο του προβλήματος είναι ο υπολογισμός του. 149 | \subsection{Elliptic curve Diffie-Hellman (ECDH)} 150 | Το σχήμα ανταλλαγής κλειδιού Diffie-Hellman για ελλειπτικές καμπύλες ακολουθεί την ίδια λογική με το Diffie-Hellman και στηρίζεται στο ECDLP. 151 | Η διαδικασία που ακολουθείται παρουσιάζεται παρακάτω: 152 | Αρχικά επιλέγονται δημόσια ένα πεπερασμένο σώμα $\mathbb{F}_p$, μία ελλειπτική καμπύλη πάνω σε αυτό το σώμα και ένα σημείο $G$ αυτής (domain parameters). 153 | 154 | Έπειτα οι χρήστες Α και Β κάνουν τα παρακάτω: 155 | \begin{itemize} 156 | \item Επιλέγουν τυχαία έναν αριθμό $d_A$ και $d_B$ αντίστοιχα για τους οποίους ισχύει ότι $d_A < ord(G)$ και $d_B < ord(G)$. 157 | \item Υπολογίζουν το $Q_A = d_A \cdot G$ και $Q_B = d_B \cdot G$ με χρήση βαθμωτού πολλαπλασιασμού. 158 | \item Έχοντας σχηματίσει ένα ζεύγος public-private key $(Q_A,d_A)$ και $(Q_B, d_B)$ αντίστοιχα δημοσιεύουν τα $Q_A, Q_B$. 159 | \item Ο χρήστης Α υπολογίζει το $K = d_A \cdot Q_B$ και ο χρήστης Β το $K = d_B \cdot Q_A$. 160 | \item Έτσι τελικά και οι 2 έχουν υπολογίσει το $K = d_A \cdot d_B \cdot G = d_B \cdot d_A \cdot G$, χωρίς να είναι εφικτό για κάποιον τρίτο να το υπολογίσει χωρίς να λύσει το πρόβλημα του διακριτού λογαρίθμου για ελλειπτικές καμπύλες. 161 | \end{itemize} 162 | \subsection{Elliptic curve digital signature algorithm (ECDSA)} 163 | \paragraph{Παραγωγή υπογραφής} 164 | Για να υπογράψει ένα μήνυμα $m$, ο χρήστης Α με παραμέτρους $D = (q, FR, a, b, G, n, h)$ και ένα ζεύγος ιδιωτικού-δημόσιου κλειδιού $(d, Q)$ ακολουθεί τα παρακάτω βήματα: 165 | \begin{enumerate} 166 | \item Επιλέγει έναν τυχαίο αριθμό $k$ τέτοιο ώστε $1 \leq k \geq n-1$. 167 | \item Υπολογίζει το σημείο $k \cdot G = (x_1, y_1)$. 168 | \item Υπολογίζει το $r = x_1 \pmod n$. Αν $r = 0$ επιστρέφει στο βήμα $1$. 169 | \item Υπολογίζει το $k^{-1} \pmod n$. 170 | \item Υπολογίζει το $SHA-1(m)$ και μετατρέπει το αποτέλεσμα του bit-string σε έναν ακέραιο $e$. 171 | \item Υπολογίζει το $s = k^{-1} \cdot (e + d \cdot r) \pmod n$. Αν $s = 0$ επιστρέφει στο βήμα $1$. 172 | \item Η υπογραφή του A για το μήνυμα $m$ είναι $(r,s)$. 173 | \end{enumerate} 174 | 175 | \paragraph{Επαλήθευση υπογραφής} 176 | Για να επαληθέυση μία υπογραφή $(r,s)$ σε ένα μήνυμα $m$, ο χρήστης Β με παραμέτρους $D = (q, FR, a, b, G, n, h)$ και ένα δημόσιο κλειδί $Q$ θα πρέπει αρχικά να επαληθεύσει την ορθότητα των $D$ και $Q$ καθώς μπορεί το $Q$ να έχει τροποποιηθεί απο κάποιον κακόβουλο χρήστη \cite{ECDSA}, έπειτα ακολουθεί τα παρακάτω βήματα: 177 | \begin{enumerate} 178 | \item Επιβεβαιώνει ότι τα $r,s$ είναι ακέραιοι στο διάστημα $[1, n-1]$. 179 | \item Υπολογίζει το $SHA-1(m)$ και μετατρέπει το αποτέλεσμα του bit-string σε έναν ακέραιο $e$. 180 | \item Υπολογίζει το $w = s^{-1} \pmod n$. 181 | \item Υπολογίζει το $u_1 = e \cdot w \pmod n$ και το $u_2 = r \cdot w \pmod n$. 182 | \item Υπολογίζει το $X = u_1 \cdot G + u_2 \cdot G$ 183 | \item Εάν $X = \mathcal{O}$ τότε απορρίπτει την υπογραφή. Αλλιώς υπολογίζει τo $u = x_1 \pmod n$ όπου $x_1$ η συντεταγμένη $x$ του $X$. 184 | \item Δέχεται την υπογραφή αν και μόνο αν $u = r$. 185 | \end{enumerate} 186 | \pagebreak 187 | 188 | \section{Υλοποίηση ενός συστήματος κρυπτογραφίας βασισμένο σε ελλειπτικές καμπύλες} 189 | \subsection{Πλεονεκτήματα χρήσης} 190 | Ένας από τους κύριους λόγους χρησιμοποιήσης ελλειπτικών καμπυλών για υλοποίηση συστημάτων κρυπτογραφίας είναι ότι μπορούν να προσφέρουν τον ίδιο βαθμό ασφάλειας με συστήματα όπως το RSA ή το Diffie-Hellman με πολύ μικρότερο μήκος κλειδιού. Έτσι μειώνεται το υπολογιστικό κόστος χωρίς να επηρεάζεται ο βαθμός ασφάλειας. Στον παρακάτω πίνακα παρουσιάζεται το απαιτούμενο μήκος κλειδιού σε bits για το ECC ώστε να επιτευχθεί ανάλογος βαθμός ασφάλειας με αυτή των RSA και AES για διάφορα μήκη κλειδιών. 191 | \\ \medskip 192 | 193 | 194 | \begin{figure}[!htbp] 195 | \begin{center} 196 | \begin{tabular}{|l|l|l|l|} \hline 197 | \textbf{ECC} & \textbf{RSA} & \textbf{Αναλογία} & \textbf{AES} \\ \hline 198 | 163 & 1024 & 1:6 & \\ \hline 199 | 256 & 3072 & 1:12 & 128 \\ \hline 200 | 384 & 7680 & 1:20 & 192 \\ \hline 201 | 512 & 15360 & 1:30 & 256 \\ \hline 202 | \end{tabular} \\ 203 | \end{center} 204 | \caption{Αντιστοιχία μήκος κλεδιού σε bits του ECC με RSA και AES} 205 | \end{figure} 206 | 207 | 208 | Για το λόγο αυτό τα συστήμα κρυπτογραφίας βασισμένα σε ελλειπτικές καμπύλες χρησιμοποιούνται ευρέως σε συσκευές με περιορισμένες υπολογιστικές δυνατότητες και σε συσκευές που απαιτείται χαμηλή κατανάλωση ενέργειας, όπως κινητά για παράδειγμα. 209 | 210 | \subsection{Επιλογή παραμέτρων} 211 | Για την αποφυγή επιθέσεων προς το κρυπτοσύστημα απαιτείται κατάλληλη επιλογή των παραμέτρων αυτού. 212 | Οι παράμετροι αυτοί είναι: 213 | 214 | \begin{figure}[!htbp] 215 | \begin{center} 216 | \begin{tabular}{|l|l|} \hline 217 | \textbf{Παράμετρος} & \textbf{Περιγραφή} \\ \hline 218 | p & Η χαρακτηριστική του πεπερασμένου σώματος $\mathbb{F}_p$ \\ \hline 219 | a & Ο συντελεστής a της ελλειπτικής καμπύλης \\ \hline 220 | b & Ο συντελεστής b της ελλειπτικής καμπύλης \\ \hline 221 | G & Ένα σημείο $G = (x_G, y_G)$ της ελλειπτικής καμπύλης (base point) \\ \hline 222 | n & Η τάξη του στοιχείου $G$ \\ \hline 223 | h & $\sharp E(\mathbb{F}_p)/n$ \\ \hline 224 | \end{tabular} \\ 225 | \end{center} 226 | \caption{Παράμετροι ECC} 227 | \end{figure} 228 | 229 | Οι παραπάνω παράμετροι είναι πολύ σημαντικοί για την ασφάλεια του κρυπτοσυστήματος για αυτό και χρειάζεται ιδιαίτερη μέριμνα στην επιλογή τους. Σχετικά με το ποίες είναι οι επιθυμητές ιδιότητες ασφάλειας των παραμέτρων, πως να παράγουμε παραμέτρους με βάση αυτές και πως να επικυρώσουμε ότι ένα set παραμέτρων έχει τις ιδιότητες αυτές ο αναγνώστης προτρέπεται να ανατρέξει στα \cite{BPOOL}, \cite{SEC2} και\cite{ECDSA}. 230 | Επίσης μπορούμε να χρησιμοποιήσουμε και ένα έτοιμο set παραμέτρων, τακτική που ακολουθήσαμε και εμείς στην υλοποίηση μας με το \emph{brainpoolP256r1} \cite{BPOOL}. 231 | 232 | \subsection{Επίπεδα υλοποίησης} 233 | Η υλοποίηση ενός συστήματος κρυπτογραφίας μπορεί να γίνει σε 4 επίπεδα: 234 | \begin{itemize} 235 | \item Στο χαμηλότερο επίπεδο είναι η υλοποίηση modulo αριθμητικής που υπολογιστικά είναι και το πιο ακριβό μέρος. 236 | \item Υλοποίηση των ορισμένων πράξεων της ομάδας, δηλαδή της πρόσθεσης και του διπλασιασμού σημείου. 237 | \item Υλοποίηση του βαθμωτού πολλαπλασιασμού 238 | \item Στο υψηλότερο επίπεδο είναι η υλοποίηση ενός κρυπτοσυστήματος όπως το ECDH και το ECDSA. 239 | \end{itemize} 240 | 241 | \subsection{Αλγόριθμοι υλοποίησης βαθμωτού πολλαπλασιασμού} 242 | Ο πιο απλός τρόπος να υπολογίσουμε το $k \cdot P$ είναι να κάνουμε $k$ προσθέσεις του σημείου $P$ με τον εαυτό του, ωστόσο αυτό δεν είναι καθόλου αποδοτικό. 243 | Για να κατασκευάσουμε ένα αποδοτικό κρυπτοσύστημα χρειαζόμαστε έναν αποδοτικό τρόπο εκτέλεσης βαθμωτού πολλαπλασιασμού. 244 | Ένας αποδοτικός τρόπος είναι με τη μέθοδο double-and-add \cite{PAAR}. \\ 245 | %PSEUDOCODE HERE% 246 | \medskip 247 | 248 | \begin{algorithm}[H] 249 | \SetAlgoNoLine 250 | \KwIn{Elliptic curve $E$, elliptic curve point $P$, scalar $d$: $(d_1 d_2 \ldots d_t)$ } 251 | \KwOut{$T = d \cdot P$ } 252 | $T \leftarrow P$ \\ 253 | \For{$i \leftarrow t -1$ \Kwdto $0$}{ 254 | $T \leftarrow T + T \pmod n$\\ 255 | \If{$d_i = 1$}{$T \leftarrow T + P \pmod n$} 256 | } 257 | \KwRet{T} 258 | \caption{Μέθοδος double-and-add} 259 | \end{algorithm} 260 | 261 | \bigskip 262 | Υπάρχουν διάφορες παραλλαγές αυτού του αλγορίθμου που στην πράξη είναι πιο αποδοτικοί \cite{BERN}. 263 | \pagebreak 264 | \section{Υλοποίηση στη γλώσσα OCaml} 265 | \subsection{Υλοποίηση βιβλιοθήκης} 266 | Προκειμένου να υλοποιήσουμε ένα σύστημα κρυπτογραφίας βασισμένο σε ελλειπτικές καμπύλες υλοποιήσαμε μία βιβλιοθήκη που περιέχει όλες τις απαιτούμενες συναρτήσεις. 267 | \subsubsection{Modulo αριθμητική} 268 | Οι πράξεις modulo είναι το πιο ακριβό υπολογιστικά κομμάτι ενός συστήματος κρυπτογραφίας. Για το λόγο αυτό οι προσπάθειες βελτίωσης της απόδησης του συστήματος πρέπει να επικεντρωθούν στο κομμάτι αυτό. 269 | Για τον παραπάνω λόγο για την υλοποίηση modulo αριθμητικής σε μεγάλους αριθμούς προτιμήσαμε τη βιβλιοθήκη μεγάλων αριθμών \href{http://forge.ocamlcore.org/projects/zarith}{Zarith} που βασίζεται στο GMP καθώς διαθέτει αρκετές και αποδοτικές συναρτήσεις λόγω του ότι το GMP είναι υλοποιημένο σε C και αρκετά optimized σε σχέση με την ενσωματωμένη βιβλιοθήκη της OCaml ή κάποια δική μας λύση. 270 | \subsubsection{Υλοποίηση πράξεων ομάδας} 271 | Έχοντας πλέον την υποστήριξη για modulo αριθμητική υλοποιήσαμε τις συναρτήσεις για τις πράξεις που ορίζονται σε μία ομάδα που ορίζει μία ελλειπτική καμπύλη όπως αυτές αναλύθηκαν στο κεφάλαιο 1.3.1. 272 | \subsubsection{Υλοποίηση βαθμωτού πολλαπλασιασμού} 273 | Χρησιμοποιήσαμε τη μέθοδο double-and-add όπως αναλύεται στο 3.4. 274 | \subsubsection{Ψηφιακή υπογραφή} 275 | Για τη διαδικασία υπογραφής και επαλήθευσης ενός μηνύματος ακολουθήσαμε τον αλγόριθμο που ορίζει το ECDSA με τη διαφορά ότι αντι για την προτεινόμενη secure hash function SHA-1 χρησιμοποιήσαμε το MD5. 276 | \\ \medskip 277 | \emph{Σημειώνεται ότι για πραγματικές εφαρμογές θα πρέπει να χρησιμοποιηθεί μία πιο ισχυρή συνάρτηση κατακερματισμού. 278 | }\subsection{Προγράμματα επίδειξης} 279 | \subsubsection{Υλοποίηση ECDH} 280 | Για να υλοποιήσουμε το σχήμα κρυπτογραφίας ECDH όπως αυτό αναλύθηκε στο 2.3 δημιουργήσαμε δύο προγράμματα που χρησιμοποιούν την παραπάνω βιβλιοθήκη, η λειτουργία των οποίων εξηγείται παρακάτω: 281 | \paragraph{Register.} Το πρόγραμμα \emph{register\_dh} δέχεται ως input ένα username και δημιουργεί ένα αρχείο με όνομα \emph{username.pk} που περιέχει το δημόσιο κλειδί του χρήστη και ένα αρχείο με όνομα \emph{username.sk} που περιέχει το ιδιωτικό κλειδί του χρήστη. Σε περίπτωση που υπάρχουν αρχεία με αυτό το όνομα δίνεται μήνυμα λάθους και το πρόγραμμα τερματίζει. \\ 282 | \medskip 283 | \emph{Σημείωνεται ότι το ιδιωτικό κλειδί του χρήστη αποθηκεύεται στο δίσκο ως plain-text, ενώ σε πραγματική εφαρμογή θα έπρεπε να κρυπτογραφείται.} 284 | \paragraph{Exchange.} Το πρόγραμμα \emph{exchange\_dh} δέχεται ως input το όνομα ενός χρήστη και το όνομα του χρήστη με τον οποίο θέλει να ανταλλάξει κλειδί. Στη συνέχεια διαβάζει το δημόσιο κλειδί του δεύτερου χρήστη και το ιδιωτικό κλειδί του πρώτου χρήστη και υπολογίζει το κοινό κλειδί. 285 | \subsubsection{ECDSA} 286 | Για την υπογραφή μηνυμάτων δημιουργήσαμε δύο προγράμματα που χρησιμοποιούν τις συναρτήσεις \emph{sign} και \emph{verify} της βιβλιοθήκης η λειτουργία των οποίων εξηγείται παρακάτω: 287 | \paragraph{Sign.} Το πρόγραμμα \emph{sign} δέχεται ως input το username ενός χρήστη και ένα μήνυμα και δημιουργεί ένα αρχείο με όνομα \emph{username.msg} που περιέχει το μήνυμα και την υπογραφή. Σε περίπτωση που δε βρεθεί το username δίνεται μήνυμα λάθους και το πρόγραμμα τερματίζει. 288 | \paragraph{Verify.} Το πρόγραμμα \emph{verify} δέχεται ως input το username του χρήστη στον οποίο ανήκει το μήνυμα που θέλουμε να επαληθεύσουμε, ανακτά το δημόσιο κλειδί του, βρίσκει το μήνυμα και την υπογραφή απο το αρχείο που έχει δημιουργήσει το \emph{sign} και επαληθεύει την αυθεντικότητα της υπογραφής. 289 | \subsubsection{Πηγαίος κώδικας} 290 | Ο πηγαίος κώδικας για όλα τα παραπάνω βρίσκεται στο \href{https://github.com/zoep/ECC-OCaml}{Github}. 291 | \subsection{Τεκμηρίωση Βιβλιοθήκης} 292 | 293 | \begin{ocamldoccode} 294 | {\tt{module }}{\tt{Ecc}}{\tt{ : }}\end{ocamldoccode} 295 | \label{module:Ecc.Ecc}\index{Ecc@\verb`Ecc`} 296 | 297 | \begin{ocamldocsigend} 298 | 299 | 300 | \label{type:Ecc.Ecc.point}\begin{ocamldoccode} 301 | type point = 302 | | Infinity 303 | | Point of Z.t * Z.t 304 | \end{ocamldoccode} 305 | \begin{ocamldocdescription} 306 | An elliptic curve point. It is either infinity or a point (x,y). 307 | \end{ocamldocdescription} 308 | \index{point@\verb`point`} 309 | 310 | 311 | \label{type:Ecc.Ecc.elliptic-underscorecurve}\begin{ocamldoccode} 312 | type elliptic_curve = {\char123} 313 | p : Z.t ; 314 | a : Z.t ; 315 | b : Z.t ; 316 | g : point ; 317 | n : Z.t ; 318 | h : Z.t ; 319 | {\char125} 320 | \end{ocamldoccode} 321 | \index{elliptic-underscorecurve@\verb`elliptic_curve`} 322 | \begin{ocamldocdescription} 323 | The type of domain parameters 324 | \end{ocamldocdescription} 325 | 326 | \label{val:Ecc.Ecc.inverse}\begin{ocamldoccode} 327 | val inverse : Z.t -> Z.t -> Z.t 328 | \end{ocamldoccode} 329 | \index{inverse@\verb`inverse`} 330 | \begin{ocamldocdescription} 331 | \textbf{Ecc.inverse a n} inverses the number a modulo n 332 | \end{ocamldocdescription} 333 | 334 | 335 | \label{val:Ecc.Ecc.verify-underscorerange}\begin{ocamldoccode} 336 | val verify_range : Z.t -> Z.t -> Z.t -> bool 337 | \end{ocamldoccode} 338 | \index{verify-underscorerange@\verb`verify_range`} 339 | \begin{ocamldocdescription} 340 | \textbf{Ecc.verify\_range a l h} returns true if l $\leq$ a $\leq$ h or false otherwise 341 | 342 | 343 | \end{ocamldocdescription} 344 | 345 | 346 | \label{val:Ecc.Ecc.is-underscorepoint}\begin{ocamldoccode} 347 | val is_point : point -> elliptic_curve -> bool 348 | \end{ocamldoccode} 349 | \index{is-underscorepoint@\verb`is_point`} 350 | \begin{ocamldocdescription} 351 | Returns true if a point belongs to an elliptic curve or false otherwise 352 | 353 | 354 | \end{ocamldocdescription} 355 | 356 | 357 | \label{val:Ecc.Ecc.double-underscorepoint}\begin{ocamldoccode} 358 | val double_point : point -> elliptic_curve -> point 359 | \end{ocamldoccode} 360 | \index{double-underscorepoint@\verb`double_point`} 361 | \begin{ocamldocdescription} 362 | Given a point P on an elliptic curve and the elliptic curve retuns the point 2P 363 | on that curve. 364 | 365 | 366 | \end{ocamldocdescription} 367 | 368 | 369 | \label{val:Ecc.Ecc.add-underscorepoint}\begin{ocamldoccode} 370 | val add_point : point -> point -> elliptic_curve -> point 371 | \end{ocamldoccode} 372 | \index{add-underscorepoint@\verb`add_point`} 373 | \begin{ocamldocdescription} 374 | Given two points P and Q, both on the same elliptic curve, and the elliptic curve returns 375 | P+Q on that curve. 376 | 377 | 378 | \end{ocamldocdescription} 379 | 380 | 381 | \label{val:Ecc.Ecc.multiply-underscorepoint}\begin{ocamldoccode} 382 | val multiply_point : point -> Z.t -> elliptic_curve -> point 383 | \end{ocamldoccode} 384 | \index{multiply-underscorepoint@\verb`multiply_point`} 385 | \begin{ocamldocdescription} 386 | Given a point P on an elliptic curve, an integer k and the elliptic curve returns 387 | the scalar multiplication kP on that curve. 388 | 389 | 390 | \end{ocamldocdescription} 391 | 392 | 393 | 394 | 395 | \label{val:Ecc.Ecc.integer-underscoreof-underscoreoctStr}\begin{ocamldoccode} 396 | val integer_of_octStr : string -> Z.t 397 | \end{ocamldoccode} 398 | \index{integer-underscoreof-underscoreoctStr@\verb`integer_of_octStr`} 399 | \begin{ocamldocdescription} 400 | Converts an octet string to an intenger. Useful for defining domain parameters. 401 | 402 | 403 | \end{ocamldocdescription} 404 | 405 | 406 | \label{val:Ecc.Ecc.brainpool-underscoreP256-underscorer1}\begin{ocamldoccode} 407 | val brainpool_P256_r1 : elliptic_curve 408 | \end{ocamldoccode} 409 | \index{brainpool-underscoreP256-underscorer1@\verb`brainpool_P256_r1`} 410 | \begin{ocamldocdescription} 411 | An elliptic curve used for ECC as defined by Brainpool 412 | 413 | 414 | \end{ocamldocdescription} 415 | 416 | 417 | \label{val:Ecc.Ecc.test-underscorecurve}\begin{ocamldoccode} 418 | val test_curve : elliptic_curve 419 | \end{ocamldoccode} 420 | \index{test-underscorecurve@\verb`test_curve`} 421 | \begin{ocamldocdescription} 422 | An elliptic curve with small domain parameters for testing purposes 423 | 424 | 425 | \end{ocamldocdescription} 426 | 427 | 428 | \label{val:Ecc.Ecc.random-underscorebig-underscoreint}\begin{ocamldoccode} 429 | val random_big_int : Z.t -> Z.t 430 | \end{ocamldoccode} 431 | \index{random-underscorebig-underscoreint@\verb`random_big_int`} 432 | \begin{ocamldocdescription} 433 | \textbf{Ecc.random\_big\_int bound} returns a random integer in {\tt{1, bound-1}} 434 | 435 | 436 | \end{ocamldocdescription} 437 | 438 | 439 | \label{val:Ecc.Ecc.sign}\begin{ocamldoccode} 440 | val sign : string -> Z.t -> elliptic_curve -> Z.t * Z.t 441 | \end{ocamldoccode} 442 | \index{sign@\verb`sign`} 443 | \begin{ocamldocdescription} 444 | \textbf{Ecc.sign message sk curve} where sk is secret key of the user s and curve 445 | the public elliptic curve, returns the signature (r, s) of the message. 446 | 447 | 448 | \end{ocamldocdescription} 449 | 450 | 451 | \label{val:Ecc.Ecc.verify}\begin{ocamldoccode} 452 | val verify : string -> Z.t * Z.t -> point -> elliptic_curve -> bool 453 | \end{ocamldoccode} 454 | \index{verify@\verb`verify`} 455 | \begin{ocamldocdescription} 456 | \textbf{Ecc.verify message (r, s) pk curve} where pk is the public key of the user 457 | who signed the message, returns true if the (r, s) is a valid 458 | signature or false otherwise. 459 | 460 | 461 | \end{ocamldocdescription} 462 | 463 | 464 | \label{val:Ecc.Ecc.create-underscorekeys}\begin{ocamldoccode} 465 | val create_keys : elliptic_curve -> point * Z.t 466 | \end{ocamldoccode} 467 | \index{create-underscorekeys@\verb`create_keys`} 468 | \begin{ocamldocdescription} 469 | Creates a tuple (public\_key, secret\_key) where public\_key is a point of 470 | the curve and secret\_key an integer. 471 | 472 | 473 | \end{ocamldocdescription} 474 | \end{ocamldocsigend} 475 | 476 | 477 | \pagebreak 478 | 479 | %http://www.ccs.neu.edu/home/riccardo/courses/cs6750-fa09/talks/Ellis-elliptic-curve-crypto.pdf 480 | %http://cgi.di.uoa.gr/~halatsis/Crypto/Bibliografia/Elliptic/koblitz_ecc.pdf 481 | %http://www.certicom.com/index.php/-50-elliptic-curve-groups-and-the-discrete-logarithm-problem 482 | %http://cs.ucsb.edu/~koc/ccs130h/notes/ecdsa-cert.pdf 483 | %https://engineering.purdue.edu/kak/compsec/NewLectures/Lecture14.pdf 484 | %http://wiki.crypto.rub.de/Buch/download/Understanding_Cryptography_Chptr_9---ECC.pdf 485 | %http://www.ecc-brainpool.org/download/Domain-parameters.pdf 486 | \begin{thebibliography}{2} 487 | \bibitem{ECDSA} Don Johnson, Alfred Menezes, Scott Vanstone, \emph{The Elliptic Curve Digital Signature Algorithm (ECDSA)}, \emph{Certicom Research}. 488 | \bibitem{SEC2} Certicom Research, \emph{SEC 2: Recommended Elliptic Curve Domain Parameters}, September 2000. 489 | \bibitem{BPOOL} Brainpool, \emph{ECC Brainpool Standard Curves and Curve Generation v1.0}, October 2005. 490 | \bibitem{PAAR} Chrisoft Paar, Jan pelzl, \emph{Understanding Cryptography: A textbook for Students and Practitioners}, \emph{Springer}, July 2010. 491 | \bibitem{BERN} Daniel J. Bernstein, Tanja Lange, \emph{Analysis and optimization of elliptic-curve single-scalar multiplication}. 492 | \end{thebibliography} 493 | \end{document} 494 | -------------------------------------------------------------------------------- /src/Secp256k1.ml: -------------------------------------------------------------------------------- 1 | open EccPrimitives 2 | 3 | module Secp256k1 = Make_Curve 4 | (struct 5 | type t = 6 | { 7 | p : Z.t; 8 | (* p for the prime field Fp*) 9 | a : Z.t; 10 | (* variable a of the eliptic curve equation *) 11 | b : Z.t; 12 | (* variable b of the eliptic curve equation *) 13 | g : point; 14 | (* the base point *) 15 | n : Z.t; 16 | (* order of the base point *) 17 | h : Z.t; 18 | (* cofactor of the base point *) 19 | points : point list 20 | (* the point list used to pre-compute points to use on 21 | multiply_point algorithm *) 22 | } 23 | 24 | let curve = { 25 | p = Z.of_string_base 16 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"; 26 | a = Z.zero; 27 | b = Z.of_string_base 16 "0000000000000000000000000000000000000000000000000000000000000007"; 28 | g = 29 | Point (Z.of_string_base 16 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 30 | Z.of_string_base 16 "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); 31 | n = Z.of_string_base 16 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; 32 | h = Z.one; 33 | points = 34 | [Point (Z.of_string "42246602079981622997344400664532560234433342616784197585611913914714141525950", 35 | Z.of_string "61835501952265390066811470665897425612541327657481464188269938336845805842950"); 36 | Point(Z.of_string "46460269787542938608828482740848373709079876823327944354090070116427489517527", 37 | Z.of_string "102144161666123662734987302011731550822440782722543352594100911135137187302376"); 38 | Point(Z.of_string "109642552416651464875177535527340022686210544221319897041069203258472613047302", 39 | Z.of_string "52220679029478769733481485569781744595464000208688833635034774375321898049793"); 40 | Point(Z.of_string "41293508420921713809509271549681433110786208781187328157905964916717488452124", 41 | Z.of_string "94380876783757173643379456172520611336027727481860850709400609491948445468191"); 42 | Point(Z.of_string "68522981790747611148039171539829252646008591398458336683379366804072944441093", 43 | Z.of_string "68259749602112720108448779745463376203908070241496565207934710169157635838457"); 44 | Point(Z.of_string "104627677449711716266087199108325150924235489316248383364887356694983489993083", 45 | Z.of_string "7708200774285834635744950000840068621612010670698154588214826705924677119524"); 46 | Point(Z.of_string "104609889403804228654374146538141097862877323184388134603900908836154391601158", 47 | Z.of_string "56850921622023447109542506613581206505363554034987192435778070793913051846355"); 48 | Point(Z.of_string "113176265019734027839407688941655008870884390949890215800087491836545197564093", 49 | Z.of_string "19986271560705038294975100567846484087326268640452090569065269746787509963538"); 50 | Point(Z.of_string "16218958430206956857203726696721609008268516046330783800676099836190284822579", 51 | Z.of_string "13130077129698466389970469182522315376386178076388507128724216156769663373491"); 52 | Point(Z.of_string "102947450912513396846837423611178512585996560132632575921382559818642657503790", 53 | Z.of_string "3080672307201810353672599849419381664902527212748852103033915027534220501156"); 54 | Point(Z.of_string "100584263591428904311841331088070499116075180634996448354205860003009926878232", 55 | Z.of_string "112036073007991600393123344422537418683718465258368160839264309056512884031794"); 56 | Point(Z.of_string "50099551917916829222906678161585378594836936955039234378036254086564275220975", 57 | Z.of_string "55202511527584028886719126815779404258431469811463817470685422368029514044734"); 58 | Point(Z.of_string "584953940238611692716369383619121176170693727598487465865531986784704254571", 59 | Z.of_string "14843886240207775294913261321199925414813174473760588781550364419502051469"); 60 | Point(Z.of_string "111247622390413862672012812784194608034956282151740982628486647983272959395309", 61 | Z.of_string "3545131270584729518286142214373406426115731492192480331655704095151635374619"); 62 | Point(Z.of_string "78523970353868757127860372656538870690581645153883103850292663404968126426827", 63 | Z.of_string "109630414502453631611208795699606583248407219203475475599182558458796820276552"); 64 | Point(Z.of_string "53611189866873544095713968823232039562533247559711846182291556579415007759703", 65 | Z.of_string "72122844789934505386880137268105899946705816708393388148081223494140732071516"); 66 | Point(Z.of_string "2450678495626018549363796584529655230962841159017328202328335466627727157600", 67 | Z.of_string "85836280719645963241537946629153268781597039922789889167529263254671422437992"); 68 | Point(Z.of_string "32286164061913648390701118931655868108162501253906037805916703287937675918709", 69 | Z.of_string "43255184589186864929084333294697965359525222368878331241008017143887496024284"); 70 | Point(Z.of_string "108244156308252410114338858176228141774478287195716561335573243902156797983690", 71 | Z.of_string "52787607021267843957868475066610080122762175913817715424819738571701450986827"); 72 | Point(Z.of_string "25938957082734693143119535138829716615473817174117242916795763254540578697822", 73 | Z.of_string "66259499731477133645367082655650387118702041133246469267582775780000015919539"); 74 | Point(Z.of_string "99176712740254506234006891361804963095615042720368670759549902524437399964308", 75 | Z.of_string "67332205819290869250975394377122283945285263114744391436863559221618929906296"); 76 | Point(Z.of_string "23886403779930084679681860134726308787447699613663291937542204710312319161328", 77 | Z.of_string "32202341684866744721624198887586803909731921878706270037571346746571995574806"); 78 | Point(Z.of_string "35546426351617368635549349409581634972131097265765200284776715526325909123609", 79 | Z.of_string "88679562866924524866626416814007377340635918991153461441735664177124811764224"); 80 | Point(Z.of_string "25972902529974187668883225807596136782939875689817147529955214959074030321896", 81 | Z.of_string "21986593754459192146485008939703141484728347294264692420949598326533444815794"); 82 | Point(Z.of_string "25819550180624466411414663634341747665947049140064043394621250042801840204491", 83 | Z.of_string "20825508656170326518272261173652292512037260976199639783129607350443536878026"); 84 | Point(Z.of_string "26445068418004277380926243815680803793414903773693655343302263633863706123446", 85 | Z.of_string "9763006572613373161334155506731553413921505509666299212276486794403461928199"); 86 | Point(Z.of_string "53287513821509100124826550203118545468310807868729185695011711689362578474125", 87 | Z.of_string "4208373004708597360754428880558158016435411958138809177990195164160566296720"); 88 | Point(Z.of_string "36866134618127526980444747948186099268926011348914636333104504450195256051209", 89 | Z.of_string "114980177720586508505095660475140810696541818486657385574992383715665260208760"); 90 | Point(Z.of_string "75679446995497569912596222885619877321256611640685815869823597870090194535779", 91 | Z.of_string "82084073991975167115331408241384522364600201894322097526096278655506000138147"); 92 | Point(Z.of_string "93573654916908469865612581608066207367013936625779932495846528016524147252007", 93 | Z.of_string "57268285207360490934322155023863512284988179173017360762997976064764485308667"); 94 | Point(Z.of_string "92458633529422410326338431127195898430886920710777464668390723412431433157387", 95 | Z.of_string "107235709772740771822557144111582233283221044424190823815104889769859157421781"); 96 | Point(Z.of_string "13716417507660162731354652469237449847325584136943304111808851164055681617046", 97 | Z.of_string "97340876840577544720647101778749396281941983509771431394927232561013404711109"); 98 | Point(Z.of_string "115658269859502167764416473723712153580063073650585703240902909844207866829383", 99 | Z.of_string "96664476395640661788722340354568479098226799410386123947148039604016629739943"); 100 | Point(Z.of_string "76284006798170459196853220483267480864823247968004895819359299229783621269899", 101 | Z.of_string "49279647492202581822055695749679480174107727975266601788050679149974830042696"); 102 | Point(Z.of_string "6196321934296409719701384622666226942510535780510057740398374342234097183915", 103 | Z.of_string "15805770474830391288728990430989880051154221724377198377694955629176725477705"); 104 | Point(Z.of_string "68018098555604196971848072082119457965935950768829325192064148784419482829368", 105 | Z.of_string "94692186861615773060737362326936889990245904786493259061699724312354593562587"); 106 | Point(Z.of_string "59300854574127786742145821493222559219592140689041562728524783206447763728762", 107 | Z.of_string "61315760332247989887278043355461640630451006046535109438154351656490751483670"); 108 | Point(Z.of_string "43084154579134873016517321951681062310947255641048551135264463881370726283610", 109 | Z.of_string "33028944413710322006211224840217533478610434612555007806962237806535192034111"); 110 | Point(Z.of_string "22190198488948301732208097731693959424561616656784413459983511620664367620286", 111 | Z.of_string "75411332337890477564464523675379795060300890921210805826468000443851552626871"); 112 | Point(Z.of_string "59414819167408483069280502365901221637502481902994867636548724904556022671723", 113 | Z.of_string "88383262348479165780323619823989765350934967134625217357749691606313397752184"); 114 | Point(Z.of_string "73625923752167711151499796771636688027593353865916127739283461600936533096616", 115 | Z.of_string "71445742144172148239386798857376405963590604018611691288464064655494240713564"); 116 | Point(Z.of_string "87688179594792217057090118622345355437613344230864011813912155046320681341356", 117 | Z.of_string "79981443946144080982364002660353231185999817333478163531160010598047713047705"); 118 | Point(Z.of_string "23319423859074864313496742629079072312906305600358759104408457890766774379331", 119 | Z.of_string "22288754135945829157348861055944082968854327404482864573451896054984775811394"); 120 | Point(Z.of_string "110871665243414813814325548427991567616616658065751158629956231972048102601990", 121 | Z.of_string "104748771639792953636287192046485954825996545663230023325814428930393444525205"); 122 | Point(Z.of_string "79771803857740978561149568834789184624147934446133091632348396391204287524761", 123 | Z.of_string "7653711284559768402573705660400659795593493539332173538823597166282716980725"); 124 | Point(Z.of_string "49520179119512644585138883273711909270464553906960582385862934367450878975478", 125 | Z.of_string "854701409657018422156396404448712806380804989081141038295183653863384758106"); 126 | Point(Z.of_string "19029758020090027693718328625811627166812891859419560705480566280493559973645", 127 | Z.of_string "55712771002095531318357177126006383911592189516972177625356990899110115365303"); 128 | Point(Z.of_string "87696733661404188805050255659062696239336284582127463643886891462527652196112", 129 | Z.of_string "214800748085639397665662012695233402510606477077821748554135926331229914144"); 130 | Point(Z.of_string "4496620989032442163077191040933912625332715985816106675710143463609931160926", 131 | Z.of_string "3987278062211187929519519918291686468915017873574976615709272719214104909870"); 132 | Point(Z.of_string "42838587638860273205806300749400317825735693310728235033854846032581930411802", 133 | Z.of_string "72474804733838010903881526849021306152066193634525099921996776916160074801140"); 134 | Point(Z.of_string "85611140147260455738364010151866621881066904302295735651734699784126820217623", 135 | Z.of_string "29317243279485864699033770453000297441854584704679713691322687034482309044165"); 136 | Point(Z.of_string "112468423190501023592273005343708573865431485052390368722620904830803241360545", 137 | Z.of_string "43587973013938698583642661020099063978007353667138490742658175190381664419466"); 138 | Point(Z.of_string "51152670663414615552065492774561010415888324331150272805465987197254667886144", 139 | Z.of_string "97659712037886932609433240104533661287088378539725054370221269179870448944468"); 140 | Point(Z.of_string "95012318826227953547882464023569098095015772120770966549333056783459658142684", 141 | Z.of_string "72751790790672604647407346809721480086067554343468380791097001132431181657285"); 142 | Point(Z.of_string "32719076198152449667923047335473592038454433447261194562691787996114621783479", 143 | Z.of_string "69402521675062161688556144673484860488412162349533764367070794042563990443972"); 144 | Point(Z.of_string "30325598285015512801938454441947042649783161460970526240376762555727538871108", 145 | Z.of_string "18002800338202423317299947351385149986367235344695867471381027218928395712258"); 146 | Point(Z.of_string "5242677189585419366169302382537944722906662959689284716735373624773677854923", 147 | Z.of_string "21339388261868459875983699799634359904937636365195091056655233668456624227027"); 148 | Point(Z.of_string "10749025800106529283134517357445575512833851247426491370190089211127761564844", 149 | Z.of_string "59450621864225477411768718473443061539275199377078723552016619057307406679956"); 150 | Point(Z.of_string "9299536375647244587751929354011214813839297997156334971307027165499353441915", 151 | Z.of_string "61921430745998655712380686314601239574670517230188864259489224140099561455976"); 152 | Point(Z.of_string "31488932465912493077903640397394470255598760595654027524796519373400735399512", 153 | Z.of_string "39915306639833768229168228685959757401762384247793680072677452668588194819289"); 154 | Point(Z.of_string "30126700056236591350942813417204334097934743662052617575181576028157529193225", 155 | Z.of_string "35789667990877259087353254065467677934430855563067242056515511316064617261675"); 156 | Point(Z.of_string "17883270747724683386289103552773390915246157012530869751635723419192317714851", 157 | Z.of_string "30238293096477177901210273873083649109263085783090336489259670604797039171070"); 158 | Point(Z.of_string "113629880216554481493073868791035724779247698972145305878346369581088172148128", 159 | Z.of_string "35176286882574099250123241755991852951924099800228854492638727506151242555630"); 160 | Point(Z.of_string "57117112057550124051021298814399831514635050730433281130219365533835824314463", 161 | Z.of_string "81547221220433383295958294949338511642518418201977361607961147291102242196593"); 162 | Point(Z.of_string "1788616847580942725649636376763630062162991716133649655359112625468667068606", 163 | Z.of_string "42477094329594213070474788091603998634960693886387737365219362983037074499373"); 164 | Point(Z.of_string "10845642044240026014396107228685612423377668884226088953088282941006365957058", 165 | Z.of_string "102822000266620316062121744826811940146233627275561179259983518483125753798778"); 166 | Point(Z.of_string "22280874253835890191644798427762019145329377972239215444341672540555248535776", 167 | Z.of_string "67002318631910978766106672523363458932424589847999257487796029659406987176348"); 168 | Point(Z.of_string "75599157406198864571449018327203917267130424604166480449062484976553116902580", 169 | Z.of_string "87243792865575834188261946273142671546901874824839133947436737835011338189408"); 170 | Point(Z.of_string "100888845701681192141455835884235987762076422403070020454006856598044632081144", 171 | Z.of_string "106422563521822727898510248709729762584531948887965635368126329452129591987637"); 172 | Point(Z.of_string "89902030372775286791280316761995403459816390960777586909164015961141757249426", 173 | Z.of_string "105823716359661541353329637297497332851528302573678481665302742868221281173962"); 174 | Point(Z.of_string "103626781979515146770199852044470873591351903128708956090074481178369590071365", 175 | Z.of_string "55450003206041842222307901224510570635546566833281126301624658916989017423386"); 176 | Point(Z.of_string "80931452170175250234405059710941711720746352299204472770501586647381659591255", 177 | Z.of_string "678978346799198408095227694181002181111848049145269936267087076952093864484"); 178 | Point(Z.of_string "45573678932946396870595377154028349018754510360529159345717277603890259790841", 179 | Z.of_string "86337064919996069082617950583164734273973377858385868247499179413249041096484"); 180 | Point(Z.of_string "107314856760626966322638116573879558571191719600477901378788743659017666938921", 181 | Z.of_string "70932672138707320171133764841310263292359830890763304537007250953600107369721"); 182 | Point(Z.of_string "85166021302910759690156166084007599410941437727660216629799201191130729164141", 183 | Z.of_string "48493683083050288234270665563523984688105011632132654271696194114110457589115"); 184 | Point(Z.of_string "15697331408420441954583827153736266793225656194790799985633724594755945834687", 185 | Z.of_string "70520840071347504434937097211854417000577691434307663629203820607196142270009"); 186 | Point(Z.of_string "34808603633530161342090762190238246947659195446419766232478695745740271238971", 187 | Z.of_string "16171452831375115800134844184208146103922651574490568553181302050274004747803"); 188 | Point(Z.of_string "44793433016290450140950071549583425928625008566889198562757165584503234807834", 189 | Z.of_string "84164674562984395739991883897662696408954513420183413048910225369439997456648"); 190 | Point(Z.of_string "37132632752575842080983608780667077401295936827503201322988816829933966548103", 191 | Z.of_string "47544374421729746218622270472225490380252710854785133700036704526033852689021"); 192 | Point(Z.of_string "87915256174604560496506970901899209377504315105023535502806095863908752077823", 193 | Z.of_string "68730679165892480304582952761400306743139699213767760103438802378958086010627"); 194 | Point(Z.of_string "108708260968072185966030307723115414687607281608863792935289027680799181032458", 195 | Z.of_string "39304706742566257903494202035223268798517842865516894670026394427412884462346"); 196 | Point(Z.of_string "5277786924354080189354732581769930964339887346726404221988825981097208152885", 197 | Z.of_string "19427928544717242302107968690807481526531152772741889917228993464998252753275"); 198 | Point(Z.of_string "26308409147026688447513839761396032161436341452903611730904783166334356540829", 199 | Z.of_string "38944163392102736709685234913974100751488815321739226526656481769194013162421"); 200 | Point(Z.of_string "114479830788175602654765516128952914432670616323288708492972859652794983381439", 201 | Z.of_string "108584425136995067889846262102066324408669391011507652197501942389048443128032"); 202 | Point(Z.of_string "46637462143754952038709779825074450135100779961554590173001826089370888704051", 203 | Z.of_string "102190868613103369745676837485339734103019821897911796109868913750827752003170"); 204 | Point(Z.of_string "113517450891386850746397179308148566158771611960950247783932782846719819197090", 205 | Z.of_string "108171768809492164427050207744155355331771739008244124205372818251726939462973"); 206 | Point(Z.of_string "38240169349108327393028959639562180057143641547116530088728715269415804628410", 207 | Z.of_string "90710750410729121437880015222810009312633470701710435875585890278457534611270"); 208 | Point(Z.of_string "46120862506690025566154907103334568451176450706737333364037230303364767910808", 209 | Z.of_string "92896899664269639977275596015891082661146986436166556196288879933146559740829"); 210 | Point(Z.of_string "91791149942574670690868865412565488023263282049992951568794967145025639990959", 211 | Z.of_string "111995758028903628067321268218352986392807921121667287849911498516906100422398"); 212 | Point(Z.of_string "37715289817539930992460526202591391240449943365538369239347820914399281898938", 213 | Z.of_string "8166217700774838411970752827683996565366775596426675569456364697353277452498"); 214 | Point(Z.of_string "88022144836556665090808715405330689950641192282504939787976081499642093468233", 215 | Z.of_string "70067801766242475511766690990030003728861834701285025803511491440896926576883"); 216 | Point(Z.of_string "106393757702890179709504748417279758833427783973775192350061645518277528347372", 217 | Z.of_string "74995135842580514840005438773498480506352450199894776651760431777184874517525"); 218 | Point(Z.of_string "113000975349672893319935827999909933854274306100052038907351918957607569725721", 219 | Z.of_string "14184964063318240535794185470488225132384520785964777320689895344317884678374"); 220 | Point(Z.of_string "81386147284599293299861793243924429282652958560702634472788625783808425014246", 221 | Z.of_string "98805078149328213555899183187104797681015042303583909087650906458838763179489"); 222 | Point(Z.of_string "85964092541375930326647029864948657639324789698277418639087751891084424281089", 223 | Z.of_string "20757427911411779719156529654567964146354244531994168888749678603602266881112"); 224 | Point(Z.of_string "71449543261060781513036728954955568119705883463536806769758791739330040750189", 225 | Z.of_string "32525419179073359795927652755688057582574068246800581291569739476100112906580"); 226 | Point(Z.of_string "87022332193909528339440857168776649742663859070700178220828325481515892297468", 227 | Z.of_string "89758986015367518791796694200665466810980267126587762853029775564217989653629"); 228 | Point(Z.of_string "774507726779820719011325467199200933244866331252880867407397351671621730662", 229 | Z.of_string "82888843573834154470497704404379255602360474228392096492286007316173767507471"); 230 | Point(Z.of_string "96731302639298590033161301932447430332852140579080326224731576597821655596896", 231 | Z.of_string "103048459597901480203575605705271240481477739673577706263943687911852150734804"); 232 | Point(Z.of_string "97263308830445883286286626709573284039569086063011789671111611054344451179949", 233 | Z.of_string "41386756027842588312004110209847180375991177750690971089579447326934133163287"); 234 | Point(Z.of_string "80315391618503400626386651198172939155651824720200772431319939738372790477201", 235 | Z.of_string "105761768955557504232168157326595726850477509221703594672958688838021892584033"); 236 | Point(Z.of_string "15922169699750424897222542213879992627034479146629376871684593422876884974040", 237 | Z.of_string "115222973727580735646070738037546865236841110356254940978073406192574479556734"); 238 | Point(Z.of_string "9251478048282717967904872694694120090616737597289398591541413543906469253569", 239 | Z.of_string "47727377006484475351066322188151193039879613722146841131356035310941919669665"); 240 | Point(Z.of_string "42072651501531035697864257931502832299445574224640684940398729599974567646173", 241 | Z.of_string "78184377537902585529635237974095695522157122398544641434590562640667635745242"); 242 | Point(Z.of_string "10142963744065389438107901103238359423938252301012269227184606046128987031540", 243 | Z.of_string "85815968968468248563387645414705721728734797126151633050858542428804804435036"); 244 | Point(Z.of_string "19770338246020173809480900018523239843689119264550805173274917119350645870721", 245 | Z.of_string "113988018014659980045299363440543097112638284151153850376835239649016308376452"); 246 | Point(Z.of_string "9253545951434556233943039851739061143793861553777141146209185983948790711603", 247 | Z.of_string "95149455887207673765973773420645881663194057310230667381828041306717070109736"); 248 | Point(Z.of_string "42867717725633690091127322886049894587164424735990712846880508543802532213263", 249 | Z.of_string "53113567908833389058645559214906270350633112924200936670968858758988903584667"); 250 | Point(Z.of_string "54324590807269377679544937413601021651006974059904524771727699035349838853916", 251 | Z.of_string "106866819825417353092696005020964130540322848813442470120900331863623781191813"); 252 | Point(Z.of_string "110806672665031760239284227549978930915243468401897591399639371195350547961334", 253 | Z.of_string "21531675142106151254204530858973366787237375547698938838030556324226769919751"); 254 | Point(Z.of_string "49129060932763451298048586283101836325698674493902527150795835621556328361958", 255 | Z.of_string "108981389385375783571152799582717878472404740007321712386704175384714616932000"); 256 | Point(Z.of_string "26340351947539714570157057534853240144876310886677423778600336047465590788395", 257 | Z.of_string "68768247102290235298188822745697160869267269498054545426977063101653472243328"); 258 | Point(Z.of_string "113901404780313695776903291457061849459758620639028893370801528721254291052076", 259 | Z.of_string "9024236548804839628950504310445609357291021601333217142141623108549977784912"); 260 | Point(Z.of_string "22063282008932875383880869694712855501712603458237355625562771346645788601584", 261 | Z.of_string "38984382797176771457940099253734465422342027386974035512057806908007884244580"); 262 | Point(Z.of_string "76417552565136309548995308160565984104208388223287030483897163118746244305758", 263 | Z.of_string "62738009427501701955795586392184231048207473407295185539896614970360139886154"); 264 | Point(Z.of_string "112580467264032996380352106605037321970669557365847128238731733999550531604623", 265 | Z.of_string "42894578976620085115187347367153962595583247878402385042845602011642722675607"); 266 | Point(Z.of_string "43830098527644128136953060695891085974194125403112089093563290807328311355661", 267 | Z.of_string "93949778597316731481889727765267140056805304543437827714548762387098646631215"); 268 | Point(Z.of_string "20882541620138181989507810366070488208507569082926489356630795700182539068795", 269 | Z.of_string "12927552864572339810305156234768664401162173993774567694321849887019921665904"); 270 | Point(Z.of_string "89010368611633522363135332892884058988866001649925330429006595676209290226205", 271 | Z.of_string "110921753825188993018465178477103229702073862409225970322153671627693801167211"); 272 | Point(Z.of_string "47159970464925994807631072890734586315769179830476432617129274653209411258307", 273 | Z.of_string "92945946596001932332483841720564205203798714385734370135649923496945367589097"); 274 | Point(Z.of_string "46053122573716701000039362367167188778172043478875632278002906307277720954980", 275 | Z.of_string "58637067186836615595138476509425571649353379888038222848318242410514381778567"); 276 | Point(Z.of_string "309360768446416160958120789096623673321581925287993520578727665847649946974", 277 | Z.of_string "15545747453258058211051112710175110980847149697872893474129490656712600840644"); 278 | Point(Z.of_string "111074907564813235589236019726686918258299080928220099851794721258295360723553", 279 | Z.of_string "68219183722388131882608504000217272808529537938801462511574420529241433931992"); 280 | Point(Z.of_string "37137830207322793881961094801535416288434799099607035659469701669103932908350", 281 | Z.of_string "94379817757692358485771630532379333475294297835953749749976520013026014567539"); 282 | Point(Z.of_string "115196035379221719046601785156347717352838444810397338671042735887416313297714", 283 | Z.of_string "19118332585913657750480311533039520227246884387962518675826988717809919601363"); 284 | Point(Z.of_string "41624839734554243043930651979190152106110456551204484683807059517198206678132", 285 | Z.of_string "97232068009378082976341105684933298058982012804785038346447696304748564578496"); 286 | Point(Z.of_string "20063671337884349435916060413663379372353645507223795991982454141538067885200", 287 | Z.of_string "42281668517922921936266976927024554985401928376993498142462166950332723185983"); 288 | Point(Z.of_string "25189755076968237763611660020604537382682981857235682004983404119337071095319", 289 | Z.of_string "390553589691201067136596085090108611563963655594807885170307338397127533147"); 290 | Point(Z.of_string "37421712338459846554413756193902797012350418527202436104864199237820546657758", 291 | Z.of_string "36564962470334647631629006333551029130228853773600414560474997249481630207662")]; 292 | } 293 | 294 | let field = curve.p 295 | let g = curve.g 296 | let n = curve.n 297 | let a = curve.a 298 | let b = curve.b 299 | let points = curve.points 300 | 301 | end) 302 | --------------------------------------------------------------------------------